2008-09-26 Bruno Haible <bruno@clisp.org>
+ * modules/sigpipe-tests: New file.
+ * tests/test-sigpipe.c: New file.
+ * tests/test-sigpipe.sh: New file.
+
* modules/write: New file.
* lib/unistd.in.h: Include <sys/types.h>.
(write): New declaration.
--- /dev/null
+/* Test of SIGPIPE handling.
+ Copyright (C) 2008 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, 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, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+#include <signal.h>
+
+/* Check that SIGPIPE is defined. */
+int s = SIGPIPE;
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void
+handler (int sig)
+{
+ exit (0);
+}
+
+int
+main (int argc, char **argv)
+{
+ char mode = argv[1][0];
+
+ switch (mode)
+ {
+ case 'A': signal (SIGPIPE, SIG_DFL); break;
+ case 'B': signal (SIGPIPE, SIG_IGN); break;
+ case 'C': signal (SIGPIPE, handler); break;
+ }
+
+ /* Produce infinite output. Since it is piped into "head -1", the writes
+ must ultimately fail. */
+ for (;;)
+ {
+ char c[2] = { 'y', '\n' };
+ int ret = write (1, c, sizeof (c));
+ if (ret <= 0)
+ {
+ switch (mode)
+ {
+ case 'B': /* The write() call should have failed with EPIPE. */
+ if (ret < 0 && errno == EPIPE)
+ exit (0);
+ /*FALLTHROUGH*/
+ case 'A': /* The process should silently die. */
+ case 'C': /* The handler should have been called. */
+ fprintf (stderr, "write() returned %d with error %d.\n", ret, errno);
+ exit (1);
+ }
+ }
+ }
+}
--- /dev/null
+#!/bin/sh
+
+tmpfiles=""
+trap 'rm -fr $tmpfiles' 1 2 3 15
+
+# Test signal's default behaviour.
+tmpfiles="$tmpfiles t-sigpipeA.tmp"
+./test-sigpipe${EXEEXT} A 2> t-sigpipeA.tmp | head -1 > /dev/null
+if test -s t-sigpipeA.tmp; then
+ LC_ALL=C tr -d '\r' < t-sigpipeA.tmp
+ rm -fr $tmpfiles; exit 1
+fi
+
+# Test signal's ignored behaviour.
+tmpfiles="$tmpfiles t-sigpipeB.tmp"
+./test-sigpipe${EXEEXT} B 2> t-sigpipeB.tmp | head -1 > /dev/null
+if test -s t-sigpipeB.tmp; then
+ LC_ALL=C tr -d '\r' < t-sigpipeB.tmp
+ rm -fr $tmpfiles; exit 1
+fi
+
+# Test signal's behaviour when a handler is installed.
+tmpfiles="$tmpfiles t-sigpipeC.tmp"
+./test-sigpipe${EXEEXT} B 2> t-sigpipeC.tmp | head -1 > /dev/null
+if test -s t-sigpipeC.tmp; then
+ LC_ALL=C tr -d '\r' < t-sigpipeC.tmp
+ rm -fr $tmpfiles; exit 1
+fi
+
+rm -fr $tmpfiles
+exit 0