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