changeset 30175:ff3e077a698d

New module 'write'.
author Bruno Haible <bruno@clisp.org>
date Fri, 26 Sep 2008 13:29:53 +0200
parents be50cfde3f08
children 0a0b42931b5c
files ChangeLog doc/posix-functions/write.texi lib/unistd.in.h lib/write.c m4/unistd_h.m4 m4/write.m4 modules/unistd modules/write
diffstat 8 files changed, 159 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Sep 26 13:25:57 2008 +0200
+++ b/ChangeLog	Fri Sep 26 13:29:53 2008 +0200
@@ -23,6 +23,18 @@
 
 2008-09-26  Bruno Haible  <bruno@clisp.org>
 
+	* 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.
+
 	* lib/signal.in.h (SIGPIPE): Define to a replacement value.
 	(raise): New declaration.
 	* lib/sigprocmask.c (SIGPIPE_handler): New variable.
--- a/doc/posix-functions/write.texi	Fri Sep 26 13:25:57 2008 +0200
+++ b/doc/posix-functions/write.texi	Fri Sep 26 13:29:53 2008 +0200
@@ -4,10 +4,15 @@
 
 POSIX specification: @url{http://www.opengroup.org/susv3xsh/write.html}
 
-Gnulib module: ---
+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:
--- a/lib/unistd.in.h	Fri Sep 26 13:25:57 2008 +0200
+++ b/lib/unistd.in.h	Fri Sep 26 13:29:53 2008 +0200
@@ -35,6 +35,11 @@
 /* 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,6 +338,16 @@
 #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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/write.c	Fri Sep 26 13:29:53 2008 +0200
@@ -0,0 +1,62 @@
+/* POSIX compatible write() function.
+   Copyright (C) 2008 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 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
--- a/m4/unistd_h.m4	Fri Sep 26 13:25:57 2008 +0200
+++ b/m4/unistd_h.m4	Fri Sep 26 13:29:53 2008 +0200
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 11
+# 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,18 +32,20 @@
 
 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_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,4 +62,5 @@
   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])
 ])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m4/write.m4	Fri Sep 26 13:29:53 2008 +0200
@@ -0,0 +1,20 @@
+# 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
+  ])
+])
--- a/modules/unistd	Fri Sep 26 13:25:57 2008 +0200
+++ b/modules/unistd	Fri Sep 26 13:29:53 2008 +0200
@@ -36,6 +36,8 @@
 	      -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,6 +53,7 @@
 	      -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; \
 	} > $@-t
 	mv $@-t $@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/write	Fri Sep 26 13:29:53 2008 +0200
@@ -0,0 +1,25 @@
+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
+