exceeding PATH_MAX

Eric Blake ebb9@byu.net
Sat Mar 26 15:48:00 GMT 2005


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

The attached program is a derivative of the configure-time test used in
coreutils to see if getcwd is broken.  Many systems support relative
pathnames whose absolute name is longer than PATH_MAX, and on some of
them, getcwd fails in that case.  But I understand that cygwin currently
treats PATH_MAX as the maximum length of the absolute Windows pathname
that corresponds to the POSIX name, whether relative or absolute, since
Windows 95 and the ASCII versions of Windows syscalls refuse to work on
path names longer than 260 bytes.  This means that even with relative
paths, it is impossible to creat() or mkdir() a path that would exceed the
name limitations of Windows.  Therefore, on cygwin, getcwd() currently
can't fail on a current working directory longer than PATH_MAX, since it
is trivially provable that since such a directory can't be created, it
can't be the current working directory; but the configure test was failing
to detect that.

The problem here is that the test program shows that mkdir is failing with
EINVAL (22); when looking at POSIX,
http://www.opengroup.org/onlinepubs/009695399/functions/mkdir.html, mkdir
is not documented as returning EINVAL, but is allowed to return
ENAMETOOLONG (91).  Likewise, many other functions are documented as
allowing ENAMETOOLONG when the pathname exceeds implementation
limitations.  Furthermore, if I replace mkdir/errno with
CreateDirectory/GetLastError, Windows is returning
ERROR_FILENAME_EXCED_RANGE, which is a good candidate for mapping cleanly
to ENAMETOOLONG.

On NT systems, and using the Unicode versions of Windows syscalls, Windows
supports up to 32k for pathnames, with component names up to 255 bytes, by
using the \\?\ prefix.  Cygwin could actually support the XSI-recommended
minimum PATH_MAX of 1024, rather than the POSIX-required minimum of 256,
and support it on the Posix name rather than the Windows name as is
currently done.  That would also let cygwin support relative pathnames
whose absolute name is greater than PATH_MAX, up to the 32k limit of the
absolute path name, as is done on many other systems.  The XSI-recommended
NAME_MAX of 255 is a bit problematic - on managed mounts, it is possible
for an 85-char POSIX name to occupy 255 Windows characters, but at least
that is still greater than the POSIX recommended minimum NAME_MAX of 14.
However, changing cygwin to support filenames greater than 260 on systems
that support it would be a big patch to cygwin, and I don't have an
assignment in place.

One other comment - limits.h defines PATH_MAX as 259 (#define PATH_MAX
(260 - 1 /*NUL*/)) instead of the Windows API MAX_PATH of 260.  But POSIX
states that PATH_MAX includes the trailing NUL, so there is no reason for
cygwin to short-change the length by a byte.

This patch fixes the smaller issues:

2005-03-26  Eric Blake  <ebb9@byu.net>

	* errno.cc (FILENAME_EXCED_RANGE): Map to ENAMETOOLONG.
	* include/limits.h (NAME_MAX): New define.
	(PATH_MAX): POSIX allows PATH_MAX to include trailing NUL.

- --
Life is short - so eat dessert first!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCRYQ984KuGfSFAYARAg9PAJ9IBnJU99Mk7dLMMciIt9xSvEwk5gCfaXML
snkvzBf+BcDbXS+CG5SFmnk=
=OvLe
-----END PGP SIGNATURE-----
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: foo.c
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20050326/0c66f184/attachment.c>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: cygwin.patch
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20050326/0c66f184/attachment.ksh>


More information about the Cygwin-patches mailing list