annotate lib/pipe-filter-ii.c @ 13745:6328b8d2c617

Separate the module 'waitpid' from the module 'sys_wait'. * lib/sys_wait.in.h (waitpid): Declare only if the 'waitpid' module is present. * m4/sys_wait_h.m4 (gl_SYS_WAIT_MODULE_INDICATOR): Invoke gl_MODULE_INDICATOR_FOR_TESTS. (gl_SYS_WAIT_H_DEFAULTS): Initialize GNULIB_WAITPID. * modules/sys_wait (Depends-on): Remove waitpid. (Makefile.am): Substitute GNULIB_WAITPID. * modules/waitpid (configure.ac): Invoke gl_SYS_WAIT_MODULE_INDICATOR. * tests/test-sys_wait-c++.cc (GNULIB_NAMESPACE::waitpid): Check the signature only if the 'waitpid' module is present. * doc/posix-functions/waitpid.texi: Mention the 'waitpid' module. * NEWS: Mention the change. * modules/grantpt (Depends-on): Add waitpid. * modules/wait-process (Depends-on): Likewise.
author Bruno Haible <bruno@clisp.org>
date Wed, 29 Sep 2010 16:14:55 +0200
parents c2cbabec01dd
children 5be0c314f2f8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Filtering of data through a subprocess.
12559
c2cbabec01dd update nearly all FSF copyright year lists to include 2010
Jim Meyering <meyering@redhat.com>
parents: 12421
diff changeset
2 Copyright (C) 2001-2003, 2008-2010 Free Software Foundation, Inc.
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Bruno Haible <bruno@clisp.org>, 2009.
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 (at your option) any later version.
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 GNU General Public License for more details.
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
17
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18 #include <config.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20 #include "pipe-filter.h"
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22 #include <errno.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <fcntl.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include <stdbool.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include <stdint.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include <stdlib.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #include <unistd.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
29 # include <windows.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 #else
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 # include <signal.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 # include <sys/select.h>
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 #endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35 #include "error.h"
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 #include "pipe.h"
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
37 #include "wait-process.h"
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 #include "gettext.h"
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 #define _(str) gettext (str)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42 #include "pipe-filter-aux.h"
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 struct locals
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 /* Arguments passed to pipe_filter_ii_execute. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 prepare_write_fn prepare_write;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 done_write_fn done_write;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51 prepare_read_fn prepare_read;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 done_read_fn done_read;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 /* Management of the subprocess. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55 void *private_data;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 int fd[2];
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 /* Status of the writer part. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 volatile bool writer_terminated;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 volatile int writer_errno;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61 /* Status of the reader part. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 volatile bool reader_terminated;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 volatile int reader_errno;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 };
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 static unsigned int WINAPI
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 writer_thread_func (void *thread_arg)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
69 struct locals *l = (struct locals *) thread_arg;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 for (;;)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 size_t bufsize;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 const void *buf = l->prepare_write (&bufsize, l->private_data);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 if (buf != NULL)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
76 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
77 ssize_t nwritten =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
78 write (l->fd[1], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
79 if (nwritten < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
80 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
81 /* Don't assume that the gnulib modules 'write' and 'sigpipe' are
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
82 used. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
83 if (GetLastError () == ERROR_NO_DATA)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
84 errno = EPIPE;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
85 l->writer_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
86 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
87 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
88 else if (nwritten > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
89 l->done_write ((void *) buf, nwritten, l->private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
90 }
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
92 break;
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
94
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
95 l->writer_terminated = true;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96 _endthreadex (0); /* calls ExitThread (0) */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97 abort ();
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
98 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
99
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100 static unsigned int WINAPI
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 reader_thread_func (void *thread_arg)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 struct locals *l = (struct locals *) thread_arg;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105 for (;;)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 size_t bufsize;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 void *buf = l->prepare_read (&bufsize, l->private_data);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 if (!(buf != NULL && bufsize > 0))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
110 /* prepare_read returned wrong values. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
111 abort ();
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
112 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
113 ssize_t nread =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
114 read (l->fd[0], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
115 if (nread < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
116 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
117 l->reader_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
118 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
119 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
120 else if (nread > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
121 l->done_read (buf, nread, l->private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
122 else /* nread == 0 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
123 break;
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
124 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
125 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
126
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
127 l->reader_terminated = true;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
128 _endthreadex (0); /* calls ExitThread (0) */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
129 abort ();
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
131
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132 #endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 int
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135 pipe_filter_ii_execute (const char *progname,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
136 const char *prog_path, const char **prog_argv,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
137 bool null_stderr, bool exit_on_error,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
138 prepare_write_fn prepare_write,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
139 done_write_fn done_write,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
140 prepare_read_fn prepare_read,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
141 done_read_fn done_read,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
142 void *private_data)
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144 pid_t child;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 int fd[2];
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
146 #if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
147 struct sigaction orig_sigpipe_action;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148 #endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
149
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
150 /* Open a bidirectional pipe to a subprocess. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
151 child = create_pipe_bidi (progname, prog_path, (char **) prog_argv,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
152 null_stderr, true, exit_on_error,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
153 fd);
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
154 if (child == -1)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
155 return -1;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
156
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
158 /* Native Woe32 API. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159 /* Pipes have a non-blocking mode, see function SetNamedPipeHandleState and
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
160 the article "Named Pipe Type, Read, and Wait Modes", but Microsoft's
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
161 documentation discourages its use. So don't use it.
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 Asynchronous I/O is also not suitable because it notifies the caller only
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
163 about completion of the I/O request, not about intermediate progress.
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
164 So do the writing and the reading in separate threads. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
165 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
166 struct locals l;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
167 HANDLE handles[2];
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
168 #define writer_thread_handle handles[0]
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
169 #define reader_thread_handle handles[1]
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
170 bool writer_cleaned_up;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
171 bool reader_cleaned_up;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
172
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
173 l.prepare_write = prepare_write;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
174 l.done_write = done_write;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
175 l.prepare_read = prepare_read;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
176 l.done_read = done_read;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
177 l.private_data = private_data;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
178 l.fd[0] = fd[0];
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
179 l.fd[1] = fd[1];
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
180 l.writer_terminated = false;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
181 l.writer_errno = 0;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
182 l.reader_terminated = false;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
183 l.reader_errno = 0;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
184
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
185 writer_thread_handle =
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
186 (HANDLE) _beginthreadex (NULL, 100000, writer_thread_func, &l, 0, NULL);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
187 reader_thread_handle =
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
188 (HANDLE) _beginthreadex (NULL, 100000, reader_thread_func, &l, 0, NULL);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
189 if (writer_thread_handle == NULL || reader_thread_handle == NULL)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
190 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
191 if (exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
192 error (EXIT_FAILURE, 0, _("creation of threads failed"));
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
193 if (reader_thread_handle != NULL)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
194 CloseHandle (reader_thread_handle);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
195 if (writer_thread_handle != NULL)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
196 CloseHandle (writer_thread_handle);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
197 goto fail;
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
198 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
199 writer_cleaned_up = false;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
200 reader_cleaned_up = false;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
201 for (;;)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
202 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
203 DWORD ret;
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
204
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
205 /* Here !(writer_cleaned_up && reader_cleaned_up). */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
206 if (writer_cleaned_up)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
207 ret = WaitForSingleObject (reader_thread_handle, INFINITE);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
208 else if (reader_cleaned_up)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
209 ret = WaitForSingleObject (writer_thread_handle, INFINITE);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
210 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
211 ret = WaitForMultipleObjects (2, handles, FALSE, INFINITE);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
212 if (!(ret == WAIT_OBJECT_0 + 0 || ret == WAIT_OBJECT_0 + 1))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
213 abort ();
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
214
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
215 if (l.writer_terminated)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
216 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
217 /* The writer thread has just terminated. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
218 l.writer_terminated = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
219 CloseHandle (writer_thread_handle);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
220 if (l.writer_errno)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
221 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
222 if (exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
223 error (EXIT_FAILURE, l.writer_errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
224 _("write to %s subprocess failed"), progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
225 if (!reader_cleaned_up)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
226 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
227 TerminateThread (reader_thread_handle, 1);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
228 CloseHandle (reader_thread_handle);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
229 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
230 goto fail;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
231 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
232 /* Tell the child there is nothing more the parent will send. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
233 close (fd[1]);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
234 writer_cleaned_up = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
235 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
236 if (l.reader_terminated)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
237 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
238 /* The reader thread has just terminated. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
239 l.reader_terminated = false;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
240 CloseHandle (reader_thread_handle);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
241 if (l.reader_errno)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
242 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
243 if (exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
244 error (EXIT_FAILURE, l.reader_errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
245 _("read from %s subprocess failed"), progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
246 if (!writer_cleaned_up)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
247 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
248 TerminateThread (writer_thread_handle, 1);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
249 CloseHandle (writer_thread_handle);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
250 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
251 goto fail;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
252 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
253 reader_cleaned_up = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
254 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
255 if (writer_cleaned_up && reader_cleaned_up)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
256 break;
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
257 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
258 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
259 #else
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
260 /* When we write to the child process and it has just terminated,
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
261 we don't want to die from a SIGPIPE signal. So set the SIGPIPE
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
262 handler to SIG_IGN, and handle EPIPE error codes in write(). */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
263 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
264 struct sigaction sigpipe_action;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
265
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
266 sigpipe_action.sa_handler = SIG_IGN;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
267 sigpipe_action.sa_flags = 0;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
268 sigemptyset (&sigpipe_action.sa_mask);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
269 if (sigaction (SIGPIPE, &sigpipe_action, &orig_sigpipe_action) < 0)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
270 abort ();
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
271 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
272
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
273 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
274 # if HAVE_SELECT
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
275 fd_set readfds; /* All bits except fd[0] are always cleared. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
276 fd_set writefds; /* All bits except fd[1] are always cleared. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
277 # endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
278 bool done_writing;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
279
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
280 /* Enable non-blocking I/O. This permits the read() and write() calls
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
281 to return -1/EAGAIN without blocking; this is important for polling
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
282 if HAVE_SELECT is not defined. It also permits the read() and write()
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
283 calls to return after partial reads/writes; this is important if
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
284 HAVE_SELECT is defined, because select() only says that some data
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
285 can be read or written, not how many. Without non-blocking I/O,
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
286 Linux 2.2.17 and BSD systems prefer to block instead of returning
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
287 with partial results. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
288 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
289 int fcntl_flags;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
290
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
291 if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
292 || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
293 || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
294 || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
295 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
296 if (exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
297 error (EXIT_FAILURE, errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
298 _("cannot set up nonblocking I/O to %s subprocess"),
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
299 progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
300 goto fail;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
301 }
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
302 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
303
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
304 # if HAVE_SELECT
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
305 FD_ZERO (&readfds);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
306 FD_ZERO (&writefds);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
307 # endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
308 done_writing = false;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
309 for (;;)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
310 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
311 # if HAVE_SELECT
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
312 int n;
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
313
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
314 FD_SET (fd[0], &readfds);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
315 n = fd[0] + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
316 if (!done_writing)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
317 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
318 FD_SET (fd[1], &writefds);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
319 if (n <= fd[1])
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
320 n = fd[1] + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
321 }
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
322
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
323 n = select (n, &readfds, (!done_writing ? &writefds : NULL), NULL,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
324 NULL);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
325 if (n < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
326 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
327 if (exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
328 error (EXIT_FAILURE, errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
329 _("communication with %s subprocess failed"), progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
330 goto fail;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
331 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
332 if (!done_writing && FD_ISSET (fd[1], &writefds))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
333 goto try_write;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
334 if (FD_ISSET (fd[0], &readfds))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
335 goto try_read;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
336 /* How could select() return if none of the two descriptors is ready? */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
337 abort ();
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
338 # endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
339
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
340 /* Attempt to write. */
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
341 # if HAVE_SELECT
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
342 try_write:
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
343 # endif
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
344 if (!done_writing)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
345 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
346 size_t bufsize;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
347 const void *buf = prepare_write (&bufsize, private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
348 if (buf != NULL)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
349 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
350 ssize_t nwritten =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
351 write (fd[1], buf,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
352 bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
353 if (nwritten < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
354 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
355 if (!IS_EAGAIN (errno))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
356 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
357 if (exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
358 error (EXIT_FAILURE, errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
359 _("write to %s subprocess failed"), progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
360 goto fail;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
361 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
362 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
363 else if (nwritten > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
364 done_write ((void *) buf, nwritten, private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
365 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
366 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
367 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
368 /* Tell the child there is nothing more the parent will send. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
369 close (fd[1]);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
370 done_writing = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
371 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
372 }
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
373 # if HAVE_SELECT
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
374 continue;
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
375 # endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
376
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
377 /* Attempt to read. */
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
378 # if HAVE_SELECT
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
379 try_read:
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
380 # endif
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
381 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
382 size_t bufsize;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
383 void *buf = prepare_read (&bufsize, private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
384 if (!(buf != NULL && bufsize > 0))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
385 /* prepare_read returned wrong values. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
386 abort ();
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
387 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
388 ssize_t nread =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
389 read (fd[0], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
390 if (nread < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
391 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
392 if (!IS_EAGAIN (errno))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
393 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
394 if (exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
395 error (EXIT_FAILURE, errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
396 _("read from %s subprocess failed"), progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
397 goto fail;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
398 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
399 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
400 else if (nread > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
401 done_read (buf, nread, private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
402 else /* nread == 0 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
403 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
404 if (done_writing)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
405 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
406 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
407 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
408 }
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
409 # if HAVE_SELECT
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
410 continue;
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
411 # endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
412 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
413 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
414
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
415 /* Restore SIGPIPE signal handler. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
416 if (sigaction (SIGPIPE, &orig_sigpipe_action, NULL) < 0)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
417 abort ();
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
418 #endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
419
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
420 close (fd[0]);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
421
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
422 /* Remove zombie process from process list. */
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
423 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
424 int exitstatus =
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
425 wait_subprocess (child, progname, false, null_stderr,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
426 true, exit_on_error, NULL);
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
427 if (exitstatus != 0 && exit_on_error)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
428 error (EXIT_FAILURE, 0, _("%s subprocess terminated with exit code %d"),
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
429 progname, exitstatus);
11758
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
430 return exitstatus;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
431 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
432
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
433 fail:
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
434 {
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
435 int saved_errno = errno;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
436 close (fd[1]);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
437 #if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
438 if (sigaction (SIGPIPE, &orig_sigpipe_action, NULL) < 0)
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
439 abort ();
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
440 #endif
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
441 close (fd[0]);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
442 wait_subprocess (child, progname, true, true, true, false, NULL);
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
443 errno = saved_errno;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
444 return -1;
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
445 }
c4cba25224b1 New module 'pipe-filter-ii'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
446 }