From 5f12d9389f0d0597c4996dfb15c0a5c64808774a Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 21 Sep 2011 21:16:45 +0200 Subject: [PATCH] New module 'fdopen'. * lib/stdio.in.h (fdopen): New declaration. * lib/fdopen.c: New file. * m4/fdopen.m4: New file. * m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Initialize GNULIB_FDOPEN, REPLACE_FDOPEN. * modules/stdio (Makefile.am): Substitute GNULIB_FDOPEN, REPLACE_FDOPEN. * modules/fdopen: New file. * modules/stdio-tests (Depends-on): Remove fdopen-tests. * tests/test-stdio-c++.cc: Check signature of fdopen. * doc/posix-functions/fdopen.texi: Mention the new module. --- ChangeLog | 15 ++++++++++++++ doc/posix-functions/fdopen.texi | 8 ++++---- lib/fdopen.c | 43 +++++++++++++++++++++++++++++++++++++++ lib/stdio.in.h | 20 ++++++++++++++++++ m4/fdopen.m4 | 45 +++++++++++++++++++++++++++++++++++++++++ m4/stdio_h.m4 | 4 +++- modules/fdopen | 28 +++++++++++++++++++++++++ modules/stdio | 2 ++ modules/stdio-tests | 1 - tests/test-stdio-c++.cc | 4 ++++ 10 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 lib/fdopen.c create mode 100644 m4/fdopen.m4 create mode 100644 modules/fdopen diff --git a/ChangeLog b/ChangeLog index d808c871a..b3c41501e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2011-09-21 Bruno Haible + New module 'fdopen'. + * lib/stdio.in.h (fdopen): New declaration. + * lib/fdopen.c: New file. + * m4/fdopen.m4: New file. + * m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Initialize GNULIB_FDOPEN, + REPLACE_FDOPEN. + * modules/stdio (Makefile.am): Substitute GNULIB_FDOPEN, + REPLACE_FDOPEN. + * modules/fdopen: New file. + * modules/stdio-tests (Depends-on): Remove fdopen-tests. + * tests/test-stdio-c++.cc: Check signature of fdopen. + * doc/posix-functions/fdopen.texi: Mention the new module. + +2011-09-21 Bruno Haible + unlockpt tests: Avoid test failure on NetBSD 5.1. * tests/test-unlockpt.c (main): Skip the EBADF tests on NetBSD. * doc/posix-functions/unlockpt.texi: Mention the bug on NetBSD. diff --git a/doc/posix-functions/fdopen.texi b/doc/posix-functions/fdopen.texi index 4324453fd..49c006719 100644 --- a/doc/posix-functions/fdopen.texi +++ b/doc/posix-functions/fdopen.texi @@ -4,15 +4,15 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/fdopen.html} -Gnulib module: --- +Gnulib module: fdopen Portability problems fixed by Gnulib: @itemize +@item +On Windows platforms (excluding Cygwin), this function does not set @code{errno} +upon failure. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -On Windows platforms (excluding Cygwin), this function does not set @code{errno} -upon failure. @end itemize diff --git a/lib/fdopen.c b/lib/fdopen.c new file mode 100644 index 000000000..c443ab660 --- /dev/null +++ b/lib/fdopen.c @@ -0,0 +1,43 @@ +/* Open a stream with a given file descriptor. + Copyright (C) 2011 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#undef fdopen + +FILE * +rpl_fdopen (int fd, const char *mode) +{ + int saved_errno = errno; + FILE *fp; + + errno = 0; + fp = fdopen (fd, mode); + if (fp == NULL) + { + if (errno == 0) + errno = EBADF; + } + else + errno = saved_errno; + + return fp; +} diff --git a/lib/stdio.in.h b/lib/stdio.in.h index f5ffd8501..ebbf80117 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -170,6 +170,26 @@ _GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - " "use gnulib module fclose for portable POSIX compliance"); #endif +#if @GNULIB_FDOPEN@ +# if @REPLACE_FDOPEN@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef fdopen +# define fdopen rpl_fdopen +# endif +_GL_FUNCDECL_RPL (fdopen, FILE *, (int fd, const char *mode) + _GL_ARG_NONNULL ((2))); +_GL_CXXALIAS_RPL (fdopen, FILE *, (int fd, const char *mode)); +# else +_GL_CXXALIAS_SYS (fdopen, FILE *, (int fd, const char *mode)); +# endif +_GL_CXXALIASWARN (fdopen); +#elif defined GNULIB_POSIXCHECK +# undef fdopen +/* Assume fdopen is always declared. */ +_GL_WARN_ON_USE (fdopen, "fdopen on Win32 platforms is not POSIX compatible - " + "use gnulib module fdopen for portability"); +#endif + #if @GNULIB_FFLUSH@ /* Flush all pending data on STREAM according to POSIX rules. Both output and seekable input streams are supported. diff --git a/m4/fdopen.m4 b/m4/fdopen.m4 new file mode 100644 index 000000000..dd2cf264d --- /dev/null +++ b/m4/fdopen.m4 @@ -0,0 +1,45 @@ +# fdopen.m4 serial 1 +dnl Copyright (C) 2011 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. + +AC_DEFUN([gl_FUNC_FDOPEN], +[ + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Test whether fdopen() sets errno when it fails due to a bad fd argument. + AC_CACHE_CHECK([whether fdopen sets errno], [gl_cv_func_fdopen_works], + [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +int +main (void) +{ + FILE *fp; + errno = 0; + fp = fdopen (-1, "r"); + if (fp != NULL) + return 1; + if (errno == 0) + return 2; + return 0; +}]])], + [gl_cv_func_fdopen_works=yes], + [gl_cv_func_fdopen_works=no], + [case "$host_os" in + mingw*) gl_cv_func_fdopen_works="guessing no" ;; + *) gl_cv_func_fdopen_works="guessing yes" ;; + esac + ]) + ]) + case "$gl_cv_func_fdopen_works" in + *no) REPLACE_FDOPEN=1 ;; + esac +]) + +dnl Prerequisites of lib/fdopen.c. +AC_DEFUN([gl_PREREQ_FDOPEN], []) diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index 988e0255d..39bf80e2a 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -1,4 +1,4 @@ -# stdio_h.m4 serial 39 +# stdio_h.m4 serial 40 dnl Copyright (C) 2007-2011 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -91,6 +91,7 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], [ GNULIB_DPRINTF=0; AC_SUBST([GNULIB_DPRINTF]) GNULIB_FCLOSE=0; AC_SUBST([GNULIB_FCLOSE]) + GNULIB_FDOPEN=0; AC_SUBST([GNULIB_FDOPEN]) GNULIB_FFLUSH=0; AC_SUBST([GNULIB_FFLUSH]) GNULIB_FGETC=0; AC_SUBST([GNULIB_FGETC]) GNULIB_FGETS=0; AC_SUBST([GNULIB_FGETS]) @@ -161,6 +162,7 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], HAVE_VDPRINTF=1; AC_SUBST([HAVE_VDPRINTF]) REPLACE_DPRINTF=0; AC_SUBST([REPLACE_DPRINTF]) REPLACE_FCLOSE=0; AC_SUBST([REPLACE_FCLOSE]) + REPLACE_FDOPEN=0; AC_SUBST([REPLACE_FDOPEN]) REPLACE_FFLUSH=0; AC_SUBST([REPLACE_FFLUSH]) REPLACE_FOPEN=0; AC_SUBST([REPLACE_FOPEN]) REPLACE_FPRINTF=0; AC_SUBST([REPLACE_FPRINTF]) diff --git a/modules/fdopen b/modules/fdopen new file mode 100644 index 000000000..4054b054d --- /dev/null +++ b/modules/fdopen @@ -0,0 +1,28 @@ +Description: +fdopen() function: open a stream with a given file descriptor. + +Files: +lib/fdopen.c +m4/fdopen.m4 + +Depends-on: +stdio + +configure.ac: +gl_FUNC_FDOPEN +if test $REPLACE_FDOPEN = 1; then + AC_LIBOBJ([fdopen]) + gl_PREREQ_FDOPEN +fi +gl_STDIO_MODULE_INDICATOR([fdopen]) + +Makefile.am: + +Include: + + +License: +LGPLv2+ + +Maintainer: +Bruno Haible diff --git a/modules/stdio b/modules/stdio index 26bfc12b1..2e094b8fe 100644 --- a/modules/stdio +++ b/modules/stdio @@ -31,6 +31,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''NEXT_STDIO_H''@|$(NEXT_STDIO_H)|g' \ -e 's/@''GNULIB_DPRINTF''@/$(GNULIB_DPRINTF)/g' \ -e 's/@''GNULIB_FCLOSE''@/$(GNULIB_FCLOSE)/g' \ + -e 's/@''GNULIB_FDOPEN''@/$(GNULIB_FDOPEN)/g' \ -e 's/@''GNULIB_FFLUSH''@/$(GNULIB_FFLUSH)/g' \ -e 's/@''GNULIB_FGETC''@/$(GNULIB_FGETC)/g' \ -e 's/@''GNULIB_FGETS''@/$(GNULIB_FGETS)/g' \ @@ -101,6 +102,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's|@''HAVE_VDPRINTF''@|$(HAVE_VDPRINTF)|g' \ -e 's|@''REPLACE_DPRINTF''@|$(REPLACE_DPRINTF)|g' \ -e 's|@''REPLACE_FCLOSE''@|$(REPLACE_FCLOSE)|g' \ + -e 's|@''REPLACE_FDOPEN''@|$(REPLACE_FDOPEN)|g' \ -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ -e 's|@''REPLACE_FOPEN''@|$(REPLACE_FOPEN)|g' \ -e 's|@''REPLACE_FPRINTF''@|$(REPLACE_FPRINTF)|g' \ diff --git a/modules/stdio-tests b/modules/stdio-tests index fff23030a..6cb9eac79 100644 --- a/modules/stdio-tests +++ b/modules/stdio-tests @@ -4,7 +4,6 @@ tests/test-stdio.c Depends-on: verify stdio-c++-tests -fdopen-tests fgetc-tests configure.ac: diff --git a/tests/test-stdio-c++.cc b/tests/test-stdio-c++.cc index 07faf0fa0..213dcfdf2 100644 --- a/tests/test-stdio-c++.cc +++ b/tests/test-stdio-c++.cc @@ -32,6 +32,10 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::dprintf, int, (int, const char *, ...)); SIGNATURE_CHECK (GNULIB_NAMESPACE::fclose, int, (FILE *)); #endif +#if GNULIB_TEST_FDOPEN +SIGNATURE_CHECK (GNULIB_NAMESPACE::fdopen, FILE *, (int, const char *)); +#endif + #if GNULIB_TEST_FFLUSH SIGNATURE_CHECK (GNULIB_NAMESPACE::fflush, int, (FILE *)); #endif -- 2.11.0