1 /* Filtering of data through a subprocess.
2 Copyright (C) 2001-2003, 2008-2016 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2009.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "pipe-filter.h"
28 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
30 #elif defined __KLIBC__
34 /* Simple implementation of Win32 APIs */
38 typedef struct _HANDLE
42 unsigned int WINAPI (*start) (void *);
49 start_wrapper (void *arg)
51 HANDLE h = (HANDLE) arg;
55 DosPostEventSem (h->hevDone);
60 _beginthreadex (void *s, unsigned n, unsigned int WINAPI (*start) (void *),
61 void *arg, unsigned fl, unsigned *th)
65 h = malloc (sizeof (*h));
69 if (DosCreateEventSem (NULL, &h->hevDone, 0, FALSE))
75 h->tid = _beginthread (start_wrapper, NULL, n, (void *) h);
77 goto exit_close_event_sem;
82 DosCloseEventSem (h->hevDone);
91 CloseHandle (HANDLE h)
93 DosCloseEventSem (h->hevDone);
97 # define _endthreadex(x) return (x)
98 # define TerminateThread(h, e) DosKillThread (h->tid)
100 # define GetLastError() -1
102 # ifndef ERROR_NO_DATA
103 # define ERROR_NO_DATA 232
106 # define INFINITE SEM_INDEFINITE_WAIT
107 # define WAIT_OBJECT_0 0
110 WaitForSingleObject (HANDLE h, DWORD ms)
112 return DosWaitEventSem (h->hevDone, ms) == 0 ? WAIT_OBJECT_0 : (DWORD) -1;
116 WaitForMultipleObjects (DWORD nCount, const HANDLE *pHandles, BOOL bWaitAll,
122 ULONG rc = (ULONG) -1;
125 psr = malloc (sizeof (*psr) * nCount);
129 for (i = 0; i < nCount; ++i)
131 psr[i].hsemCur = (HSEM) pHandles[i]->hevDone;
132 psr[i].ulUser = WAIT_OBJECT_0 + i;
135 if (DosCreateMuxWaitSem (NULL, &hmux, nCount, psr,
136 bWaitAll ? DCMW_WAIT_ALL : DCMW_WAIT_ANY))
139 rc = DosWaitMuxWaitSem (hmux, ms, &ulUser);
140 DosCloseMuxWaitSem (hmux);
153 # include <sys/select.h>
157 #include "spawn-pipe.h"
158 #include "wait-process.h"
161 #define _(str) gettext (str)
163 #include "pipe-filter-aux.h"
165 #if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
166 || defined __KLIBC__)
170 /* Arguments passed to pipe_filter_ii_execute. */
171 prepare_write_fn prepare_write;
172 done_write_fn done_write;
173 prepare_read_fn prepare_read;
174 done_read_fn done_read;
176 /* Management of the subprocess. */
180 /* Status of the writer part. */
181 volatile bool writer_terminated;
182 volatile int writer_errno;
183 /* Status of the reader part. */
184 volatile bool reader_terminated;
185 volatile int reader_errno;
188 static unsigned int WINAPI
189 writer_thread_func (void *thread_arg)
191 struct locals *l = (struct locals *) thread_arg;
196 const void *buf = l->prepare_write (&bufsize, l->private_data);
200 write (l->fd[1], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
203 /* Don't assume that the gnulib modules 'write' and 'sigpipe' are
205 if (GetLastError () == ERROR_NO_DATA)
207 l->writer_errno = errno;
210 else if (nwritten > 0)
211 l->done_write ((void *) buf, nwritten, l->private_data);
217 l->writer_terminated = true;
218 _endthreadex (0); /* calls ExitThread (0) */
222 static unsigned int WINAPI
223 reader_thread_func (void *thread_arg)
225 struct locals *l = (struct locals *) thread_arg;
230 void *buf = l->prepare_read (&bufsize, l->private_data);
231 if (!(buf != NULL && bufsize > 0))
232 /* prepare_read returned wrong values. */
236 read (l->fd[0], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
239 l->reader_errno = errno;
243 l->done_read (buf, nread, l->private_data);
244 else /* nread == 0 */
249 l->reader_terminated = true;
250 _endthreadex (0); /* calls ExitThread (0) */
257 pipe_filter_ii_execute (const char *progname,
258 const char *prog_path, const char **prog_argv,
259 bool null_stderr, bool exit_on_error,
260 prepare_write_fn prepare_write,
261 done_write_fn done_write,
262 prepare_read_fn prepare_read,
263 done_read_fn done_read,
268 #if !(((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
269 || defined __KLIBC__)
270 struct sigaction orig_sigpipe_action;
273 /* Open a bidirectional pipe to a subprocess. */
274 child = create_pipe_bidi (progname, prog_path, (char **) prog_argv,
275 null_stderr, true, exit_on_error,
280 #if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
281 || defined __KLIBC__)
282 /* Native Windows API. */
283 /* Pipes have a non-blocking mode, see function SetNamedPipeHandleState and
284 the article "Named Pipe Type, Read, and Wait Modes", but Microsoft's
285 documentation discourages its use. So don't use it.
286 Asynchronous I/O is also not suitable because it notifies the caller only
287 about completion of the I/O request, not about intermediate progress.
288 So do the writing and the reading in separate threads. */
292 #define writer_thread_handle handles[0]
293 #define reader_thread_handle handles[1]
294 bool writer_cleaned_up;
295 bool reader_cleaned_up;
297 l.prepare_write = prepare_write;
298 l.done_write = done_write;
299 l.prepare_read = prepare_read;
300 l.done_read = done_read;
301 l.private_data = private_data;
304 l.writer_terminated = false;
306 l.reader_terminated = false;
309 writer_thread_handle =
310 (HANDLE) _beginthreadex (NULL, 100000, writer_thread_func, &l, 0, NULL);
311 reader_thread_handle =
312 (HANDLE) _beginthreadex (NULL, 100000, reader_thread_func, &l, 0, NULL);
313 if (writer_thread_handle == NULL || reader_thread_handle == NULL)
316 error (EXIT_FAILURE, 0, _("creation of threads failed"));
317 if (reader_thread_handle != NULL)
318 CloseHandle (reader_thread_handle);
319 if (writer_thread_handle != NULL)
320 CloseHandle (writer_thread_handle);
323 writer_cleaned_up = false;
324 reader_cleaned_up = false;
329 /* Here !(writer_cleaned_up && reader_cleaned_up). */
330 if (writer_cleaned_up)
331 ret = WaitForSingleObject (reader_thread_handle, INFINITE);
332 else if (reader_cleaned_up)
333 ret = WaitForSingleObject (writer_thread_handle, INFINITE);
335 ret = WaitForMultipleObjects (2, handles, FALSE, INFINITE);
336 if (!(ret == WAIT_OBJECT_0 + 0 || ret == WAIT_OBJECT_0 + 1))
339 if (l.writer_terminated)
341 /* The writer thread has just terminated. */
342 l.writer_terminated = false;
343 CloseHandle (writer_thread_handle);
347 error (EXIT_FAILURE, l.writer_errno,
348 _("write to %s subprocess failed"), progname);
349 if (!reader_cleaned_up)
351 TerminateThread (reader_thread_handle, 1);
352 CloseHandle (reader_thread_handle);
356 /* Tell the child there is nothing more the parent will send. */
358 writer_cleaned_up = true;
360 if (l.reader_terminated)
362 /* The reader thread has just terminated. */
363 l.reader_terminated = false;
364 CloseHandle (reader_thread_handle);
368 error (EXIT_FAILURE, l.reader_errno,
369 _("read from %s subprocess failed"), progname);
370 if (!writer_cleaned_up)
372 TerminateThread (writer_thread_handle, 1);
373 CloseHandle (writer_thread_handle);
377 reader_cleaned_up = true;
379 if (writer_cleaned_up && reader_cleaned_up)
384 /* When we write to the child process and it has just terminated,
385 we don't want to die from a SIGPIPE signal. So set the SIGPIPE
386 handler to SIG_IGN, and handle EPIPE error codes in write(). */
388 struct sigaction sigpipe_action;
390 sigpipe_action.sa_handler = SIG_IGN;
391 sigpipe_action.sa_flags = 0;
392 sigemptyset (&sigpipe_action.sa_mask);
393 if (sigaction (SIGPIPE, &sigpipe_action, &orig_sigpipe_action) < 0)
399 fd_set readfds; /* All bits except fd[0] are always cleared. */
400 fd_set writefds; /* All bits except fd[1] are always cleared. */
404 /* Enable non-blocking I/O. This permits the read() and write() calls
405 to return -1/EAGAIN without blocking; this is important for polling
406 if HAVE_SELECT is not defined. It also permits the read() and write()
407 calls to return after partial reads/writes; this is important if
408 HAVE_SELECT is defined, because select() only says that some data
409 can be read or written, not how many. Without non-blocking I/O,
410 Linux 2.2.17 and BSD systems prefer to block instead of returning
411 with partial results. */
415 if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0
416 || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1
417 || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0
418 || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1)
421 error (EXIT_FAILURE, errno,
422 _("cannot set up nonblocking I/O to %s subprocess"),
432 done_writing = false;
438 FD_SET (fd[0], &readfds);
442 FD_SET (fd[1], &writefds);
447 /* Do EINTR handling here instead of in pipe-filter-aux.h,
448 because select() cannot be referred to from an inline
449 function on AIX 7.1. */
451 retval = select (n, &readfds, (!done_writing ? &writefds : NULL),
453 while (retval < 0 && errno == EINTR);
459 error (EXIT_FAILURE, errno,
460 _("communication with %s subprocess failed"), progname);
463 if (!done_writing && FD_ISSET (fd[1], &writefds))
465 if (FD_ISSET (fd[0], &readfds))
467 /* How could select() return if none of the two descriptors is ready? */
471 /* Attempt to write. */
478 const void *buf = prepare_write (&bufsize, private_data);
481 /* Writing to a pipe in non-blocking mode is tricky: The
482 write() call may fail with EAGAIN, simply because sufficient
483 space is not available in the pipe. See POSIX:2008
484 <http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html>.
485 This happens actually on AIX and IRIX, when bufsize >= 8192
486 (even though PIPE_BUF and pathconf ("/", _PC_PIPE_BUF) are
488 size_t attempt_to_write =
489 (bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
492 ssize_t nwritten = write (fd[1], buf, attempt_to_write);
497 attempt_to_write = attempt_to_write / 2;
498 if (attempt_to_write == 0)
501 else if (!IS_EAGAIN (errno))
504 error (EXIT_FAILURE, errno,
505 _("write to %s subprocess failed"),
513 done_write ((void *) buf, nwritten, private_data);
520 /* Tell the child there is nothing more the parent will send. */
529 /* Attempt to read. */
535 void *buf = prepare_read (&bufsize, private_data);
536 if (!(buf != NULL && bufsize > 0))
537 /* prepare_read returned wrong values. */
541 read (fd[0], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
544 if (!IS_EAGAIN (errno))
547 error (EXIT_FAILURE, errno,
548 _("read from %s subprocess failed"), progname);
553 done_read (buf, nread, private_data);
554 else /* nread == 0 */
567 /* Restore SIGPIPE signal handler. */
568 if (sigaction (SIGPIPE, &orig_sigpipe_action, NULL) < 0)
574 /* Remove zombie process from process list. */
577 wait_subprocess (child, progname, false, null_stderr,
578 true, exit_on_error, NULL);
579 if (exitstatus != 0 && exit_on_error)
580 error (EXIT_FAILURE, 0, _("%s subprocess terminated with exit code %d"),
581 progname, exitstatus);
587 int saved_errno = errno;
589 #if !(((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
590 || defined __KLIBC__)
591 if (sigaction (SIGPIPE, &orig_sigpipe_action, NULL) < 0)
595 wait_subprocess (child, progname, true, true, true, false, NULL);