2008-09-26 Bruno Haible <[EMAIL PROTECTED]> * modules/write: New file. * lib/unistd.in.h: Include <sys/types.h>. (write): New declaration. * lib/write.c: New file. * m4/write.m4: New file. * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize GNULIB_UNISTD_H_SIGPIPE, GNULIB_WRITE, REPLACE_WRITE. * modules/unistd (Makefile.am): Substitute GNULIB_UNISTD_H_SIGPIPE, GNULIB_WRITE, REPLACE_WRITE. * doc/posix-functions/write.texi: Mention the write, sigpipe modules and the SIGPIPE issue.
========================= modules/write ================================ Description: POSIX compatible write() function: write data to a file descriptor Files: lib/write.c m4/write.m4 Depends-on: unistd configure.ac: gl_FUNC_WRITE gl_UNISTD_MODULE_INDICATOR([write]) Makefile.am: Include: <unistd.h> License: LGPLv2+ Maintainer: Bruno Haible ========================== lib/write.c ================================= /* POSIX compatible write() function. Copyright (C) 2008 Free Software Foundation, Inc. Written by Bruno Haible <[EMAIL PROTECTED]>, 2008. 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 <http://www.gnu.org/licenses/>. */ #include <config.h> /* Specification. */ #include <unistd.h> /* Replace this function only if module 'sigpipe' is requested. */ #if GNULIB_SIGPIPE /* On native Windows platforms, SIGPIPE does not exist. When write() is called on a pipe with no readers, WriteFile() fails with error GetLastError() = ERROR_NO_DATA, and write() in consequence fails with error EINVAL. */ # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ # include <errno.h> # include <signal.h> # include <io.h> # define WIN32_LEAN_AND_MEAN /* avoid including junk */ # include <windows.h> ssize_t rpl_write (int fd, const void *buf, size_t count) #undef write { ssize_t ret = write (fd, buf, count); if (ret < 0) { if (GetLastError () == ERROR_NO_DATA && GetFileType (_get_osfhandle (fd)) == FILE_TYPE_PIPE) { /* Try to raise signal SIGPIPE. */ raise (SIGPIPE); /* If it is currently blocked or ignored, change errno from EINVAL to EPIPE. */ errno = EPIPE; } } return ret; } # endif #endif ========================== m4/write.m4 ================================= # write.m4 serial 1 dnl Copyright (C) 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. AC_DEFUN([gl_FUNC_WRITE], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) dnl This ifdef is just an optimization, to avoid performing a configure dnl check whose result is not used. It does not make the test of dnl GNULIB_UNISTD_H_SIGPIPE or GNULIB_SIGPIPE redundant. m4_ifdef([gl_SIGNAL_SIGPIPE], [ gl_SIGNAL_SIGPIPE if test $gl_cv_header_signal_h_SIGPIPE != yes; then REPLACE_WRITE=1 AC_LIBOBJ([write]) fi ]) ]) ======================================================================== *** lib/unistd.in.h.orig 2008-09-26 12:52:18.000000000 +0200 --- lib/unistd.in.h 2008-09-26 03:14:02.000000000 +0200 *************** *** 35,40 **** --- 35,45 ---- /* mingw fails to declare _exit in <unistd.h>. */ #include <stdlib.h> + #if @GNULIB_WRITE@ && @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@ + /* Get ssize_t. */ + # include <sys/types.h> + #endif + /* The definition of GL_LINK_WARNING is copied here. */ *************** *** 333,338 **** --- 338,353 ---- #endif + #if @GNULIB_WRITE@ && @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@ + /* Write up to COUNT bytes starting at BUF to file descriptor FD. + See the POSIX:2001 specification + <http://www.opengroup.org/susv3xsh/write.html>. */ + # undef write + # define write rpl_write + extern ssize_t write (int fd, const void *buf, size_t count); + #endif + + #ifdef __cplusplus } #endif *** m4/unistd_h.m4.orig 2008-09-26 12:52:18.000000000 +0200 --- m4/unistd_h.m4 2008-09-26 02:34:36.000000000 +0200 *************** *** 1,4 **** ! # unistd_h.m4 serial 11 dnl Copyright (C) 2006-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, --- 1,4 ---- ! # unistd_h.m4 serial 12 dnl Copyright (C) 2006-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, *************** *** 32,49 **** AC_DEFUN([gl_UNISTD_H_DEFAULTS], [ ! GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN]) ! GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2]) ! GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) ! GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) ! GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) ! GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) ! GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R]) ! GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE]) ! GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN]) ! GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) ! GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) ! GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_DUP2=1; AC_SUBST([HAVE_DUP2]) HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) --- 32,51 ---- AC_DEFUN([gl_UNISTD_H_DEFAULTS], [ ! GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN]) ! GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2]) ! GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON]) ! GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR]) ! GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE]) ! GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD]) ! GNULIB_GETLOGIN_R=0; AC_SUBST([GNULIB_GETLOGIN_R]) ! GNULIB_GETPAGESIZE=0; AC_SUBST([GNULIB_GETPAGESIZE]) ! GNULIB_LCHOWN=0; AC_SUBST([GNULIB_LCHOWN]) ! GNULIB_LSEEK=0; AC_SUBST([GNULIB_LSEEK]) ! GNULIB_READLINK=0; AC_SUBST([GNULIB_READLINK]) ! GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) ! GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE]) ! GNULIB_WRITE=0; AC_SUBST([GNULIB_WRITE]) dnl Assume proper GNU behavior unless another module says otherwise. HAVE_DUP2=1; AC_SUBST([HAVE_DUP2]) HAVE_FTRUNCATE=1; AC_SUBST([HAVE_FTRUNCATE]) *************** *** 60,63 **** --- 62,66 ---- REPLACE_GETPAGESIZE=0; AC_SUBST([REPLACE_GETPAGESIZE]) REPLACE_LCHOWN=0; AC_SUBST([REPLACE_LCHOWN]) REPLACE_LSEEK=0; AC_SUBST([REPLACE_LSEEK]) + REPLACE_WRITE=0; AC_SUBST([REPLACE_WRITE]) ]) *** modules/unistd.orig 2008-09-26 12:52:19.000000000 +0200 --- modules/unistd 2008-09-26 02:35:33.000000000 +0200 *************** *** 36,41 **** --- 36,43 ---- -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \ -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \ -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \ + -e 's|@''GNULIB_UNISTD_H_SIGPIPE''@|$(GNULIB_UNISTD_H_SIGPIPE)|g' \ + -e 's|@''GNULIB_WRITE''@|$(GNULIB_WRITE)|g' \ -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \ -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \ -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \ *************** *** 51,56 **** --- 53,59 ---- -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \ -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \ -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \ + -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \ < $(srcdir)/unistd.in.h; \ } > [EMAIL PROTECTED] mv [EMAIL PROTECTED] $@ *** doc/posix-functions/write.texi.orig 2008-09-26 12:52:18.000000000 +0200 --- doc/posix-functions/write.texi 2008-09-26 00:35:13.000000000 +0200 *************** *** 4,13 **** POSIX specification: @url{http://www.opengroup.org/susv3xsh/write.html} ! Gnulib module: --- Portability problems fixed by Gnulib: @itemize @end itemize Portability problems not fixed by Gnulib: --- 4,18 ---- POSIX specification: @url{http://www.opengroup.org/susv3xsh/write.html} ! Gnulib module: write, sigpipe Portability problems fixed by Gnulib: @itemize + @item + When writing to a pipe with no readers, this function fails with error + @code{EINVAL}, instead of obeying the current @code{SIGPIPE} handler, on + some platforms: + mingw. @end itemize Portability problems not fixed by Gnulib: