1 ?RCS: $Id: nblock_io.U,v 3.0.1.2 1997/02/28 16:17:14 ram Exp $
3 ?RCS: Copyright (c) 1991-1993, Raphael Manfredi
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.
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
17 ?RCS: Revision 3.0.1.1 1995/07/25 14:13:22 ram
18 ?RCS: patch56: created
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
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 $@ %<
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.
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).
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!
46 ?S: This variable conditionally defines EOF_NONBLOCK if EOF can be seen
47 ?S: when reading from a non-blocking I/O source.
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.
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.
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!
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!).
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
77 ?F:!try.out !try.ret !try.err !try !mtry
79 : check for non-blocking I/O stuff
81 true) echo "#include <sys/file.h>" > head.c;;
84 true) echo "#include <fcntl.h>" > head.c;;
85 *) echo "#include <sys/fcntl.h>" > head.c;;
90 echo "Figuring out the flag used by open() for non-blocking I/O..." >&4
106 printf("O_NONBLOCK\n");
110 printf("O_NDELAY\n");
113 ?X: Stevens "Advanced Programming in the UNIX Environment" page 364 mentions
114 ?X: the FNDELAY symbol, used in 4.3BSD (source: Paul Marquess).
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.";;
130 echo "(I can't compile the test program; pray O_NONBLOCK is right!)"
133 *) echo "Using $hint value $o_nonblock.";;
138 echo "Let's see what value errno gets from read() on a $o_nonblock file..." >&4
141 case "$d_fork:$d_pipe" in
146 #include <sys/types.h>
157 #define MY_O_NONBLOCK $o_nonblock
158 #ifndef errno /* XXX need better Configure test */
171 $signal_t blech(int x) { exit(3); }
173 $cat >> try.c <<'EOCP'
181 pipe(pd); /* Down: child -> parent */
182 pipe(pu); /* Up: parent -> child */
185 close(pd[1]); /* Parent reads from pd[0] */
186 close(pu[0]); /* Parent writes (blocking) to pu[1] */
188 if (-1 == fcntl(pd[0], F_SETFL, MY_O_NONBLOCK))
193 signal(SIGALRM, blech);
195 if ((ret = read(pd[0], buf, 1)) > 0) /* Nothing to read! */
197 sprintf(string, "%d\n", ret);
198 write(2, string, strlen(string));
201 if (errno == EAGAIN) {
207 if (errno == EWOULDBLOCK)
208 printf("EWOULDBLOCK\n");
211 write(pu[1], buf, 1); /* Unblocks child, tell it to close our pipe */
212 sleep(2); /* Give it time to close our pipe */
214 ret = read(pd[0], buf, 1); /* Should read EOF */
216 sprintf(string, "%d\n", ret);
217 write(4, string, strlen(string));
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! */
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
234 ./mtry >/dev/null 2>&1
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.";;
243 rd_nodata=`$cat try.ret`
244 echo "A read() system call with no data present returns $rd_nodata."
248 echo "(That's peculiar, fixing that to be -1.)"
254 echo "Forcing errno EAGAIN on read() with no data available."
258 echo "Your read() sets errno to $eagain when no data is available."
261 status=`$cat try.err`
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??";;
268 if test "$status" = "$rd_nodata"; then
269 echo "WARNING: you can't distinguish between EOF and no data!"
273 echo "I can't compile the test program--assuming errno EAGAIN will do."
277 *) echo "Can't figure out how to test this--assuming errno EAGAIN will do."
286 echo "Using $hint value $eagain."
287 echo "Your read() returns $rd_nodata when no data is present."
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.";;
292 ?X: Should not happen, but if it does, assume the worst!
293 echo "(Assuming you can't see EOF status from read anyway.)"