This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
More specific comment based on findings in RT#7586
[metaconfig.git] / U / perl / fflushall.U
CommitLineData
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 \
4bc6cd65 12 Oldconfig Myread Setvar echo \
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
47echo " "
48$cat >&4 <<EOM
49Checking how to flush all pending stdio output...
50EOM
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
53case "$osname" in
54sunos) $echo '#define PERL_FFLUSH_ALL_FOPEN_MAX 32' > try.c ;;
55esac
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
71int 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}
121EOCP
122: first we have to find out how _not_ to flush
0f00356b 123$to try.c
959f3c4c
JH
124if $test "X$fflushNULL" = X -o "X$fflushall" = X; then
125 output=''
126 set try -DTRY_FPUTC
127 if eval $compile; then
f5a7caaa
JH
128 $run ./try 2>/dev/null
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
f5a7caaa
JH
139 $run ./try 2>/dev/null
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
148fi
65a32477 149: check for fflush NULL behavior
959f3c4c
JH
150case "$fflushNULL" in
151'') set try -DTRY_FFLUSH_NULL $output
152 if eval $compile; then
0f00356b 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.)
162EOM
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
169Your fflush(NULL) works okay for output streams.
170Let's see if it clobbers input pipes...
959f3c4c 171EOM
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>
177int
178main(int argc, char **argv)
179{
180 char buf[1024];
181 int i;
182 char *bp = buf;
183 while (1) {
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;
5ef94ee9
JH
193 bp = buf;
194 }
195}
196EOCP
197 fflushNULL="$define"
198 set tryp
199 if eval $compile; then
200 $rm -f tryp.out
0f00356b 201 $cat tryp.c | $run ./tryp 2>/dev/null > tryp.out
5ef94ee9
JH
202 if cmp tryp.c tryp.out >/dev/null 2>&1; then
203 $cat >&4 <<EOM
204fflush(NULL) seems to behave okay with input streams.
205EOM
206 fflushNULL="$define"
207 else
208 $cat >&4 <<EOM
209Ouch, fflush(NULL) clobbers input pipes! We will not use it.
210EOM
211 fflushNULL="$undef"
212 fi
213 fi
1b13c38f 214 $rm -f core tryp.c tryp.core core.tryp.*
959f3c4c
JH
215 ;;
216 '') $cat >&4 <<EOM
217Your fflush(NULL) isn't working (contrary to ANSI C).
218EOM
219 fflushNULL="$undef"
220 ;;
221 *) $cat >&4 <<EOM
222Cannot figure out whether your fflush(NULL) works or not.
223I'm assuming it doesn't (contrary to ANSI C).
224EOM
225 fflushNULL="$undef"
226 ;;
227 esac
228 ;;
229$define|true|[yY]*)
230 fflushNULL="$define"
231 ;;
232*)
233 fflushNULL="$undef"
234 ;;
235esac
1b13c38f
JH
236: check explicit looping only if NULL did not work, and if the pipe
237: bug does not show up on an explicit flush too
959f3c4c
JH
238case "$fflushNULL" in
239"$undef")
1b13c38f
JH
240 $cat >tryp.c <<EOCP
241#include <stdio.h>
242int
243main(int argc, char **argv)
244{
245 char buf[1024];
246 int i;
247 char *bp = buf;
248 while (1) {
249 while ((i = getc(stdin)) != -1
250 && (*bp++ = i) != '\n'
251 && bp < &buf[1024])
252 /* DO NOTHING */ ;
253 *bp = '\0';
254 fprintf(stdout, "%s", buf);
255 fflush(stdin);
256 if (i == -1)
257 return 0;
258 bp = buf;
259 }
260}
261EOCP
262 set tryp
263 if eval $compile; then
264 $rm -f tryp.out
0f00356b 265 $cat tryp.c | $run ./tryp 2>/dev/null > tryp.out
1b13c38f
JH
266 if cmp tryp.c tryp.out >/dev/null 2>&1; then
267 $cat >&4 <<EOM
268Good, at least fflush(stdin) seems to behave okay when stdin is a pipe.
959f3c4c 269EOM
1b13c38f 270 : now check for fflushall behaviour
959f3c4c 271 case "$fflushall" in
1b13c38f
JH
272 '') set try -DTRY_FFLUSH_ALL $output
273 if eval $compile; then
274 $cat >&4 <<EOM
275(Now testing the other method--but note that this also may fail.)
276EOM
0f00356b 277 $run ./try 2>/dev/null
f5a7caaa
JH
278 code=$?
279 $from try.out
280 if $test -s try.out -a "X$code" = X42; then
1b13c38f
JH
281 fflushall="`$cat try.out`"
282 fi
283 fi
2cb64bf6 284 $rm_try
1b13c38f
JH
285 case "$fflushall" in
286 x) $cat >&4 <<EOM
959f3c4c
JH
287Whew. Flushing explicitly all the stdio streams works.
288EOM
1b13c38f
JH
289 fflushall="$define"
290 ;;
291 '') $cat >&4 <<EOM
959f3c4c
JH
292Sigh. Flushing explicitly all the stdio streams doesn't work.
293EOM
1b13c38f
JH
294 fflushall="$undef"
295 ;;
296 *) $cat >&4 <<EOM
959f3c4c
JH
297Cannot figure out whether flushing stdio streams explicitly works or not.
298I'm assuming it doesn't.
299EOM
1b13c38f
JH
300 fflushall="$undef"
301 ;;
302 esac
303 ;;
304 "$define"|true|[yY]*)
305 fflushall="$define"
306 ;;
307 *)
959f3c4c
JH
308 fflushall="$undef"
309 ;;
310 esac
1b13c38f
JH
311 else
312 $cat >&4 <<EOM
313All is futile. Even fflush(stdin) clobbers input pipes!
314EOM
959f3c4c 315 fflushall="$undef"
1b13c38f
JH
316 fi
317 else
318 fflushall="$undef"
319 fi
320 $rm -f core tryp.c tryp.core core.tryp.*
959f3c4c 321 ;;
1b13c38f 322*) fflushall="$undef"
959f3c4c
JH
323 ;;
324esac
1b13c38f 325
959f3c4c
JH
326case "$fflushNULL$fflushall" in
327undefundef)
328 $cat <<EOM
1b13c38f
JH
329OK, I give up. I cannot figure out how to flush pending stdio output.
330We won't be flushing handles at all before fork/exec/popen.
959f3c4c
JH
331EOM
332 ;;
333esac
41322e17 334$rm_try tryp
959f3c4c 335