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:



Reply via email to