This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
71b9158dd522c0ae7f6231fad8537dcb8728283d
[metaconfig.git] / U / compline / nblock_io.U
1 ?RCS: $Id: nblock_io.U,v 3.0.1.2 1997/02/28 16:17:14 ram Exp $
2 ?RCS:
3 ?RCS: Copyright (c) 1991-1993, Raphael Manfredi
4 ?RCS:
5 ?RCS: You may redistribute only under the terms of the Artistic License,
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 License; a copy of which may be found at the root
9 ?RCS: of the source tree for dist 3.0.
10 ?RCS:
11 ?RCS: $Log: nblock_io.U,v $
12 ?RCS: Revision 3.0.1.2  1997/02/28  16:17:14  ram
13 ?RCS: patch61: simplify here document for shells that can't handle them well
14 ?RCS: patch61: force use of "startsh" at the head of the generated script
15 ?RCS: patch61: added new files to the ?F: metalint hint
16 ?RCS:
17 ?RCS: Revision 3.0.1.1  1995/07/25  14:13:22  ram
18 ?RCS: patch56: created
19 ?RCS:
20 ?X:
21 ?X: Simplify here document for shells that can't handle them well.
22 ?X: (Problem reported on FreeBSD; it's unclear if this helps.)  --AD
23 ?X:
24 ?MAKE:o_nonblock eagain rd_nodata d_eofnblk: cat rm_try Compile run \
25         d_open3 h_sysfile h_fcntl signal_t hint Oldconfig Setvar \
26         startsh i_unistd i_string i_fcntl i_stdlib d_fork d_pipe
27 ?MAKE:  -pick add $@ %<
28 ?S:o_nonblock:
29 ?S:     This variable bears the symbol value to be used during open() or fcntl()
30 ?S:     to turn on non-blocking I/O for a file descriptor. If you wish to switch
31 ?S:     between blocking and non-blocking, you may try ioctl(FIOSNBIO) instead,
32 ?S:     but that is only supported by some devices.
33 ?S:.
34 ?S:eagain:
35 ?S:     This variable bears the symbolic errno code set by read() when no
36 ?S:     data is present on the file and non-blocking I/O was enabled (otherwise,
37 ?S:     read() blocks naturally).
38 ?S:.
39 ?S:rd_nodata:
40 ?S:     This variable holds the return code from read() when no data is
41 ?S:     present. It should be -1, but some systems return 0 when O_NDELAY is
42 ?S:     used, which is a shame because you cannot make the difference between
43 ?S:     no data and an EOF.. Sigh!
44 ?S:.
45 ?S:d_eofnblk:
46 ?S:     This variable conditionally defines EOF_NONBLOCK if EOF can be seen
47 ?S:     when reading from a non-blocking I/O source.
48 ?S:.
49 ?C:VAL_O_NONBLOCK:
50 ?C:     This symbol is to be used during open() or fcntl(F_SETFL) to turn on
51 ?C:     non-blocking I/O for the file descriptor. Note that there is no way
52 ?C:     back, i.e. you cannot turn it blocking again this way. If you wish to
53 ?C:     alternatively switch between blocking and non-blocking, use the
54 ?C:     ioctl(FIOSNBIO) call instead, but that is not supported by all devices.
55 ?C:.
56 ?C:VAL_EAGAIN:
57 ?C:     This symbol holds the errno error code set by read() when no data was
58 ?C:     present on the non-blocking file descriptor.
59 ?C:.
60 ?C:RD_NODATA:
61 ?C:     This symbol holds the return code from read() when no data is present
62 ?C:     on the non-blocking file descriptor. Be careful! If EOF_NONBLOCK is
63 ?C:     not defined, then you can't distinguish between no data and EOF by
64 ?C:     issuing a read(). You'll have to find another way to tell for sure!
65 ?C:.
66 ?C:EOF_NONBLOCK:
67 ?C:     This symbol, if defined, indicates to the C program that a read() on
68 ?C:     a non-blocking file descriptor will return 0 on EOF, and not the value
69 ?C:     held in RD_NODATA (-1 usually, in that case!).
70 ?C:.
71 ?H:#define VAL_O_NONBLOCK $o_nonblock
72 ?H:#define VAL_EAGAIN $eagain
73 ?H:#define RD_NODATA $rd_nodata
74 ?H:#$d_eofnblk EOF_NONBLOCK
75 ?H:.
76 ?T:status
77 ?F:!try.out !try.ret !try.err !try !mtry
78 ?LINT:use d_open3
79 : check for non-blocking I/O stuff
80 case "$h_sysfile" in
81 true) echo "#include <sys/file.h>" > head.c;;
82 *)
83        case "$h_fcntl" in
84        true) echo "#include <fcntl.h>" > head.c;;
85        *) echo "#include <sys/fcntl.h>" > head.c;;
86        esac
87        ;;
88 esac
89 echo " "
90 echo "Figuring out the flag used by open() for non-blocking I/O..." >&4
91 case "$o_nonblock" in
92 '')
93         $cat head.c > try.c
94         $cat >>try.c <<EOCP
95 #include <stdio.h>
96 #$i_stdlib I_STDLIB
97 #ifdef I_STDLIB
98 #include <stdlib.h>
99 #endif
100 #$i_fcntl I_FCNTL
101 #ifdef I_FCNTL
102 #include <fcntl.h>
103 #endif
104 int main() {
105 #ifdef O_NONBLOCK
106         printf("O_NONBLOCK\n");
107         exit(0);
108 #endif
109 #ifdef O_NDELAY
110         printf("O_NDELAY\n");
111         exit(0);
112 #endif
113 ?X: Stevens "Advanced Programming in the UNIX Environment" page 364 mentions
114 ?X: the FNDELAY symbol, used in 4.3BSD (source: Paul Marquess).
115 #ifdef FNDELAY
116         printf("FNDELAY\n");
117         exit(0);
118 #endif
119         exit(0);
120 }
121 EOCP
122         set try
123         if eval $compile_ok; then
124                 o_nonblock=`$run ./try`
125                 case "$o_nonblock" in
126                 '') echo "I can't figure it out, assuming O_NONBLOCK will do.";;
127                 *) echo "Seems like we can use $o_nonblock.";;
128                 esac
129         else
130                 echo "(I can't compile the test program; pray O_NONBLOCK is right!)"
131         fi
132         ;;
133 *) echo "Using $hint value $o_nonblock.";;
134 esac
135 $rm_try
136
137 echo " "
138 echo "Let's see what value errno gets from read() on a $o_nonblock file..." >&4
139 case "$eagain" in
140 '')
141         case "$d_fork:$d_pipe" in
142         define:define)
143         $cat head.c > try.c
144         $cat >>try.c <<EOCP
145 #include <errno.h>
146 #include <sys/types.h>
147 #include <signal.h>
148 #include <stdio.h>
149 #$i_stdlib I_STDLIB
150 #ifdef I_STDLIB
151 #include <stdlib.h>
152 #endif
153 #$i_fcntl I_FCNTL
154 #ifdef I_FCNTL
155 #include <fcntl.h>
156 #endif
157 #define MY_O_NONBLOCK $o_nonblock
158 #ifndef errno  /* XXX need better Configure test */
159 extern int errno;
160 #endif
161 #$i_unistd I_UNISTD
162 #ifdef I_UNISTD
163 #include <unistd.h>
164 #endif
165 #$i_string I_STRING
166 #ifdef I_STRING
167 #include <string.h>
168 #else
169 #include <strings.h>
170 #endif
171 $signal_t blech(int x) { exit(3); }
172 EOCP
173         $cat >> try.c <<'EOCP'
174 int main()
175 {
176         int pd[2];
177         int pu[2];
178         char buf[1];
179         char string[100];
180
181         pipe(pd);       /* Down: child -> parent */
182         pipe(pu);       /* Up: parent -> child */
183         if (0 != fork()) {
184                 int ret;
185                 close(pd[1]);   /* Parent reads from pd[0] */
186                 close(pu[0]);   /* Parent writes (blocking) to pu[1] */
187 #ifdef F_SETFL
188                 if (-1 == fcntl(pd[0], F_SETFL, MY_O_NONBLOCK))
189                         exit(1);
190 #else
191                 exit(4);
192 #endif
193                 signal(SIGALRM, blech);
194                 alarm(5);
195                 if ((ret = read(pd[0], buf, 1)) > 0)    /* Nothing to read! */
196                         exit(2);
197                 sprintf(string, "%d\n", ret);
198                 write(2, string, strlen(string));
199                 alarm(0);
200 #ifdef EAGAIN
201                 if (errno == EAGAIN) {
202                         printf("EAGAIN\n");
203                         goto ok;
204                 }
205 #endif
206 #ifdef EWOULDBLOCK
207                 if (errno == EWOULDBLOCK)
208                         printf("EWOULDBLOCK\n");
209 #endif
210         ok:
211                 write(pu[1], buf, 1);   /* Unblocks child, tell it to close our pipe */
212                 sleep(2);                               /* Give it time to close our pipe */
213                 alarm(5);
214                 ret = read(pd[0], buf, 1);      /* Should read EOF */
215                 alarm(0);
216                 sprintf(string, "%d\n", ret);
217                 write(4, string, strlen(string));
218                 exit(0);
219         }
220
221         close(pd[0]);                   /* We write to pd[1] */
222         close(pu[1]);                   /* We read from pu[0] */
223         read(pu[0], buf, 1);    /* Wait for parent to signal us we may continue */
224         close(pd[1]);                   /* Pipe pd is now fully closed! */
225         exit(0);                                /* Bye bye, thank you for playing! */
226 }
227 EOCP
228         set try
229         if eval $compile_ok; then
230 ?X: Use script to avoid the possible 'alarm call' message
231                 echo "$startsh" >mtry
232                 echo "$run ./try >try.out 2>try.ret 4>try.err || exit 4" >>mtry
233                 chmod +x mtry
234                 ./mtry >/dev/null 2>&1
235                 case $? in
236                 0) eagain=`$cat try.out`;;
237                 1) echo "Could not perform non-blocking setting!";;
238                 2) echo "I did a successful read() for something that was not there!";;
239                 3) echo "Hmm... non-blocking I/O does not seem to be working!";;
240                 4) echo "Could not find F_SETFL!";;
241                 *) echo "Something terribly wrong happened during testing.";;
242                 esac
243                 rd_nodata=`$cat try.ret`
244                 echo "A read() system call with no data present returns $rd_nodata."
245                 case "$rd_nodata" in
246                 0|-1) ;;
247                 *)
248                         echo "(That's peculiar, fixing that to be -1.)"
249                         rd_nodata=-1
250                         ;;
251                 esac
252                 case "$eagain" in
253                 '')
254                         echo "Forcing errno EAGAIN on read() with no data available."
255                         eagain=EAGAIN
256                         ;;
257                 *)
258                         echo "Your read() sets errno to $eagain when no data is available."
259                         ;;
260                 esac
261                 status=`$cat try.err`
262                 case "$status" in
263                 0) echo "And it correctly returns 0 to signal EOF.";;
264                 -1) echo "But it also returns -1 to signal EOF, so be careful!";;
265                 *) echo "However, your read() returns '$status' on EOF??";;
266                 esac
267                 val="$define"
268                 if test "$status" = "$rd_nodata"; then
269                         echo "WARNING: you can't distinguish between EOF and no data!"
270                         val="$undef"
271                 fi
272         else
273                 echo "I can't compile the test program--assuming errno EAGAIN will do."
274                 eagain=EAGAIN
275         fi
276         ;;
277         *)      echo "Can't figure out how to test this--assuming errno EAGAIN will do."
278                 eagain=EAGAIN
279                 val="$define"
280                 ;;
281         esac
282         set d_eofnblk
283         eval $setvar
284         ;;
285 *)
286         echo "Using $hint value $eagain."
287         echo "Your read() returns $rd_nodata when no data is present."
288         case "$d_eofnblk" in
289         "$define") echo "And you can see EOF because read() returns 0.";;
290         "$undef") echo "But you can't see EOF status from read() returned value.";;
291         *)
292 ?X: Should not happen, but if it does, assume the worst!
293                 echo "(Assuming you can't see EOF status from read anyway.)"
294                 d_eofnblk=$undef
295                 ;;
296         esac
297         ;;
298 esac
299 $rm_try head.c mtry
300