Mercurial > hg > octave-kai > gnulib-hg
changeset 14532:0b3f0c54fbc8
nonblocking: provide O_NONBLOCK for mingw
Mingw is the only known platform that lacks O_NONBLOCK (possibly
via the alternate spelling O_NDELAY). But mingw also lacks any
files where open() needs to enforce non-blocking behavior, and
lacks openat(), so it is relatively simple to provide a non-zero
flag. A future patches will make use of O_NONBLOCK for pipe2.
* modules/nonblocking (Depends-on): Add open.
(configure.ac): Set new witness macro.
* m4/fcntl_h.m4 (gl_FCNTL_H_DEFAULTS): Provide default for it.
* modules/fcntl-h (Makefile.am): Substitute it.
* lib/fcntl.in.h (O_NONBLOCK): Guarantee non-zero definition when
nonblocking module is in use.
* lib/nonblocking.c: Adjust portability test.
* lib/open.c (open): Don't let native open see gnulib flag.
* tests/test-fcntl-h.c (main): Enhance test.
* tests/test-open.h (test_open): Likewise.
* doc/posix-headers/fcntl.texi (fcntl.h): Document the replacement.
Signed-off-by: Eric Blake <eblake@redhat.com>
author | Eric Blake <eblake@redhat.com> |
---|---|
date | Fri, 08 Apr 2011 10:15:54 -0600 |
parents | bdf4fc6a1b28 |
children | 7c084dd61825 |
files | ChangeLog doc/posix-headers/fcntl.texi lib/fcntl.in.h lib/nonblocking.c lib/open.c m4/fcntl_h.m4 modules/fcntl-h modules/nonblocking tests/test-fcntl-h.c tests/test-open.h |
diffstat | 10 files changed, 139 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2011-04-08 Eric Blake <eblake@redhat.com> + nonblocking: provide O_NONBLOCK for mingw + * modules/nonblocking (Depends-on): Add open. + (configure.ac): Set new witness macro. + * m4/fcntl_h.m4 (gl_FCNTL_H_DEFAULTS): Provide default for it. + * modules/fcntl-h (Makefile.am): Substitute it. + * lib/fcntl.in.h (O_NONBLOCK): Guarantee non-zero definition when + nonblocking module is in use. + * lib/nonblocking.c: Adjust portability test. + * lib/open.c (open): Don't let native open see gnulib flag. + * tests/test-fcntl-h.c (main): Enhance test. + * tests/test-open.h (test_open): Likewise. + * doc/posix-headers/fcntl.texi (fcntl.h): Document the replacement. + careadlink: fix compilation error on mingw * lib/careadlinkat.c (standard_allocator): Avoid renaming fields within struct allocator.
--- a/doc/posix-headers/fcntl.texi +++ b/doc/posix-headers/fcntl.texi @@ -9,9 +9,14 @@ @itemize @item @samp{O_CLOEXEC}, @samp{O_DIRECTORY}, @samp{O_DSYNC}, @samp{O_NOCTTY}, -@samp{O_NOFOLLOW}, @samp{O_NONBLOCK}, @samp{O_RSYNC}, @samp{O_SYNC}, +@samp{O_NOFOLLOW}, @samp{O_RSYNC}, @samp{O_SYNC}, and @samp{O_TTY_INIT} are not defined on some platforms. Gnulib defines -these macros to 0. +these macros to 0, which is generally safe. + +@item +@samp{O_NONBLOCK} is not defined on some platforms. If the +@samp{nonblocking} module is in use, gnulib guarantees a working +non-zero value; otherwise, the gnulib replacement is 0. @item @samp{O_EXEC} and @samp{O_SEARCH} are not defined on some platforms.
--- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -182,8 +182,7 @@ #endif #if !defined O_CLOEXEC && defined O_NOINHERIT -/* Mingw spells it `O_NOINHERIT'. Intentionally leave it - undefined if not available. */ +/* Mingw spells it `O_NOINHERIT'. */ # define O_CLOEXEC O_NOINHERIT #endif @@ -219,6 +218,16 @@ # define O_NONBLOCK O_NDELAY #endif +#if @GNULIB_NONBLOCKING@ +# if O_NONBLOCK +# define GNULIB_defined_O_NONBLOCK 0 +# else +# define GNULIB_defined_O_NONBLOCK 1 +# undef O_NONBLOCK +# define O_NONBLOCK 0x40000000 +# endif +#endif + #ifndef O_NOCTTY # define O_NOCTTY 0 #endif
--- a/lib/nonblocking.c +++ b/lib/nonblocking.c @@ -113,7 +113,7 @@ # include <fcntl.h> -# if !O_NONBLOCK +# if GNULIB_defined_O_NONBLOCK # error Please port nonblocking to your platform # endif
--- a/lib/open.c +++ b/lib/open.c @@ -63,6 +63,15 @@ va_end (arg); } +#if GNULIB_defined_O_NONBLOCK + /* The only known platform that lacks O_NONBLOCK is mingw, but it + also lacks named pipes and Unix sockets, which are the only two + file types that require non-blocking handling in open(). + Therefore, it is safe to ignore O_NONBLOCK here. It is handy + that mingw also lacks openat(), so that is also covered here. */ + flags &= ~O_NONBLOCK; +#endif + #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ if (strcmp (filename, "/dev/null") == 0) filename = "NUL";
--- a/m4/fcntl_h.m4 +++ b/m4/fcntl_h.m4 @@ -31,13 +31,14 @@ AC_DEFUN([gl_FCNTL_H_DEFAULTS], [ - GNULIB_FCNTL=0; AC_SUBST([GNULIB_FCNTL]) - GNULIB_OPEN=0; AC_SUBST([GNULIB_OPEN]) - GNULIB_OPENAT=0; AC_SUBST([GNULIB_OPENAT]) + GNULIB_FCNTL=0; AC_SUBST([GNULIB_FCNTL]) + GNULIB_NONBLOCKING=0; AC_SUBST([GNULIB_NONBLOCKING]) + GNULIB_OPEN=0; AC_SUBST([GNULIB_OPEN]) + GNULIB_OPENAT=0; AC_SUBST([GNULIB_OPENAT]) dnl Assume proper GNU behavior unless another module says otherwise. - HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL]) - HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT]) - REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL]) - REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN]) - REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT]) + HAVE_FCNTL=1; AC_SUBST([HAVE_FCNTL]) + HAVE_OPENAT=1; AC_SUBST([HAVE_OPENAT]) + REPLACE_FCNTL=0; AC_SUBST([REPLACE_FCNTL]) + REPLACE_OPEN=0; AC_SUBST([REPLACE_OPEN]) + REPLACE_OPENAT=0; AC_SUBST([REPLACE_OPENAT]) ])
--- a/modules/fcntl-h +++ b/modules/fcntl-h @@ -30,6 +30,7 @@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \ -e 's|@''GNULIB_FCNTL''@|$(GNULIB_FCNTL)|g' \ + -e 's|@''GNULIB_NONBLOCKING''@|$(GNULIB_NONBLOCKING)|g' \ -e 's|@''GNULIB_OPEN''@|$(GNULIB_OPEN)|g' \ -e 's|@''GNULIB_OPENAT''@|$(GNULIB_OPENAT)|g' \ -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
--- a/modules/nonblocking +++ b/modules/nonblocking @@ -8,10 +8,12 @@ Depends-on: fcntl-h ioctl +open stdbool sys_socket configure.ac: +gl_FCNTL_MODULE_INDICATOR([nonblocking]) Makefile.am: lib_SOURCES += nonblocking.c
--- a/tests/test-fcntl-h.c +++ b/tests/test-fcntl-h.c @@ -29,10 +29,88 @@ int sk[] = { SEEK_CUR, SEEK_END, SEEK_SET }; /* Check that the FD_* macros are defined. */ -int fd = FD_CLOEXEC; +int i = FD_CLOEXEC; int main (void) { - return 0; + /* Ensure no overlap in SEEK_*. */ + switch (0) + { + case SEEK_CUR: + case SEEK_END: + case SEEK_SET: + ; + } + + /* Ensure no dangerous overlap in non-zero gnulib-defined replacements. */ + switch (O_RDONLY) + { + /* Access modes */ + case O_RDONLY: + case O_WRONLY: + case O_RDWR: +#if O_EXEC && O_EXEC != O_RDONLY + case O_EXEC: +#endif +#if O_SEARCH && O_EXEC != O_SEARCH && O_SEARCH != O_RDONLY + case O_SEARCH: +#endif + i = O_ACCMODE == (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH); + break; + + /* Everyone should have these */ + case O_CREAT: + case O_EXCL: + case O_TRUNC: + case O_APPEND: + break; + + /* These might be 0 or O_RDONLY, only test non-zero versions. */ +#if O_CLOEXEC + case O_CLOEXEC: +#endif +#if O_DIRECT + case O_DIRECT: +#endif +#if O_DIRECTORY + case O_DIRECTORY: +#endif +#if O_DSYNC + case O_DSYNC: +#endif +#if O_NOATIME + case O_NOATIME: +#endif +#if O_NONBLOCK + case O_NONBLOCK: +#endif +#if O_NOCTTY + case O_NOCTTY: +#endif +#if O_NOFOLLOW + case O_NOFOLLOW: +#endif +#if O_NOLINKS + case O_NOLINKS: +#endif +#if O_RSYNC && O_RSYNC != O_DSYNC + case O_RSYNC: +#endif +#if O_SYNC && O_SYNC != O_RSYNC + case O_SYNC: +#endif +#if O_TTY_INIT + case O_TTY_INIT: +#endif +#if O_BINARY + case O_BINARY: +#endif +#if O_TEXT + case O_TEXT: +#endif + ; + } + + return !i; }
--- a/tests/test-open.h +++ b/tests/test-open.h @@ -63,6 +63,12 @@ ASSERT (write (fd, "c", 1) == 1); ASSERT (close (fd) == 0); + /* Although O_NONBLOCK on regular files can be ignored, it must not + cause a failure. */ + fd = func (BASE "file", O_NONBLOCK | O_RDONLY); + ASSERT (0 <= fd); + ASSERT (close (fd) == 0); + /* Symlink handling, where supported. */ if (symlink (BASE "file", BASE "link") != 0) {