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