On 2010-12-18 11:34-0800 David MacMahon wrote:

> Hi, Alan,
>
> On Dec 18, 2010, at 10:57 AM, Alan W. Irwin wrote:
>
>> Another model for plgnver, plgndev, and plgnfnam is one similar to
>> strlcpy that is discussed by Todd C. Miller and Theo de Raadt at
>> http://www.gratisoft.us/todd/papers/strlcpy.html.  That is a most
>> interesting paper to read.  I am not necessarily advocating something
>> similar to this model API.  I leave that to those more knowledgable in
>> C than I am.  However, I am mentioning this paper for further
>> discussion.
>

> It seems like strlcpy is a more convenient alternative to strncpy,
but I don't see how this would solve the allocation problem.  Wouldn't
the user still need to ensure that a large enough buffer has been
allocated?  If so, the problem of determining how large is large
enough still remains.  Am I missing something?

See their example 1d where they check for truncation.  Instead of
taking an error return at that point as they did in their sample code
the user could instead realloc if they liked as in your original
suggestion.  Of course, the real value of the strlcpy model is the
thought that has gone into the null termination issue as well as the
definition of the size of the buffer that is returned.  For example,
after much debate about the alternatives they decided to use the
snprintf return semantics, that is, the returned length does not
include the null terminator which is the same definition as the string
length calculated by strlen.

N.B. I have now found an additional useful reference for strlcpy which is
http://www.manpagez.com/man/3/strlcpy/

>
>> <aside to Dave> Can you remember the name of the function you were using as 
>> the model
>> for your API suggestion for plgnver, plgndev, and plgnfnam?  If so,
>> that will give us a chance to dig into the official documention of
>> that function like we can currently do for getcwd and strlcpy. </aside to 
>> Dave>
>

> OK, digging way back into my mental archives (and googling), I think
I first came across this approach in a previous life when I did
Windows programming.  An example of this approach can be seen in the
Windows GetShortPathName function (and probably others as well)...

>
> http://msdn.microsoft.com/en-us/library/aa364989(v=vs.85).aspx
>

> I mis-remembered the exact details of the return code.  The WIN32
functions seem to return the total size needed iff the buffer pointer
is NULL and the size is given as 0.  This shouldn't really change the
fundamentals of what I wrote earlier, however.

Thanks for that reference.  However, I have noticed some deficiencies
in that documentation of GetShortPathName.  There is no mention there
of null termination guaranteed in the result which is an important
issue covered in the strlcpy documentation.  For example, what happens
if the buffer receiving the result is too small?  Do you get a
truncated result with no null terminator or a truncated result of one
unit smaller in size followed by a null terminator, or nothing at all
in the result?

Just because it appears to be better documented on the
null-termination guarantee issue, I suggest we adopt the strlcpy
model.  This gives the user in any language freedom to do anything
they like if the returned size (which never counts the null
terminator) is >= the value of n in the call. For high-level languages
like Python where the uses don't have to worry about allocation, they
could just call the function again with n chosen to be the previous
returned value + 1.  For lower-level languages like C, they could
realloc the buffer using the correct size, return an error, or just
accept the truncated result.

Also, I don't think we should use the wrinkle present in
GetShortPathName of doing something special for the NULL buffer,
size=0 call.  That does add a bit of convenience (but is not a
necessity) for languages such as C where the buffer is alloced
beforehand, but that wrinkle makes no sense for higher level languages
such as Python where the correctly sized buffer is created as needed.
For example, a typical Python call to plgfnam is

fnam = plgfnam()

With plgnfnam that would be changed to something like

(needed_size, fnam) = plgnfnam(100)
if needed_size >= 100:
   # Oops, 100 was too small.
   fname = plgnfnam(needed_size+1)[1]

On the other hand, I would hope the PLplot version or device names are
unlikely to be greater than 20 characters in our lifetimes.  So for
that case, you normally wouldn't bother to check the needed size in
Python:

version = plgnfnam(20)[1]
devname = plgndev(20)[1]

Note, even in the unlikely case that the version or device name were
greater than 20 characters, the above calls would be perfectly safe
and would yield properly truncated results at the 20th character.

Alan
__________________________
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for stellar interiors (freeeos.sf.net); PLplot scientific plotting software
package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of
Linux Links project (loll.sf.net); and the Linux Brochure Project
(lbproject.sf.net).
__________________________

Linux-powered Science
__________________________

------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel

Reply via email to