From 8346ecd045f052983f69eb2c1d39e89e911aed87 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 12 Jun 2008 02:17:36 +0200 Subject: [PATCH] Work around open() bug on HP-UX 11 and Solaris 9. --- ChangeLog | 9 +++++++++ doc/posix-functions/open.texi | 4 ++++ lib/open.c | 15 ++++++++++++++- m4/open.m4 | 39 +++++++++++++++++++++++++++++++++++++-- tests/test-open.c | 2 ++ 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0e6fdf69b..38b642dea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-06-11 Bruno Haible + + * m4/open.m4 (gl_FUNC_OPEN): Add test against trailing slash bug. + * lib/open.c: Include errno.h. + (open): Fail when attempting to write to a file that has a trailing + slash. + * tests/test-open.c (main): Test against trailing slash bug. + * doc/posix-functions/open.texi: Mention the trailing slash bug. + 2008-06-10 Bruno Haible * tests/test-vc-list-files-git.sh: Make double use of 'exit'. Needed diff --git a/doc/posix-functions/open.texi b/doc/posix-functions/open.texi index 7a6d5fc76..bb982cfae 100644 --- a/doc/posix-functions/open.texi +++ b/doc/posix-functions/open.texi @@ -9,6 +9,10 @@ Gnulib module: open Portability problems fixed by Gnulib: @itemize @item +This function does not fail when the file name argument ends in a slash +and (without the slash) names a nonexistent file, on some platforms: +HP-UX 11.00, Solaris 9. +@item On Windows platforms (excluding Cygwin), this function does usually not recognize the @file{/dev/null} filename. @end itemize diff --git a/lib/open.c b/lib/open.c index a52bf935b..482136896 100644 --- a/lib/open.c +++ b/lib/open.c @@ -1,5 +1,5 @@ /* Open a descriptor to a file. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007-2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ /* If the fchdir replacement is used, open() is defined in fchdir.c. */ #ifndef FCHDIR_REPLACEMENT +# include # include # include # include @@ -51,6 +52,18 @@ open (const char *filename, int flags, ...) va_end (arg); } +# if OPEN_TRAILING_SLASH_BUG + if (flags & (O_CREAT | O_WRONLY | O_RDWR)) + { + size_t len = strlen (filename); + if (len > 0 && filename[len - 1] == '/') + { + errno = EISDIR; + return -1; + } + } +# endif + # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ if (strcmp (filename, "/dev/null") == 0) filename = "NUL"; diff --git a/m4/open.m4 b/m4/open.m4 index 90d528ac1..335f4e500 100644 --- a/m4/open.m4 +++ b/m4/open.m4 @@ -1,5 +1,5 @@ -# open.m4 serial 1 -dnl Copyright (C) 2007 Free Software Foundation, Inc. +# open.m4 serial 2 +dnl Copyright (C) 2007-2008 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -13,5 +13,40 @@ AC_DEFUN([gl_FUNC_OPEN], REPLACE_OPEN=1 AC_LIBOBJ([open]) ;; + *) + dnl open("foo/") should not create a file when the file name has a + dnl trailing slash. + AC_CACHE_CHECK([whether open recognizes a trailing slash], + [gl_cv_func_open_slash], + [ + AC_TRY_RUN([ +#include +#if HAVE_UNISTD_H +# include +#endif +int main () +{ + return open ("conftest.sl/", O_CREAT, 0600) >= 0; +}], [gl_cv_func_open_slash=yes], [gl_cv_func_open_slash=no], + [ +changequote(,)dnl + case "$host_os" in + solaris2.[0-9]*) gl_cv_func_open_slash="guessing no" ;; + hpux*) gl_cv_func_open_slash="guessing no" ;; + *) gl_cv_func_open_slash="guessing yes" ;; + esac +changequote([,])dnl + ]) + rm -f conftest.sl + ]) + case "$gl_cv_func_open_slash" in + *no) + AC_DEFINE([OPEN_TRAILING_SLASH_BUG], 1, + [Define to 1 if open() fails to recognize a trailing slash.]) + REPLACE_OPEN=1 + AC_LIBOBJ([open]) + ;; + esac + ;; esac ]) diff --git a/tests/test-open.c b/tests/test-open.c index c570aaad4..aad36c4ad 100644 --- a/tests/test-open.c +++ b/tests/test-open.c @@ -38,6 +38,8 @@ int main () { + ASSERT (open ("nonexist.ent/", O_CREAT, 0600) < 0); + ASSERT (open ("/dev/null", O_RDONLY) >= 0); return 0; -- 2.11.0