New API call for path conversion
Eric Blake
ebb9@byu.net
Fri Feb 22 13:56:00 GMT 2008
According to Corinna Vinschen on 2/22/2008 5:19 AM:
> I'm mulling over a new API call for the path conversion between POSIX
> and Win32 paths. The old API (cygwin_conv_to_full_win32_path, etc) is
> just not feasible anymore. They don't allow to request the required
> buffer lengths except for the path_list functions. They don't allow to
> give the buffer size as parameter but simply assume they are big enough,
> which is quite dangerous. They don't allow to specify Win32 paths in
> WCHAR.
Agreed wholeheartedly. Any interface with an implicit maximum buffer
length is asking for problems.
>
> typedef enum
> {
> CCP_WIN_A_TO_POSIX, /* from is char*, to is char* */
> CCP_WIN_W_TO_POSIX, /* from is wchar_t*, to is char* */
> CCP_POSIX_TO_WIN_A, /* from is char*, to is char* */
> CCP_POSIX_TO_WIN_W /* from is char*, to is wchar_t* */
> } cygwin_conv_path_t;
>
> ssize_t cygwin_conv_path (cygwin_conv_path_t what, const void *from,
> void *to, size_t size);
I like the name, and the idea of an enum for making a single entry point
more flexible than a multitude of converters. Shouldn't you use restrict
on the two pointers, to guarantee non-overlap between the buffers and for
potentially better code generation? (That opens a different can of worms
- cygwin could certainly use restrict in a lot more places).
>
> "size" is the size of the "to" buffer in bytes (not in characters).
>
> If size is 0, cygwin_conv_path returns the required buffer size in
> bytes.
Including or excluding the trailing NUL? I'd argue for excluding.
>
> Otherwise, it returns 0 on success, or -1 on error and errno is set to
> one of the below values:
I slightly disagree with these semantics. My first thought was that you
should always return the required buffer size in bytes (think snprintf),
whether or not it is larger than the input size. And if the incoming size
is too small (but not 0), then guarantee that to[size-1]=='\0'. A
nonnegative result means success, -1 on error (I guess that means
converting "" should set errno to ENOENT and return -1, rather than
returning 0?).
>
> EINVAL what has an invalid value.
> EFAULT from or to point into nirvana.
> ENAMETOOLONG the resulting path is longer than 32K, or, in case
> of what == CCP_POSIX_TO_WIN_A, longer than MAX_PATH.
Now that MAX_PATH is 4k, don't you mean longer than Window's pathetic 256
byte limit?
> ENOSPC size is less than required for the conversion.
Hmm - based on my above argument (snprintf-like semantics of always
returning the necessary size and a truncated conversion), you'd never fail
with ENOSPC. On the other hand, a truncated path is potentially
dangerous, as it can lead to operations on the wrong file if the code did
not check for the result being larger than the input size. So your idea
of returning -1 and ENOSPC on insufficient non-zero buffer size is better
after all. And maybe for safety, we should try to set the output buffer
to "" on failure, so that if someone goofs and tries to use the converter
without checking for errors, they'd at least get ENOENT or EFAULT on the
subsequent operations rather silently using the original contents of the
output buffer? However, I'd still like the success result to be the size
of the conversion in bytes, rather than 0, since it may be smaller than
the size of my input buffer, and since it avoids me having to revisit the
buffer contents with strlen to find something that the converter already knew.
> Maybe we should add another function which always allocates the required
> buffer, along these lines:
>
> void *cygwin_create_path (cygwin_conv_path_t what,
> const void *from);
Yes, that would be a nice convenience wrapper.
>
> Return value is the pointer to the converted path or NULL with errno set
> as above.
or to ENOMEM if malloc failed.
>
> The old conversion functions should continue to work. They should just
> be guarded against resulting paths longer than MAX_PATH
MAX_PATH, or 256?
> and exit with an
> api_fatal error if the resulting path would be longer. This could help to
> convert applications using the old API to the new one.
>
> Does that sound reasonable?
Yes.
--
Don't work too hard, make some time for fun as well!
Eric Blake ebb9@byu.net
More information about the Cygwin-developers
mailing list