X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fopen.c;h=9a35f5b2a6add92db03e40da7b7c63a70f0d894a;hb=29dd8b5548ce047ce51ff9a73d6c4b50c9886771;hp=e9324af0de8d8c0641f508699c19a3d137a0aa56;hpb=001adc94db55b40012385a852ab7ce16d2e65a6f;p=gnulib.git diff --git a/lib/open.c b/lib/open.c index e9324af0d..9a35f5b2a 100644 --- a/lib/open.c +++ b/lib/open.c @@ -18,6 +18,18 @@ #include +/* Get the original definition of open. It might be defined as a macro. */ +#define __need_system_fcntl_h +#include +#undef __need_system_fcntl_h +#include + +static inline int +orig_open (const char *filename, int flags, mode_t mode) +{ + return open (filename, flags, mode); +} + /* Specification. */ #include @@ -32,9 +44,9 @@ int open (const char *filename, int flags, ...) -# undef open { mode_t mode; + int fd; mode = 0; if (flags & O_CREAT) @@ -52,13 +64,18 @@ open (const char *filename, int flags, ...) va_end (arg); } +# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + if (strcmp (filename, "/dev/null") == 0) + filename = "NUL"; +# endif + # if OPEN_TRAILING_SLASH_BUG /* If the filename ends in a slash and one of O_CREAT, O_WRONLY, O_RDWR is specified, then fail. Rationale: POSIX says that "A pathname that contains at least one non-slash character and that - ends withone or more trailing slashes shall be resolved as if a + ends with one or more trailing slashes shall be resolved as if a single dot character ( '.' ) were appended to the pathname." and "The special filename dot shall refer to the directory specified by @@ -85,11 +102,38 @@ open (const char *filename, int flags, ...) } # endif -# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ - if (strcmp (filename, "/dev/null") == 0) - filename = "NUL"; + fd = orig_open (filename, flags, mode); + +# if OPEN_TRAILING_SLASH_BUG + /* If the filename ends in a slash and fd does not refer to a directory, + then fail. + Rationale: POSIX + says that + "A pathname that contains at least one non-slash character and that + ends with one or more trailing slashes shall be resolved as if a + single dot character ( '.' ) were appended to the pathname." + and + "The special filename dot shall refer to the directory specified by + its predecessor." + If the named file without the slash is not a directory, open() must fail + with ENOTDIR. */ + if (fd >= 0) + { + size_t len = strlen (filename); + if (len > 0 && filename[len - 1] == '/') + { + struct stat statbuf; + + if (fstat (fd, &statbuf) >= 0 && !S_ISDIR (statbuf.st_mode)) + { + close (fd); + errno = ENOTDIR; + return -1; + } + } + } # endif - return open (filename, flags, mode); + return fd; } #endif