Commit | Line | Data |
---|---|---|
959f3c4c JH |
1 | ?RCS: $Id$ |
2 | ?RCS: | |
3 | ?RCS: Copyright (c) 1999, Jarkko Hietaniemi | |
0065f4af | 4 | ?RCS: |
65a32477 | 5 | ?RCS: You may redistribute only under the terms of the Artistic License, |
959f3c4c JH |
6 | ?RCS: as specified in the README file that comes with the distribution. |
7 | ?RCS: You may reuse parts of this distribution only within the terms of | |
65a32477 | 8 | ?RCS: that same Artistic License; a copy of which may be found at the root |
959f3c4c JH |
9 | ?RCS: of the source tree for dist 3.0. |
10 | ?RCS: | |
2cb64bf6 | 11 | ?MAKE:fflushNULL fflushall: Compile cat rm rm_try test osname run to from \ |
9c11722e | 12 | Oldconfig Myread Setvar echo targethost \ |
1273bb5e | 13 | d_sysconf i_unistd d_stdio_stream_array stdio_stream_array i_stdlib |
959f3c4c JH |
14 | ?MAKE: -pick add $@ %< |
15 | ?S:fflushNULL: | |
1c13d0ab MBT |
16 | ?S: This symbol, if defined, tells that fflush(NULL) correctly |
17 | ?S: flushes all pending stdio output without side effects. In | |
18 | ?S: particular, on some platforms calling fflush(NULL) *still* | |
19 | ?S: corrupts STDIN if it is a pipe. | |
959f3c4c JH |
20 | ?S:. |
21 | ?S:fflushall: | |
22 | ?S: This symbol, if defined, tells that to flush | |
23 | ?S: all pending stdio output one must loop through all | |
24 | ?S: the stdio file handles stored in an array and fflush them. | |
25 | ?S: Note that if fflushNULL is defined, fflushall will not | |
26 | ?S: even be probed for and will be left undefined. | |
27 | ?S:. | |
28 | ?C:FFLUSH_NULL: | |
1c13d0ab MBT |
29 | ?C: This symbol, if defined, tells that fflush(NULL) correctly |
30 | ?C: flushes all pending stdio output without side effects. In | |
31 | ?C: particular, on some platforms calling fflush(NULL) *still* | |
32 | ?C: corrupts STDIN if it is a pipe. | |
959f3c4c JH |
33 | ?C:. |
34 | ?C:FFLUSH_ALL: | |
35 | ?C: This symbol, if defined, tells that to flush | |
36 | ?C: all pending stdio output one must loop through all | |
37 | ?C: the stdio file handles stored in an array and fflush them. | |
38 | ?C: Note that if fflushNULL is defined, fflushall will not | |
39 | ?C: even be probed for and will be left undefined. | |
40 | ?C:. | |
41 | ?H:#$fflushNULL FFLUSH_NULL /**/ | |
42 | ?H:#$fflushall FFLUSH_ALL /**/ | |
43 | ?H:. | |
44 | ?T:output code | |
41322e17 | 45 | ?F:!try.out !try !tryp |
0065f4af | 46 | : Check how to flush |
959f3c4c JH |
47 | echo " " |
48 | $cat >&4 <<EOM | |
49 | Checking how to flush all pending stdio output... | |
50 | EOM | |
51 | # I only know how to find the first 32 possibly open files on SunOS. | |
52 | # See also hints/sunos_4_1.sh and util.c --AD | |
53 | case "$osname" in | |
54 | sunos) $echo '#define PERL_FFLUSH_ALL_FOPEN_MAX 32' > try.c ;; | |
55 | esac | |
56 | $cat >>try.c <<EOCP | |
57 | #include <stdio.h> | |
1273bb5e JH |
58 | #$i_stdlib I_STDLIB |
59 | #ifdef I_STDLIB | |
60 | #include <stdlib.h> | |
61 | #endif | |
959f3c4c JH |
62 | #$i_unistd I_UNISTD |
63 | #ifdef I_UNISTD | |
64 | # include <unistd.h> | |
65 | #endif | |
66 | #$d_sysconf HAS_SYSCONF | |
67 | #$d_stdio_stream_array HAS_STDIO_STREAM_ARRAY | |
68 | #ifdef HAS_STDIO_STREAM_ARRAY | |
69 | # define STDIO_STREAM_ARRAY $stdio_stream_array | |
70 | #endif | |
71 | int main() { | |
0f00356b JH |
72 | FILE* p; |
73 | unlink("try.out"); | |
74 | p = fopen("try.out", "w"); | |
959f3c4c JH |
75 | #ifdef TRY_FPUTC |
76 | fputc('x', p); | |
77 | #else | |
78 | # ifdef TRY_FPRINTF | |
79 | fprintf(p, "x"); | |
80 | # endif | |
81 | #endif | |
82 | #ifdef TRY_FFLUSH_NULL | |
83 | fflush(NULL); | |
84 | #endif | |
85 | #ifdef TRY_FFLUSH_ALL | |
86 | { | |
87 | long open_max = -1; | |
88 | # ifdef PERL_FFLUSH_ALL_FOPEN_MAX | |
89 | open_max = PERL_FFLUSH_ALL_FOPEN_MAX; | |
90 | # else | |
91 | # if defined(HAS_SYSCONF) && defined(_SC_OPEN_MAX) | |
92 | open_max = sysconf(_SC_OPEN_MAX); | |
93 | # else | |
94 | # ifdef FOPEN_MAX | |
95 | open_max = FOPEN_MAX; | |
96 | # else | |
97 | # ifdef OPEN_MAX | |
98 | open_max = OPEN_MAX; | |
99 | # else | |
100 | # ifdef _NFILE | |
101 | open_max = _NFILE; | |
102 | # endif | |
103 | # endif | |
104 | # endif | |
105 | # endif | |
2cb64bf6 | 106 | # endif |
959f3c4c JH |
107 | # ifdef HAS_STDIO_STREAM_ARRAY |
108 | if (open_max > 0) { | |
109 | long i; | |
110 | for (i = 0; i < open_max; i++) | |
111 | if (STDIO_STREAM_ARRAY[i]._file >= 0 && | |
112 | STDIO_STREAM_ARRAY[i]._file < open_max && | |
113 | STDIO_STREAM_ARRAY[i]._flag) | |
114 | fflush(&STDIO_STREAM_ARRAY[i]); | |
2cb64bf6 | 115 | } |
959f3c4c JH |
116 | } |
117 | # endif | |
118 | #endif | |
119 | _exit(42); | |
120 | } | |
121 | EOCP | |
122 | : first we have to find out how _not_ to flush | |
0f00356b | 123 | $to try.c |
959f3c4c JH |
124 | if $test "X$fflushNULL" = X -o "X$fflushall" = X; then |
125 | output='' | |
126 | set try -DTRY_FPUTC | |
127 | if eval $compile; then | |
9c11722e | 128 | $run ./try 2>/dev/null |
f5a7caaa | 129 | code="$?" |
0f00356b | 130 | $from try.out |
f5a7caaa | 131 | if $test ! -s try.out -a "X$code" = X42; then |
959f3c4c JH |
132 | output=-DTRY_FPUTC |
133 | fi | |
134 | fi | |
135 | case "$output" in | |
136 | '') | |
137 | set try -DTRY_FPRINTF | |
959f3c4c | 138 | if eval $compile; then |
9c11722e | 139 | $run ./try 2>/dev/null |
f5a7caaa | 140 | code="$?" |
0f00356b | 141 | $from try.out |
f5a7caaa | 142 | if $test ! -s try.out -a "X$code" = X42; then |
959f3c4c JH |
143 | output=-DTRY_FPRINTF |
144 | fi | |
145 | fi | |
146 | ;; | |
147 | esac | |
148 | fi | |
65a32477 | 149 | : check for fflush NULL behavior |
959f3c4c JH |
150 | case "$fflushNULL" in |
151 | '') set try -DTRY_FFLUSH_NULL $output | |
152 | if eval $compile; then | |
9c11722e | 153 | $run ./try 2>/dev/null |
959f3c4c | 154 | code="$?" |
0f00356b | 155 | $from try.out |
959f3c4c JH |
156 | if $test -s try.out -a "X$code" = X42; then |
157 | fflushNULL="`$cat try.out`" | |
158 | else | |
159 | if $test "X$code" != X42; then | |
160 | $cat >&4 <<EOM | |
161 | (If this test failed, don't worry, we'll try another method shortly.) | |
162 | EOM | |
163 | fi | |
164 | fi | |
165 | fi | |
a45723d1 | 166 | $rm -f core try.core core.try.* |
959f3c4c JH |
167 | case "$fflushNULL" in |
168 | x) $cat >&4 <<EOM | |
5ef94ee9 JH |
169 | Your fflush(NULL) works okay for output streams. |
170 | Let's see if it clobbers input pipes... | |
959f3c4c | 171 | EOM |
5ef94ee9 JH |
172 | # As of mid-March 2000 all versions of Solaris appear to have a stdio |
173 | # bug that improperly flushes the input end of pipes. So we avoid the | |
174 | # autoflush on fork/system/exec support for now. :-( | |
175 | $cat >tryp.c <<EOCP | |
176 | #include <stdio.h> | |
177 | int | |
178 | main(int argc, char **argv) | |
179 | { | |
180 | char buf[1024]; | |
181 | int i; | |
182 | char *bp = buf; | |
183 | while (1) { | |
9c11722e MB |
184 | while ((i = getc(stdin)) != -1 |
185 | && (*bp++ = i) != '\n' | |
186 | && bp < &buf[1024]) | |
187 | /* DO NOTHING */ ; | |
188 | *bp = '\0'; | |
189 | fprintf(stdout, "%s", buf); | |
190 | fflush(NULL); | |
191 | if (i == -1) | |
1b13c38f | 192 | return 0; |
9c11722e | 193 | bp = buf; |
5ef94ee9 JH |
194 | } |
195 | } | |
196 | EOCP | |
9c11722e MB |
197 | fflushNULL="$define" |
198 | set tryp | |
199 | if eval $compile; then | |
200 | $rm -f tryp.out | |
201 | # Copy the .c file to the remote host ($to is an ssh-alike if targethost is set) | |
202 | if $test "X$targethost" != X; then | |
203 | $to tryp.c | |
76d1bd01 | 204 | $to tryp |
5f6c99a5 | 205 | $run "cat tryp.c | ./tryp " 2>/dev/null > tryp.out |
9c11722e | 206 | else |
5f6c99a5 | 207 | $cat tryp.c | $run ./tryp 2>/dev/null > tryp.out |
9c11722e MB |
208 | fi |
209 | if cmp tryp.c tryp.out >/dev/null 2>&1; then | |
210 | $cat >&4 <<EOM | |
5ef94ee9 JH |
211 | fflush(NULL) seems to behave okay with input streams. |
212 | EOM | |
213 | fflushNULL="$define" | |
9c11722e | 214 | else |
5ef94ee9 JH |
215 | $cat >&4 <<EOM |
216 | Ouch, fflush(NULL) clobbers input pipes! We will not use it. | |
217 | EOM | |
9c11722e MB |
218 | fflushNULL="$undef" |
219 | fi | |
220 | fi | |
221 | $rm -f core tryp.c tryp.core core.tryp.* | |
959f3c4c JH |
222 | ;; |
223 | '') $cat >&4 <<EOM | |
224 | Your fflush(NULL) isn't working (contrary to ANSI C). | |
225 | EOM | |
226 | fflushNULL="$undef" | |
227 | ;; | |
228 | *) $cat >&4 <<EOM | |
229 | Cannot figure out whether your fflush(NULL) works or not. | |
230 | I'm assuming it doesn't (contrary to ANSI C). | |
231 | EOM | |
232 | fflushNULL="$undef" | |
233 | ;; | |
234 | esac | |
235 | ;; | |
236 | $define|true|[yY]*) | |
237 | fflushNULL="$define" | |
238 | ;; | |
239 | *) | |
240 | fflushNULL="$undef" | |
241 | ;; | |
242 | esac | |
1b13c38f JH |
243 | : check explicit looping only if NULL did not work, and if the pipe |
244 | : bug does not show up on an explicit flush too | |
959f3c4c JH |
245 | case "$fflushNULL" in |
246 | "$undef") | |
1b13c38f JH |
247 | $cat >tryp.c <<EOCP |
248 | #include <stdio.h> | |
249 | int | |
250 | main(int argc, char **argv) | |
251 | { | |
252 | char buf[1024]; | |
253 | int i; | |
254 | char *bp = buf; | |
255 | while (1) { | |
256 | while ((i = getc(stdin)) != -1 | |
257 | && (*bp++ = i) != '\n' | |
258 | && bp < &buf[1024]) | |
259 | /* DO NOTHING */ ; | |
260 | *bp = '\0'; | |
261 | fprintf(stdout, "%s", buf); | |
262 | fflush(stdin); | |
263 | if (i == -1) | |
264 | return 0; | |
265 | bp = buf; | |
266 | } | |
267 | } | |
268 | EOCP | |
269 | set tryp | |
270 | if eval $compile; then | |
271 | $rm -f tryp.out | |
9c11722e MB |
272 | if $test "X$targethost" != X; then |
273 | $to tryp.c | |
76d1bd01 | 274 | $to tryp |
5f6c99a5 | 275 | $run "cat tryp.c | ./tryp " 2>/dev/null > tryp.out |
9c11722e | 276 | else |
5f6c99a5 | 277 | $cat tryp.c | $run ./tryp 2>/dev/null > tryp.out |
9c11722e | 278 | fi |
1b13c38f JH |
279 | if cmp tryp.c tryp.out >/dev/null 2>&1; then |
280 | $cat >&4 <<EOM | |
281 | Good, at least fflush(stdin) seems to behave okay when stdin is a pipe. | |
959f3c4c | 282 | EOM |
1b13c38f | 283 | : now check for fflushall behaviour |
959f3c4c | 284 | case "$fflushall" in |
1b13c38f JH |
285 | '') set try -DTRY_FFLUSH_ALL $output |
286 | if eval $compile; then | |
287 | $cat >&4 <<EOM | |
288 | (Now testing the other method--but note that this also may fail.) | |
289 | EOM | |
0f00356b | 290 | $run ./try 2>/dev/null |
f5a7caaa JH |
291 | code=$? |
292 | $from try.out | |
293 | if $test -s try.out -a "X$code" = X42; then | |
1b13c38f JH |
294 | fflushall="`$cat try.out`" |
295 | fi | |
296 | fi | |
2cb64bf6 | 297 | $rm_try |
1b13c38f JH |
298 | case "$fflushall" in |
299 | x) $cat >&4 <<EOM | |
959f3c4c JH |
300 | Whew. Flushing explicitly all the stdio streams works. |
301 | EOM | |
1b13c38f JH |
302 | fflushall="$define" |
303 | ;; | |
304 | '') $cat >&4 <<EOM | |
959f3c4c JH |
305 | Sigh. Flushing explicitly all the stdio streams doesn't work. |
306 | EOM | |
1b13c38f JH |
307 | fflushall="$undef" |
308 | ;; | |
309 | *) $cat >&4 <<EOM | |
959f3c4c JH |
310 | Cannot figure out whether flushing stdio streams explicitly works or not. |
311 | I'm assuming it doesn't. | |
312 | EOM | |
1b13c38f JH |
313 | fflushall="$undef" |
314 | ;; | |
315 | esac | |
316 | ;; | |
317 | "$define"|true|[yY]*) | |
318 | fflushall="$define" | |
319 | ;; | |
320 | *) | |
959f3c4c JH |
321 | fflushall="$undef" |
322 | ;; | |
323 | esac | |
1b13c38f JH |
324 | else |
325 | $cat >&4 <<EOM | |
326 | All is futile. Even fflush(stdin) clobbers input pipes! | |
327 | EOM | |
959f3c4c | 328 | fflushall="$undef" |
1b13c38f JH |
329 | fi |
330 | else | |
331 | fflushall="$undef" | |
332 | fi | |
333 | $rm -f core tryp.c tryp.core core.tryp.* | |
959f3c4c | 334 | ;; |
1b13c38f | 335 | *) fflushall="$undef" |
959f3c4c JH |
336 | ;; |
337 | esac | |
1b13c38f | 338 | |
959f3c4c JH |
339 | case "$fflushNULL$fflushall" in |
340 | undefundef) | |
341 | $cat <<EOM | |
1b13c38f JH |
342 | OK, I give up. I cannot figure out how to flush pending stdio output. |
343 | We won't be flushing handles at all before fork/exec/popen. | |
959f3c4c JH |
344 | EOM |
345 | ;; | |
346 | esac | |
41322e17 | 347 | $rm_try tryp |
959f3c4c | 348 |