1 /* Filtering of data through a subprocess.
2 Copyright (C) 2001-2003, 2008-2020 Free Software Foundation, Inc.
3 Written by Paolo Bonzini <bonzini@gnu.org>, 2009,
4 and Bruno Haible <bruno@clisp.org>, 2009.
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
21 #include "pipe-filter.h"
29 #if defined _WIN32 && ! defined __CYGWIN__
31 # include <process.h> /* _beginthreadex, _endthreadex */
34 # include <sys/select.h>
38 #include "spawn-pipe.h"
39 #include "wait-process.h"
43 #define _(str) gettext (str)
45 #include "pipe-filter-aux.h"
49 /* Arguments passed to pipe_filter_gi_create. */
53 prepare_read_fn prepare_read
;
54 done_read_fn done_read
;
57 /* Management of the subprocess. */
63 /* Status of the writer part. */
64 volatile bool writer_terminated
;
66 /* Status of the reader part. */
67 volatile bool reader_terminated
;
68 volatile int reader_errno
;
70 #if defined _WIN32 && ! defined __CYGWIN__
71 CRITICAL_SECTION lock
; /* protects the volatile fields */
72 HANDLE reader_thread_handle
;
74 struct sigaction orig_sigpipe_action
;
75 fd_set readfds
; /* All bits except fd[0] are always cleared. */
76 fd_set writefds
; /* All bits except fd[1] are always cleared. */
81 /* Platform dependent functions. */
83 /* Perform additional initializations.
84 Return 0 if successful, -1 upon failure. */
85 static int filter_init (struct pipe_filter_gi
*filter
);
87 /* Write count bytes starting at buf, while at the same time invoking the
88 read iterator (the functions prepare_read/done_read) when needed. */
89 static void filter_loop (struct pipe_filter_gi
*filter
,
90 const char *wbuf
, size_t count
);
92 /* Perform cleanup actions at the end.
93 finish_reading is true if there was no error, or false if some error
95 static void filter_cleanup (struct pipe_filter_gi
*filter
,
99 #if defined _WIN32 && ! defined __CYGWIN__
100 /* Native Windows API. */
102 static unsigned int WINAPI
103 reader_thread_func (void *thread_arg
)
105 struct pipe_filter_gi
*filter
= (struct pipe_filter_gi
*) thread_arg
;
110 void *buf
= filter
->prepare_read (&bufsize
, filter
->private_data
);
111 if (!(buf
!= NULL
&& bufsize
> 0))
112 /* prepare_read returned wrong values. */
116 read (filter
->fd
[0], buf
, bufsize
> SSIZE_MAX
? SSIZE_MAX
: bufsize
);
117 EnterCriticalSection (&filter
->lock
);
118 /* If the writer already encountered an error, terminate. */
119 if (filter
->writer_terminated
)
123 filter
->reader_errno
= errno
;
127 filter
->done_read (buf
, nread
, filter
->private_data
);
128 else /* nread == 0 */
130 LeaveCriticalSection (&filter
->lock
);
134 filter
->reader_terminated
= true;
135 LeaveCriticalSection (&filter
->lock
);
136 _endthreadex (0); /* calls ExitThread (0) */
141 filter_init (struct pipe_filter_gi
*filter
)
143 InitializeCriticalSection (&filter
->lock
);
144 EnterCriticalSection (&filter
->lock
);
146 filter
->reader_thread_handle
=
147 (HANDLE
) _beginthreadex (NULL
, 100000, reader_thread_func
, filter
,
150 if (filter
->reader_thread_handle
== NULL
)
152 if (filter
->exit_on_error
)
153 error (EXIT_FAILURE
, 0, _("creation of reading thread failed"));
161 filter_loop (struct pipe_filter_gi
*filter
, const char *wbuf
, size_t count
)
163 if (!filter
->writer_terminated
)
169 /* Allow the reader thread to continue. */
170 LeaveCriticalSection (&filter
->lock
);
173 write (filter
->fd
[1], wbuf
, count
> SSIZE_MAX
? SSIZE_MAX
: count
);
175 /* Get the lock back from the reader thread. */
176 EnterCriticalSection (&filter
->lock
);
180 /* Don't assume that the gnulib modules 'write' and 'sigpipe' are
182 if (GetLastError () == ERROR_NO_DATA
)
184 filter
->writer_errno
= errno
;
185 filter
->writer_terminated
= true;
188 else if (nwritten
> 0)
195 else /* nwritten == 0 */
197 filter
->writer_terminated
= true;
205 filter_cleanup (struct pipe_filter_gi
*filter
, bool finish_reading
)
209 LeaveCriticalSection (&filter
->lock
);
210 WaitForSingleObject (filter
->reader_thread_handle
, INFINITE
);
213 TerminateThread (filter
->reader_thread_handle
, 1);
215 CloseHandle (filter
->reader_thread_handle
);
216 DeleteCriticalSection (&filter
->lock
);
223 filter_init (struct pipe_filter_gi
*filter
)
225 #if !(defined _WIN32 && ! defined __CYGWIN__)
226 /* When we write to the child process and it has just terminated,
227 we don't want to die from a SIGPIPE signal. So set the SIGPIPE
228 handler to SIG_IGN, and handle EPIPE error codes in write(). */
230 struct sigaction sigpipe_action
;
232 sigpipe_action
.sa_handler
= SIG_IGN
;
233 sigpipe_action
.sa_flags
= 0;
234 sigemptyset (&sigpipe_action
.sa_mask
);
235 if (sigaction (SIGPIPE
, &sigpipe_action
, &filter
->orig_sigpipe_action
) < 0)
240 /* Enable non-blocking I/O. This permits the read() and write() calls
241 to return -1/EAGAIN without blocking; this is important for polling
242 if HAVE_SELECT is not defined. It also permits the read() and write()
243 calls to return after partial reads/writes; this is important if
244 HAVE_SELECT is defined, because select() only says that some data
245 can be read or written, not how many. Without non-blocking I/O,
246 Linux 2.2.17 and BSD systems prefer to block instead of returning
247 with partial results. */
251 if ((fcntl_flags
= fcntl (filter
->fd
[1], F_GETFL
, 0)) < 0
252 || fcntl (filter
->fd
[1], F_SETFL
, fcntl_flags
| O_NONBLOCK
) == -1
253 || (fcntl_flags
= fcntl (filter
->fd
[0], F_GETFL
, 0)) < 0
254 || fcntl (filter
->fd
[0], F_SETFL
, fcntl_flags
| O_NONBLOCK
) == -1)
256 if (filter
->exit_on_error
)
257 error (EXIT_FAILURE
, errno
,
258 _("cannot set up nonblocking I/O to %s subprocess"),
264 FD_ZERO (&filter
->readfds
);
265 FD_ZERO (&filter
->writefds
);
271 filter_loop (struct pipe_filter_gi
*filter
, const char *wbuf
, size_t count
)
273 /* This function is used in two situations:
274 - in order to write some data to the subprocess
275 [done_writing = false],
276 - in order to read the remaining data after everything was written
277 [done_writing = true]. In this case buf is NULL and count is
279 bool done_writing
= (wbuf
== NULL
);
283 if (filter
->writer_terminated
|| filter
->reader_terminated
)
284 /* pipe_filter_gi_write was called when it should not be. */
289 if (filter
->reader_terminated
)
293 /* Loop, trying to write the given buffer or reading, whichever is
297 /* Here filter->writer_terminated is false. When it becomes true, this
298 loop is terminated. */
299 /* Whereas filter->reader_terminated is initially false but may become
300 true during this loop. */
301 /* Here, if !done_writing, count > 0. When count becomes 0, this loop
303 /* Here, if done_writing, filter->reader_terminated is false. When
304 filter->reader_terminated becomes true, this loop is terminated. */
308 /* See whether reading or writing is possible. */
310 if (!filter
->reader_terminated
)
312 FD_SET (filter
->fd
[0], &filter
->readfds
);
313 n
= filter
->fd
[0] + 1;
317 FD_SET (filter
->fd
[1], &filter
->writefds
);
318 if (n
<= filter
->fd
[1])
319 n
= filter
->fd
[1] + 1;
321 /* Do EINTR handling here instead of in pipe-filter-aux.h,
322 because select() cannot be referred to from an inline
323 function on AIX 7.1. */
326 (!filter
->reader_terminated
? &filter
->readfds
: NULL
),
327 (!done_writing
? &filter
->writefds
: NULL
),
329 while (retval
< 0 && errno
== EINTR
);
334 if (filter
->exit_on_error
)
335 error (EXIT_FAILURE
, errno
,
336 _("communication with %s subprocess failed"),
338 filter
->writer_errno
= errno
;
339 filter
->writer_terminated
= true;
343 if (!done_writing
&& FD_ISSET (filter
->fd
[1], &filter
->writefds
))
345 if (!filter
->reader_terminated
346 && FD_ISSET (filter
->fd
[0], &filter
->readfds
))
348 /* How could select() return if none of the two descriptors is ready? */
352 /* Attempt to write. */
359 write (filter
->fd
[1], wbuf
, count
> SSIZE_MAX
? SSIZE_MAX
: count
);
362 if (!IS_EAGAIN (errno
))
364 if (filter
->exit_on_error
)
365 error (EXIT_FAILURE
, errno
,
366 _("write to %s subprocess failed"),
368 filter
->writer_errno
= errno
;
369 filter
->writer_terminated
= true;
373 else if (nwritten
> 0)
385 /* Attempt to read. */
389 if (!filter
->reader_terminated
)
392 void *buf
= filter
->prepare_read (&bufsize
, filter
->private_data
);
393 if (!(buf
!= NULL
&& bufsize
> 0))
394 /* prepare_read returned wrong values. */
398 read (filter
->fd
[0], buf
,
399 bufsize
> SSIZE_MAX
? SSIZE_MAX
: bufsize
);
402 if (!IS_EAGAIN (errno
))
404 if (filter
->exit_on_error
)
405 error (EXIT_FAILURE
, errno
,
406 _("read from %s subprocess failed"),
408 filter
->reader_errno
= errno
;
409 filter
->reader_terminated
= true;
414 filter
->done_read (buf
, nread
, filter
->private_data
);
415 else /* nread == 0 */
417 filter
->reader_terminated
= true;
430 filter_cleanup (struct pipe_filter_gi
*filter
, bool finish_reading
)
433 /* A select loop, with done_writing = true. */
434 filter_loop (filter
, NULL
, 0);
436 if (sigaction (SIGPIPE
, &filter
->orig_sigpipe_action
, NULL
) < 0)
443 /* Terminate the child process. Do nothing if it already exited. */
445 filter_terminate (struct pipe_filter_gi
*filter
)
449 /* Tell the child there is nothing more the parent will send. */
450 close (filter
->fd
[1]);
451 filter_cleanup (filter
, !filter
->reader_terminated
);
452 close (filter
->fd
[0]);
454 wait_subprocess (filter
->child
, filter
->progname
, true,
455 filter
->null_stderr
, true, filter
->exit_on_error
,
457 if (filter
->exitstatus
!= 0 && filter
->exit_on_error
)
458 error (EXIT_FAILURE
, 0,
459 _("subprocess %s terminated with exit code %d"),
460 filter
->progname
, filter
->exitstatus
);
461 filter
->exited
= true;
465 /* After filter_terminate:
466 Return 0 upon success, or (only if exit_on_error is false):
467 - -1 with errno set upon failure,
468 - the positive exit code of the subprocess if that failed. */
470 filter_retcode (struct pipe_filter_gi
*filter
)
472 if (filter
->writer_errno
!= 0)
474 errno
= filter
->writer_errno
;
477 else if (filter
->reader_errno
!= 0)
479 errno
= filter
->reader_errno
;
483 return filter
->exitstatus
;
486 struct pipe_filter_gi
*
487 pipe_filter_gi_create (const char *progname
,
488 const char *prog_path
, const char **prog_argv
,
489 bool null_stderr
, bool exit_on_error
,
490 prepare_read_fn prepare_read
,
491 done_read_fn done_read
,
494 struct pipe_filter_gi
*filter
;
497 (struct pipe_filter_gi
*) xmalloc (sizeof (struct pipe_filter_gi
));
499 /* Open a bidirectional pipe to a subprocess. */
500 filter
->child
= create_pipe_bidi (progname
, prog_path
, (char **) prog_argv
,
501 null_stderr
, true, exit_on_error
,
503 filter
->progname
= progname
;
504 filter
->null_stderr
= null_stderr
;
505 filter
->exit_on_error
= exit_on_error
;
506 filter
->prepare_read
= prepare_read
;
507 filter
->done_read
= done_read
;
508 filter
->private_data
= private_data
;
509 filter
->exited
= false;
510 filter
->exitstatus
= 0;
511 filter
->writer_terminated
= false;
512 filter
->writer_errno
= 0;
513 filter
->reader_terminated
= false;
514 filter
->reader_errno
= 0;
516 if (filter
->child
== -1)
518 /* Child process could not be created.
519 Arrange for filter_retcode (filter) to be the current errno. */
520 filter
->writer_errno
= errno
;
521 filter
->writer_terminated
= true;
522 filter
->exited
= true;
524 else if (filter_init (filter
) < 0)
525 filter_terminate (filter
);
531 pipe_filter_gi_write (struct pipe_filter_gi
*filter
,
532 const void *buf
, size_t size
)
535 /* Invalid argument. */
539 return filter_retcode (filter
);
543 filter_loop (filter
, buf
, size
);
544 if (filter
->writer_terminated
|| filter
->reader_terminated
)
546 filter_terminate (filter
);
547 return filter_retcode (filter
);
554 pipe_filter_gi_close (struct pipe_filter_gi
*filter
)
559 filter_terminate (filter
);
560 ret
= filter_retcode (filter
);