1 /* Filtering of data through a subprocess.
2 Copyright (C) 2001-2003, 2008-2020 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2009.
4
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.
9
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.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17
18 #include <config.h>
19
20 #include "pipe-filter.h"
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #if defined _WIN32 && ! defined __CYGWIN__
29 # include <windows.h>
30 #elif defined __KLIBC__
31 # define INCL_DOS
32 # include <os2.h>
33
34 /* Simple implementation of Win32 APIs */
35
36 # define WINAPI
37
38 typedef struct _HANDLE
39 {
40 TID tid;
41 HEV hevDone;
42 unsigned int WINAPI (*start) (void *);
43 void *arg;
44 } *HANDLE;
45
46 typedef ULONG DWORD;
47
48 static void
start_wrapper(void * arg)49 start_wrapper (void *arg)
50 {
51 HANDLE h = (HANDLE) arg;
52
53 h->start (h->arg);
54
55 DosPostEventSem (h->hevDone);
56 _endthread ();
57 }
58
59 static HANDLE
_beginthreadex(void * s,unsigned n,unsigned int WINAPI (* start)(void *),void * arg,unsigned fl,unsigned * th)60 _beginthreadex (void *s, unsigned n, unsigned int WINAPI (*start) (void *),
61 void *arg, unsigned fl, unsigned *th)
62 {
63 HANDLE h;
64
65 h = malloc (sizeof (*h));
66 if (!h)
67 return NULL;
68
69 if (DosCreateEventSem (NULL, &h->hevDone, 0, FALSE))
70 goto exit_free;
71
72 h->start = start;
73 h->arg = arg;
74
75 h->tid = _beginthread (start_wrapper, NULL, n, (void *) h);
76 if (h->tid == -1)
77 goto exit_close_event_sem;
78
79 return h;
80
81 exit_close_event_sem:
82 DosCloseEventSem (h->hevDone);
83
84 exit_free:
85 free (h);
86
87 return NULL;
88 }
89
90 static BOOL
CloseHandle(HANDLE h)91 CloseHandle (HANDLE h)
92 {
93 DosCloseEventSem (h->hevDone);
94 free (h);
95 }
96
97 # define _endthreadex(x) return (x)
98 # define TerminateThread(h, e) DosKillThread (h->tid)
99
100 # define GetLastError() -1
101
102 # ifndef ERROR_NO_DATA
103 # define ERROR_NO_DATA 232
104 # endif
105
106 # define INFINITE SEM_INDEFINITE_WAIT
107 # define WAIT_OBJECT_0 0
108
109 static DWORD
WaitForSingleObject(HANDLE h,DWORD ms)110 WaitForSingleObject (HANDLE h, DWORD ms)
111 {
112 return DosWaitEventSem (h->hevDone, ms) == 0 ? WAIT_OBJECT_0 : (DWORD) -1;
113 }
114
115 static DWORD
WaitForMultipleObjects(DWORD nCount,const HANDLE * pHandles,BOOL bWaitAll,DWORD ms)116 WaitForMultipleObjects (DWORD nCount, const HANDLE *pHandles, BOOL bWaitAll,
117 DWORD ms)
118 {
119 HMUX hmux;
120 PSEMRECORD psr;
121 ULONG ulUser;
122 ULONG rc = (ULONG) -1;
123 DWORD i;
124
125 psr = malloc (sizeof (*psr) * nCount);
126 if (!psr)
127 goto exit_return;
128
129 for (i = 0; i < nCount; ++i)
130 {
131 psr[i].hsemCur = (HSEM) pHandles[i]->hevDone;
132 psr[i].ulUser = WAIT_OBJECT_0 + i;
133 }
134
135 if (DosCreateMuxWaitSem (NULL, &hmux, nCount, psr,
136 bWaitAll ? DCMW_WAIT_ALL : DCMW_WAIT_ANY))
137 goto exit_free;
138
139 rc = DosWaitMuxWaitSem (hmux, ms, &ulUser);
140 DosCloseMuxWaitSem (hmux);
141
142 exit_free:
143 free (psr);
144
145 exit_return:
146 if (rc)
147 return (DWORD) -1;
148
149 return ulUser;
150 }
151 #else
152 # include <signal.h>
153 # include <sys/select.h>
154 #endif
155
156 #include "error.h"
157 #include "spawn-pipe.h"
158 #include "wait-process.h"
159 #include "gettext.h"
160
161 #define _(str) gettext (str)
162
163 #include "pipe-filter-aux.h"
164
165 #if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__
166
167 struct locals
168 {
169 /* Arguments passed to pipe_filter_ii_execute. */
170 prepare_write_fn prepare_write;
171 done_write_fn done_write;
172 prepare_read_fn prepare_read;
173 done_read_fn done_read;
174
175 /* Management of the subprocess. */
176 void *private_data;
177 int fd[2];
178
179 /* Status of the writer part. */
180 volatile bool writer_terminated;
181 volatile int writer_errno;
182 /* Status of the reader part. */
183 volatile bool reader_terminated;
184 volatile int reader_errno;
185 };
186
187 static unsigned int WINAPI
writer_thread_func(void * thread_arg)188 writer_thread_func (void *thread_arg)
189 {
190 struct locals *l = (struct locals *) thread_arg;
191
192 for (;;)
193 {
194 size_t bufsize;
195 const void *buf = l->prepare_write (&bufsize, l->private_data);
196 if (buf != NULL)
197 {
198 ssize_t nwritten =
199 write (l->fd[1], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
200 if (nwritten < 0)
201 {
202 /* Don't assume that the gnulib modules 'write' and 'sigpipe' are
203 used. */
204 if (GetLastError () == ERROR_NO_DATA)
205 errno = EPIPE;
206 l->writer_errno = errno;
207 break;
208 }
209 else if (nwritten > 0)
210 l->done_write ((void *) buf, nwritten, l->private_data);
211 }
212 else
213 break;
214 }
215
216 l->writer_terminated = true;
217 _endthreadex (0); /* calls ExitThread (0) */
218 abort ();
219 }
220
221 static unsigned int WINAPI
reader_thread_func(void * thread_arg)222 reader_thread_func (void *thread_arg)
223 {
224 struct locals *l = (struct locals *) thread_arg;
225
226 for (;;)
227 {
228 size_t bufsize;
229 void *buf = l->prepare_read (&bufsize, l->private_data);
230 if (!(buf != NULL && bufsize > 0))
231 /* prepare_read returned wrong values. */
232 abort ();
233 {
234 ssize_t nread =
235 read (l->fd[0], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
236 if (nread < 0)
237 {
238 l->reader_errno = errno;
239 break;
240 }
241 else if (nread > 0)
242 l->done_read (buf, nread, l->private_data);
243 else /* nread == 0 */
244 break;
245 }
246 }
247
248 l->reader_terminated = true;
249 _endthreadex (0); /* calls ExitThread (0) */
250 abort ();
251 }
252
253 #endif
254
255 int
pipe_filter_ii_execute(const char * progname,const char * prog_path,const char ** prog_argv,bool null_stderr,bool exit_on_error,prepare_write_fn prepare_write,done_write_fn done_write,prepare_read_fn prepare_read,done_read_fn done_read,void * private_data)256 pipe_filter_ii_execute (const char *progname,
257 const char *prog_path, const char **prog_argv,
258 bool null_stderr, bool exit_on_error,
259 prepare_write_fn prepare_write,
260 done_write_fn done_write,
261 prepare_read_fn prepare_read,
262 done_read_fn done_read,
263 void *private_data)
264 {
265 pid_t child;
266 int fd[2];
267 #if !((defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__)
268 struct sigaction orig_sigpipe_action;
269 #endif
270
271 /* Open a bidirectional pipe to a subprocess. */
272 child = create_pipe_bidi (progname, prog_path, (char **) prog_argv,
273 null_stderr, true, exit_on_error,
274 fd);
275 if (child == -1)
276 return -1;
277
278 #if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__
279 /* Native Windows API. */
280 /* Pipes have a non-blocking mode, see function SetNamedPipeHandleState and
281 the article "Named Pipe Type, Read, and Wait Modes", but Microsoft's
282 documentation discourages its use. So don't use it.
283 Asynchronous I/O is also not suitable because it notifies the caller only
284 about completion of the I/O request, not about intermediate progress.
285 So do the writing and the reading in separate threads. */
286 {
287 struct locals l;
288 HANDLE handles[2];
289 #define writer_thread_handle handles[0]
290 #define reader_thread_handle handles[1]
291 bool writer_cleaned_up;
292 bool reader_cleaned_up;
293
294 l.prepare_write = prepare_write;
295 l.done_write = done_write;
296 l.prepare_read = prepare_read;
297 l.done_read = done_read;
298 l.private_data = private_data;
299 l.fd[0] = fd[0];
300 l.fd[1] = fd[1];
301 l.writer_terminated = false;
302 l.writer_errno = 0;
303 l.reader_terminated = false;
304 l.reader_errno = 0;
305
306 writer_thread_handle =
307 (HANDLE) _beginthreadex (NULL, 100000, writer_thread_func, &l, 0, NULL);
308 reader_thread_handle =
309 (HANDLE) _beginthreadex (NULL, 100000, reader_thread_func, &l, 0, NULL);
310 if (writer_thread_handle == NULL || reader_thread_handle == NULL)
311 {
312 if (exit_on_error)
313 error (EXIT_FAILURE, 0, _("creation of threads failed"));
314 if (reader_thread_handle != NULL)
315 CloseHandle (reader_thread_handle);
316 if (writer_thread_handle != NULL)
317 CloseHandle (writer_thread_handle);
318 goto fail;
319 }
320 writer_cleaned_up = false;
321 reader_cleaned_up = false;
322 for (;;)
323 {
324 DWORD ret;
325
326 /* Here !(writer_cleaned_up && reader_cleaned_up). */
327 if (writer_cleaned_up)
328 ret = WaitForSingleObject (reader_thread_handle, INFINITE);
329 else if (reader_cleaned_up)
330 ret = WaitForSingleObject (writer_thread_handle, INFINITE);
331 else
332 ret = WaitForMultipleObjects (2, handles, FALSE, INFINITE);
333 if (!(ret == WAIT_OBJECT_0 + 0 || ret == WAIT_OBJECT_0 + 1))
334 abort ();
335
336 if (l.writer_terminated)
337 {
338 /* The writer thread has just terminated. */
339 l.writer_terminated = false;
340 CloseHandle (writer_thread_handle);
341 if (l.writer_errno)
342 {
343 if (exit_on_error)
344 error (EXIT_FAILURE, l.writer_errno,
345 _("write to %s subprocess failed"), progname);
346 if (!reader_cleaned_up)
347 {
348 TerminateThread (reader_thread_handle, 1);
349 CloseHandle (reader_thread_handle);
350 }
351 goto fail;
352 }
353 /* Tell the child there is nothing more the parent will send. */
354 close (fd[1]);
355 writer_cleaned_up = true;
356 }
357 if (l.reader_terminated)
358 {
359 /* The reader thread has just terminated. */
360 l.reader_terminated = false;
361 CloseHandle (reader_thread_handle);
362 if (l.reader_errno)
363 {
364 if (exit_on_error)
365 error (EXIT_FAILURE, l.reader_errno,
366 _("read from %s subprocess failed"), progname);
367 if (!writer_cleaned_up)
368 {
369 TerminateThread (writer_thread_handle, 1);
370 CloseHandle (writer_thread_handle);
371 }
372 goto fail;
373 }
374 reader_cleaned_up = true;
375 }
376 if (writer_cleaned_up && reader_cleaned_up)
377 break;
378 }
379 }
380 #else
381 /* When we write to the child process and it has just terminated,
382 we don't want to die from a SIGPIPE signal. So set the SIGPIPE
383 handler to SIG_IGN, and handle EPIPE error codes in write(). */
384 {
385 struct sigaction sigpipe_action;
386
387 sigpipe_action.sa_handler = SIG_IGN;
388 sigpipe_action.sa_flags = 0;
389 sigemptyset (&sigpipe_action.sa_mask);
390 if (sigaction (SIGPIPE, &sigpipe_action, &orig_sigpipe_action) < 0)
391 abort ();
392 }
393
394 {
395 # if HAVE_SELECT
396 fd_set readfds; /* All bits except fd[0] are always cleared. */
397 fd_set writefds; /* All bits except fd[1] are always cleared. */
398 # endif
399 bool done_writing;
400
401 /* Enable non-blocking I/O. This permits the read() and write() calls
402 to return -1/EAGAIN without blocking; this is important for polling
403 if HAVE_SELECT is not defined. It also permits the read() and write()
404 calls to return after partial reads/writes; this is important if
405 HAVE_SELECT is defined, because select() only says that some data
406 can be read or written, not how many. Without non-blocking I/O,
407 Linux 2.2.17 and BSD systems prefer to block instead of returning
408 with partial results. */
409 {
410 int fcntl_flags;
411
412 if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0
413 || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1
414 || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0
415 || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1)
416 {
417 if (exit_on_error)
418 error (EXIT_FAILURE, errno,
419 _("cannot set up nonblocking I/O to %s subprocess"),
420 progname);
421 goto fail;
422 }
423 }
424
425 # if HAVE_SELECT
426 FD_ZERO (&readfds);
427 FD_ZERO (&writefds);
428 # endif
429 done_writing = false;
430 for (;;)
431 {
432 # if HAVE_SELECT
433 int n, retval;
434
435 FD_SET (fd[0], &readfds);
436 n = fd[0] + 1;
437 if (!done_writing)
438 {
439 FD_SET (fd[1], &writefds);
440 if (n <= fd[1])
441 n = fd[1] + 1;
442 }
443
444 /* Do EINTR handling here instead of in pipe-filter-aux.h,
445 because select() cannot be referred to from an inline
446 function on AIX 7.1. */
447 do
448 retval = select (n, &readfds, (!done_writing ? &writefds : NULL),
449 NULL, NULL);
450 while (retval < 0 && errno == EINTR);
451 n = retval;
452
453 if (n < 0)
454 {
455 if (exit_on_error)
456 error (EXIT_FAILURE, errno,
457 _("communication with %s subprocess failed"), progname);
458 goto fail;
459 }
460 if (!done_writing && FD_ISSET (fd[1], &writefds))
461 goto try_write;
462 if (FD_ISSET (fd[0], &readfds))
463 goto try_read;
464 /* How could select() return if none of the two descriptors is ready? */
465 abort ();
466 # endif
467
468 /* Attempt to write. */
469 # if HAVE_SELECT
470 try_write:
471 # endif
472 if (!done_writing)
473 {
474 size_t bufsize;
475 const void *buf = prepare_write (&bufsize, private_data);
476 if (buf != NULL)
477 {
478 /* Writing to a pipe in non-blocking mode is tricky: The
479 write() call may fail with EAGAIN, simply because sufficient
480 space is not available in the pipe. See POSIX:2008
481 <https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html>.
482 This happens actually on AIX and IRIX, when bufsize >= 8192
483 (even though PIPE_BUF and pathconf ("/", _PC_PIPE_BUF) are
484 both 32768). */
485 size_t attempt_to_write =
486 (bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
487 for (;;)
488 {
489 ssize_t nwritten = write (fd[1], buf, attempt_to_write);
490 if (nwritten < 0)
491 {
492 if (errno == EAGAIN)
493 {
494 attempt_to_write = attempt_to_write / 2;
495 if (attempt_to_write == 0)
496 break;
497 }
498 else if (!IS_EAGAIN (errno))
499 {
500 if (exit_on_error)
501 error (EXIT_FAILURE, errno,
502 _("write to %s subprocess failed"),
503 progname);
504 goto fail;
505 }
506 }
507 else
508 {
509 if (nwritten > 0)
510 done_write ((void *) buf, nwritten, private_data);
511 break;
512 }
513 }
514 }
515 else
516 {
517 /* Tell the child there is nothing more the parent will send. */
518 close (fd[1]);
519 done_writing = true;
520 }
521 }
522 # if HAVE_SELECT
523 continue;
524 # endif
525
526 /* Attempt to read. */
527 # if HAVE_SELECT
528 try_read:
529 # endif
530 {
531 size_t bufsize;
532 void *buf = prepare_read (&bufsize, private_data);
533 if (!(buf != NULL && bufsize > 0))
534 /* prepare_read returned wrong values. */
535 abort ();
536 {
537 ssize_t nread =
538 read (fd[0], buf, bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
539 if (nread < 0)
540 {
541 if (!IS_EAGAIN (errno))
542 {
543 if (exit_on_error)
544 error (EXIT_FAILURE, errno,
545 _("read from %s subprocess failed"), progname);
546 goto fail;
547 }
548 }
549 else if (nread > 0)
550 done_read (buf, nread, private_data);
551 else /* nread == 0 */
552 {
553 if (done_writing)
554 break;
555 }
556 }
557 }
558 # if HAVE_SELECT
559 continue;
560 # endif
561 }
562 }
563
564 /* Restore SIGPIPE signal handler. */
565 if (sigaction (SIGPIPE, &orig_sigpipe_action, NULL) < 0)
566 abort ();
567 #endif
568
569 close (fd[0]);
570
571 /* Remove zombie process from process list. */
572 {
573 int exitstatus =
574 wait_subprocess (child, progname, false, null_stderr,
575 true, exit_on_error, NULL);
576 if (exitstatus != 0 && exit_on_error)
577 error (EXIT_FAILURE, 0, _("%s subprocess terminated with exit code %d"),
578 progname, exitstatus);
579 return exitstatus;
580 }
581
582 fail:
583 {
584 int saved_errno = errno;
585 close (fd[1]);
586 #if !((defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__)
587 if (sigaction (SIGPIPE, &orig_sigpipe_action, NULL) < 0)
588 abort ();
589 #endif
590 close (fd[0]);
591 wait_subprocess (child, progname, true, true, true, false, NULL);
592 errno = saved_errno;
593 return -1;
594 }
595 }
596