Subject: nonblocking I/O fcntl/ioctl ineffective (#410) Index: sys/kern_descrip.c 2.11BSD Description: fcntl(f, F_SETFL, O_NONBLOCK) and ioctl(f, FIONBIO, &nonzero) do have no effect but return no error. Repeat-By: f = open(device, O_RDONLY); fcntl(f, F_SETFL, O_NONBLOCK); cnt = read(f, buf, 1); If no data is available then -1 should be returned from read() and errno should be set to EWOULDBLOCK. Fix: I ran into this bug last night while testing the new 'accounting driver' (to replace most of kern_acct.c). The desired effect was to read /dev/acctlog and return an error if no data was available. When the program "hung" in read() it was a big surprise. The problem was an extra '~' in kern_descrip.c. Instead of _preserving_ important bits (such as FNONBLOCK, FASYNC, etc) the kernel was _clearing_ them. It is a very small change (one line in kern_descrip.c and a couple lines in /VERSION). To apply the patch cut where indicated and save to a file (/tmp/410). Then: patch -p0 < /tmp/410 cd /sys/YOURKERNEL make mv /unix /ounix mv /netnix /onetnix mv unix netnix / chmod 744 /unix /netnix reboot If you are not using a networking kernel simply leave out 'netnix'. As always this and previous updates to 2.11BSD are available via anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the directory /pub/2.11BSD. --------------------------cut here------------------------- *** /sys/sys/kern_descrip.c.old Sat Feb 1 16:42:29 1997 --- /sys/sys/kern_descrip.c Tue Mar 9 21:14:43 1999 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)kern_descrip.c 1.4 (2.11BSD GTE) 1997/1/30 */ #include "param.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)kern_descrip.c 1.5 (2.11BSD) 1999/3/9 */ #include "param.h" *************** *** 131,137 **** case F_SETFL: fp->f_flag &= ~FCNTLFLAGS; ! fp->f_flag |= (FFLAGS(uap->arg)) & ~FCNTLFLAGS; u.u_error = fset(fp, FNONBLOCK, fp->f_flag & FNONBLOCK); if (u.u_error) break; --- 131,137 ---- case F_SETFL: fp->f_flag &= ~FCNTLFLAGS; ! fp->f_flag |= (FFLAGS(uap->arg)) & FCNTLFLAGS; u.u_error = fset(fp, FNONBLOCK, fp->f_flag & FNONBLOCK); if (u.u_error) break; *** /VERSION.old Fri Feb 26 20:09:03 1999 --- /VERSION Wed Mar 10 19:40:59 1999 *************** *** 1,5 **** ! Current Patch Level: 409 ! Date: February 26, 1999 2.11 BSD ============ --- 1,5 ---- ! Current Patch Level: 410 ! Date: March 10, 1999 2.11 BSD ============