annotate lib/pipe-filter-gi.c @ 40231:9b3c79fdfe0b

strtod: fix clash with strtold Problem reported for RHEL 5 by Jesse Caldwell (Bug#34817). * lib/strtod.c (compute_minus_zero, minus_zero): Simplify by remving the macro / external variable, and having just a function. User changed. This avoids the need for an external variable that might clash.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 11 Mar 2019 16:40:29 -0700
parents b06060465f09
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
1 /* Filtering of data through a subprocess.
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 19595
diff changeset
2 Copyright (C) 2001-2003, 2008-2019 Free Software Foundation, Inc.
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
3 Written by Paolo Bonzini <bonzini@gnu.org>, 2009,
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
4 and Bruno Haible <bruno@clisp.org>, 2009.
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
5
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
6 This program is free software: you can redistribute it and/or modify
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
8 the Free Software Foundation; either version 3 of the License, or
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
9 (at your option) any later version.
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
10
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
11 This program is distributed in the hope that it will be useful,
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
14 GNU General Public License for more details.
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
15
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
18
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
19 #include <config.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
20
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
21 #include "pipe-filter.h"
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
22
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
23 #include <errno.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
24 #include <fcntl.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
25 #include <stdbool.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
26 #include <stdint.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
27 #include <stdlib.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
28 #include <unistd.h>
19595
beb2ad957aca Simplify code. Drop support for Borland C++ on Windows.
Bruno Haible <bruno@clisp.org>
parents: 19484
diff changeset
29 #if defined _WIN32 && ! defined __CYGWIN__
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
30 # include <windows.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
31 #else
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
32 # include <signal.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
33 # include <sys/select.h>
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
34 #endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
35
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
36 #include "error.h"
13924
5be0c314f2f8 Rename module 'pipe' to 'spawn-pipe'.
Bruno Haible <bruno@clisp.org>
parents: 12559
diff changeset
37 #include "spawn-pipe.h"
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
38 #include "wait-process.h"
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
39 #include "xalloc.h"
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
40 #include "gettext.h"
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
41
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
42 #define _(str) gettext (str)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
43
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
44 #include "pipe-filter-aux.h"
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
45
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
46 struct pipe_filter_gi
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
47 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
48 /* Arguments passed to pipe_filter_gi_create. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
49 const char *progname;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
50 bool null_stderr;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
51 bool exit_on_error;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
52 prepare_read_fn prepare_read;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
53 done_read_fn done_read;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
54 void *private_data;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
55
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
56 /* Management of the subprocess. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
57 pid_t child;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
58 int fd[2];
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
59 bool exited;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
60 int exitstatus;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
61
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
62 /* Status of the writer part. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
63 volatile bool writer_terminated;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
64 int writer_errno;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
65 /* Status of the reader part. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
66 volatile bool reader_terminated;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
67 volatile int reader_errno;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
68
19595
beb2ad957aca Simplify code. Drop support for Borland C++ on Windows.
Bruno Haible <bruno@clisp.org>
parents: 19484
diff changeset
69 #if defined _WIN32 && ! defined __CYGWIN__
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
70 CRITICAL_SECTION lock; /* protects the volatile fields */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
71 HANDLE reader_thread_handle;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
72 #else
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
73 struct sigaction orig_sigpipe_action;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
74 fd_set readfds; /* All bits except fd[0] are always cleared. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
75 fd_set writefds; /* All bits except fd[1] are always cleared. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
76 #endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
77 };
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
78
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
79
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
80 /* Platform dependent functions. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
81
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
82 /* Perform additional initializations.
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
83 Return 0 if successful, -1 upon failure. */
17101
99fa3b05f1c8 pipe-filter-gi, pipe-filter-ii: better use of 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 16242
diff changeset
84 static int filter_init (struct pipe_filter_gi *filter);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
85
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
86 /* Write count bytes starting at buf, while at the same time invoking the
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
87 read iterator (the functions prepare_read/done_read) when needed. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
88 static void filter_loop (struct pipe_filter_gi *filter,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
89 const char *wbuf, size_t count);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
90
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
91 /* Perform cleanup actions at the end.
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
92 finish_reading is true if there was no error, or false if some error
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
93 occurred already. */
17101
99fa3b05f1c8 pipe-filter-gi, pipe-filter-ii: better use of 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 16242
diff changeset
94 static void filter_cleanup (struct pipe_filter_gi *filter,
99fa3b05f1c8 pipe-filter-gi, pipe-filter-ii: better use of 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 16242
diff changeset
95 bool finish_reading);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
96
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
97
19595
beb2ad957aca Simplify code. Drop support for Borland C++ on Windows.
Bruno Haible <bruno@clisp.org>
parents: 19484
diff changeset
98 #if defined _WIN32 && ! defined __CYGWIN__
16242
59c686e5b2df Talk about "native Windows API", not "Woe32".
Bruno Haible <bruno@clisp.org>
parents: 16201
diff changeset
99 /* Native Windows API. */
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
100
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
101 static unsigned int WINAPI
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
102 reader_thread_func (void *thread_arg)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
103 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
104 struct pipe_filter_gi *filter = (struct pipe_filter_gi *) thread_arg;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
105
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
106 for (;;)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
107 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
108 size_t bufsize;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
109 void *buf = filter->prepare_read (&bufsize, filter->private_data);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
110 if (!(buf != NULL && bufsize > 0))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
111 /* prepare_read returned wrong values. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
112 abort ();
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
113 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
114 ssize_t nread =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
115 read (filter->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
116 EnterCriticalSection (&filter->lock);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
117 /* If the writer already encountered an error, terminate. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
118 if (filter->writer_terminated)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
119 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
120 if (nread < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
121 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
122 filter->reader_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
123 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
124 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
125 else if (nread > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
126 filter->done_read (buf, nread, filter->private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
127 else /* nread == 0 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
128 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
129 LeaveCriticalSection (&filter->lock);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
130 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
131 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
132
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
133 filter->reader_terminated = true;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
134 LeaveCriticalSection (&filter->lock);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
135 _endthreadex (0); /* calls ExitThread (0) */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
136 abort ();
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
137 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
138
17101
99fa3b05f1c8 pipe-filter-gi, pipe-filter-ii: better use of 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 16242
diff changeset
139 static int
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
140 filter_init (struct pipe_filter_gi *filter)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
141 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
142 InitializeCriticalSection (&filter->lock);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
143 EnterCriticalSection (&filter->lock);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
144
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
145 filter->reader_thread_handle =
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
146 (HANDLE) _beginthreadex (NULL, 100000, reader_thread_func, filter,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
147 0, NULL);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
148
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
149 if (filter->reader_thread_handle == NULL)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
150 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
151 if (filter->exit_on_error)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
152 error (EXIT_FAILURE, 0, _("creation of reading thread failed"));
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
153 return -1;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
154 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
155 else
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
156 return 0;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
157 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
158
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
159 static void
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
160 filter_loop (struct pipe_filter_gi *filter, const char *wbuf, size_t count)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
161 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
162 if (!filter->writer_terminated)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
163 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
164 for (;;)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
165 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
166 ssize_t nwritten;
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
167
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
168 /* Allow the reader thread to continue. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
169 LeaveCriticalSection (&filter->lock);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
170
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
171 nwritten =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
172 write (filter->fd[1], wbuf, count > SSIZE_MAX ? SSIZE_MAX : count);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
173
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
174 /* Get the lock back from the reader thread. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
175 EnterCriticalSection (&filter->lock);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
176
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
177 if (nwritten < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
178 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
179 /* 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
180 used. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
181 if (GetLastError () == ERROR_NO_DATA)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
182 errno = EPIPE;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
183 filter->writer_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
184 filter->writer_terminated = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
185 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
186 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
187 else if (nwritten > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
188 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
189 count -= nwritten;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
190 if (count == 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
191 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
192 wbuf += nwritten;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
193 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
194 else /* nwritten == 0 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
195 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
196 filter->writer_terminated = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
197 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
198 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
199 }
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
200 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
201 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
202
17101
99fa3b05f1c8 pipe-filter-gi, pipe-filter-ii: better use of 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 16242
diff changeset
203 static void
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
204 filter_cleanup (struct pipe_filter_gi *filter, bool finish_reading)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
205 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
206 if (finish_reading)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
207 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
208 LeaveCriticalSection (&filter->lock);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
209 WaitForSingleObject (filter->reader_thread_handle, INFINITE);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
210 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
211 else
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
212 TerminateThread (filter->reader_thread_handle, 1);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
213
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
214 CloseHandle (filter->reader_thread_handle);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
215 DeleteCriticalSection (&filter->lock);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
216 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
217
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
218 #else
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
219 /* Unix API. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
220
17101
99fa3b05f1c8 pipe-filter-gi, pipe-filter-ii: better use of 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 16242
diff changeset
221 static int
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
222 filter_init (struct pipe_filter_gi *filter)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
223 {
19595
beb2ad957aca Simplify code. Drop support for Borland C++ on Windows.
Bruno Haible <bruno@clisp.org>
parents: 19484
diff changeset
224 #if !(defined _WIN32 && ! defined __CYGWIN__)
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
225 /* When we write to the child process and it has just terminated,
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
226 we don't want to die from a SIGPIPE signal. So set the SIGPIPE
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
227 handler to SIG_IGN, and handle EPIPE error codes in write(). */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
228 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
229 struct sigaction sigpipe_action;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
230
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
231 sigpipe_action.sa_handler = SIG_IGN;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
232 sigpipe_action.sa_flags = 0;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
233 sigemptyset (&sigpipe_action.sa_mask);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
234 if (sigaction (SIGPIPE, &sigpipe_action, &filter->orig_sigpipe_action) < 0)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
235 abort ();
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
236 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
237 #endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
238
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
239 /* Enable non-blocking I/O. This permits the read() and write() calls
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
240 to return -1/EAGAIN without blocking; this is important for polling
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
241 if HAVE_SELECT is not defined. It also permits the read() and write()
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
242 calls to return after partial reads/writes; this is important if
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
243 HAVE_SELECT is defined, because select() only says that some data
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
244 can be read or written, not how many. Without non-blocking I/O,
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
245 Linux 2.2.17 and BSD systems prefer to block instead of returning
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
246 with partial results. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
247 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
248 int fcntl_flags;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
249
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
250 if ((fcntl_flags = fcntl (filter->fd[1], F_GETFL, 0)) < 0
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
251 || fcntl (filter->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
252 || (fcntl_flags = fcntl (filter->fd[0], F_GETFL, 0)) < 0
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
253 || fcntl (filter->fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1)
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
254 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
255 if (filter->exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
256 error (EXIT_FAILURE, errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
257 _("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
258 filter->progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
259 return -1;
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
260 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
261 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
262
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
263 FD_ZERO (&filter->readfds);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
264 FD_ZERO (&filter->writefds);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
265
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
266 return 0;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
267 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
268
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
269 static void
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
270 filter_loop (struct pipe_filter_gi *filter, const char *wbuf, size_t count)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
271 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
272 /* This function is used in two situations:
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
273 - in order to write some data to the subprocess
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
274 [done_writing = false],
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
275 - in order to read the remaining data after everything was written
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
276 [done_writing = true]. In this case buf is NULL and count is
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
277 ignored. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
278 bool done_writing = (wbuf == NULL);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
279
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
280 if (!done_writing)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
281 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
282 if (filter->writer_terminated || filter->reader_terminated)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
283 /* pipe_filter_gi_write was called when it should not be. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
284 abort ();
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
285 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
286 else
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
287 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
288 if (filter->reader_terminated)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
289 return;
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
290 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
291
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
292 /* Loop, trying to write the given buffer or reading, whichever is
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
293 possible. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
294 for (;;)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
295 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
296 /* Here filter->writer_terminated is false. When it becomes true, this
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
297 loop is terminated. */
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
298 /* Whereas filter->reader_terminated is initially false but may become
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
299 true during this loop. */
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
300 /* Here, if !done_writing, count > 0. When count becomes 0, this loop
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
301 is terminated. */
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
302 /* Here, if done_writing, filter->reader_terminated is false. When
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
303 filter->reader_terminated becomes true, this loop is terminated. */
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
304 # if HAVE_SELECT
17806
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
305 int n, retval;
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
306
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
307 /* See whether reading or writing is possible. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
308 n = 1;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
309 if (!filter->reader_terminated)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
310 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
311 FD_SET (filter->fd[0], &filter->readfds);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
312 n = filter->fd[0] + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
313 }
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
314 if (!done_writing)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
315 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
316 FD_SET (filter->fd[1], &filter->writefds);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
317 if (n <= filter->fd[1])
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
318 n = filter->fd[1] + 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
319 }
17806
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
320 /* Do EINTR handling here instead of in pipe-filter-aux.h,
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
321 because select() cannot be referred to from an inline
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
322 function on AIX 7.1. */
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
323 do
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
324 retval = select (n,
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
325 (!filter->reader_terminated ? &filter->readfds : NULL),
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
326 (!done_writing ? &filter->writefds : NULL),
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
327 NULL, NULL);
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
328 while (retval < 0 && errno == EINTR);
c76a0687b1a7 pipe-filter-gi, pipe-filter-ii: port to AIX
Daiki Ueno <ueno@gnu.org>
parents: 17576
diff changeset
329 n = retval;
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
330
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
331 if (n < 0)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
332 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
333 if (filter->exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
334 error (EXIT_FAILURE, errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
335 _("communication with %s subprocess failed"),
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
336 filter->progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
337 filter->writer_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
338 filter->writer_terminated = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
339 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
340 }
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
341
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
342 if (!done_writing && FD_ISSET (filter->fd[1], &filter->writefds))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
343 goto try_write;
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
344 if (!filter->reader_terminated
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
345 && FD_ISSET (filter->fd[0], &filter->readfds))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
346 goto try_read;
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
347 /* How could select() return if none of the two descriptors is ready? */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
348 abort ();
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
349 # endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
350
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
351 /* Attempt to write. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
352 # if HAVE_SELECT
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
353 try_write:
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
354 # endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
355 if (!done_writing)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
356 {
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
357 ssize_t nwritten =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
358 write (filter->fd[1], wbuf, count > SSIZE_MAX ? SSIZE_MAX : count);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
359 if (nwritten < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
360 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
361 if (!IS_EAGAIN (errno))
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 if (filter->exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
364 error (EXIT_FAILURE, errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
365 _("write to %s subprocess failed"),
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
366 filter->progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
367 filter->writer_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
368 filter->writer_terminated = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
369 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
370 }
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 else if (nwritten > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
373 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
374 count -= nwritten;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
375 if (count == 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
376 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
377 wbuf += nwritten;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
378 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
379 }
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
380 # if HAVE_SELECT
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
381 continue;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
382 # endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
383
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
384 /* Attempt to read. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
385 # if HAVE_SELECT
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
386 try_read:
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
387 # endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
388 if (!filter->reader_terminated)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
389 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
390 size_t bufsize;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
391 void *buf = filter->prepare_read (&bufsize, filter->private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
392 if (!(buf != NULL && bufsize > 0))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
393 /* prepare_read returned wrong values. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
394 abort ();
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
395 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
396 ssize_t nread =
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
397 read (filter->fd[0], buf,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
398 bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
399 if (nread < 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
400 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
401 if (!IS_EAGAIN (errno))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
402 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
403 if (filter->exit_on_error)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
404 error (EXIT_FAILURE, errno,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
405 _("read from %s subprocess failed"),
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
406 filter->progname);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
407 filter->reader_errno = errno;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
408 filter->reader_terminated = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
409 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
410 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
411 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
412 else if (nread > 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
413 filter->done_read (buf, nread, filter->private_data);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
414 else /* nread == 0 */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
415 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
416 filter->reader_terminated = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
417 if (done_writing)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
418 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
419 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
420 }
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
421 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
422 # if HAVE_SELECT
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
423 continue;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
424 # endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
425 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
426 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
427
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
428 static void
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
429 filter_cleanup (struct pipe_filter_gi *filter, bool finish_reading)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
430 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
431 if (finish_reading)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
432 /* A select loop, with done_writing = true. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
433 filter_loop (filter, NULL, 0);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
434
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
435 if (sigaction (SIGPIPE, &filter->orig_sigpipe_action, NULL) < 0)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
436 abort ();
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
437 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
438
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
439 #endif
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
440
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
441
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
442 /* Terminate the child process. Do nothing if it already exited. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
443 static void
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
444 filter_terminate (struct pipe_filter_gi *filter)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
445 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
446 if (!filter->exited)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
447 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
448 /* Tell the child there is nothing more the parent will send. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
449 close (filter->fd[1]);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
450 filter_cleanup (filter, !filter->reader_terminated);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
451 close (filter->fd[0]);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
452 filter->exitstatus =
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
453 wait_subprocess (filter->child, filter->progname, true,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
454 filter->null_stderr, true, filter->exit_on_error,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
455 NULL);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
456 if (filter->exitstatus != 0 && filter->exit_on_error)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
457 error (EXIT_FAILURE, 0,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
458 _("subprocess %s terminated with exit code %d"),
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
459 filter->progname, filter->exitstatus);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
460 filter->exited = true;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
461 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
462 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
463
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
464 /* After filter_terminate:
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
465 Return 0 upon success, or (only if exit_on_error is false):
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
466 - -1 with errno set upon failure,
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
467 - the positive exit code of the subprocess if that failed. */
17101
99fa3b05f1c8 pipe-filter-gi, pipe-filter-ii: better use of 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 16242
diff changeset
468 static int
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
469 filter_retcode (struct pipe_filter_gi *filter)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
470 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
471 if (filter->writer_errno != 0)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
472 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
473 errno = filter->writer_errno;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
474 return -1;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
475 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
476 else if (filter->reader_errno != 0)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
477 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
478 errno = filter->reader_errno;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
479 return -1;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
480 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
481 else
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
482 return filter->exitstatus;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
483 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
484
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
485 struct pipe_filter_gi *
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
486 pipe_filter_gi_create (const char *progname,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
487 const char *prog_path, const char **prog_argv,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
488 bool null_stderr, bool exit_on_error,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
489 prepare_read_fn prepare_read,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
490 done_read_fn done_read,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
491 void *private_data)
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
492 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
493 struct pipe_filter_gi *filter;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
494
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
495 filter =
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
496 (struct pipe_filter_gi *) xmalloc (sizeof (struct pipe_filter_gi));
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
497
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
498 /* Open a bidirectional pipe to a subprocess. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
499 filter->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
500 null_stderr, true, exit_on_error,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
501 filter->fd);
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
502 filter->progname = progname;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
503 filter->null_stderr = null_stderr;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
504 filter->exit_on_error = exit_on_error;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
505 filter->prepare_read = prepare_read;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
506 filter->done_read = done_read;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
507 filter->private_data = private_data;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
508 filter->exited = false;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
509 filter->exitstatus = 0;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
510 filter->writer_terminated = false;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
511 filter->writer_errno = 0;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
512 filter->reader_terminated = false;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
513 filter->reader_errno = 0;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
514
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
515 if (filter->child == -1)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
516 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
517 /* Child process could not be created.
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
518 Arrange for filter_retcode (filter) to be the current errno. */
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
519 filter->writer_errno = errno;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
520 filter->writer_terminated = true;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
521 filter->exited = true;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
522 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
523 else if (filter_init (filter) < 0)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
524 filter_terminate (filter);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
525
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
526 return filter;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
527 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
528
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
529 int
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
530 pipe_filter_gi_write (struct pipe_filter_gi *filter,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
531 const void *buf, size_t size)
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
532 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
533 if (buf == NULL)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
534 /* Invalid argument. */
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
535 abort ();
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
536
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
537 if (filter->exited)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
538 return filter_retcode (filter);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
539
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
540 if (size > 0)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
541 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
542 filter_loop (filter, buf, size);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
543 if (filter->writer_terminated || filter->reader_terminated)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
544 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
545 filter_terminate (filter);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
546 return filter_retcode (filter);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 11873
diff changeset
547 }
11760
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
548 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
549 return 0;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
550 }
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
551
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
552 int
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
553 pipe_filter_gi_close (struct pipe_filter_gi *filter)
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
554 {
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
555 int ret;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
556 int saved_errno;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
557
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
558 filter_terminate (filter);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
559 ret = filter_retcode (filter);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
560 saved_errno = errno;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
561 free (filter);
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
562 errno = saved_errno;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
563 return ret;
f63d201737ea New module 'pipe-filter-gi'.
Bruno Haible <bruno@clisp.org>
parents:
diff changeset
564 }