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
  ============
