Subject: Re: kern/2428: socketpair() fails if fd0 open
To: None <david@mono.org>
From: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
List: netbsd-bugs
Date: 05/17/1996 16:33:52
> >Synopsis:       socketpair() fails if fd0 open

> #include <sys/types.h>  
> #include <sys/socket.h>
> main()
>     {
>     int sv[2];
> 
>     if( socketpair(AF_UNIX,SOCK_STREAM,0,sv) )
> 	perror("First call failed");
>     puts("Now close fd 0");
>     close(0);
>     if( socketpair(AF_UNIX,SOCK_STREAM,0,sv) )
> 	perror("Second call failed");
>     }

> >Fix:
> 	Fix unknown - I've kludged around it by dup()ing fd0 somewhere else,
> 	closing it, calling socketpair() then dup()ing ite back... uck...

The bug is not what you think it is; socketpair() is actually
succeeding.  The bug is, socketpair is returning one of the new file
descriptors as its return value, rather than the 0 it's documented to
return, when it succeeds.  Under NetBSD/sun3 pretty-much-current:

	[Daily-Planet] 77> cat z.c
	#include <stdio.h>
	#include <sys/types.h>
	#include <sys/socket.h>
	
	int main(void)
	{
	 int sv[2];
	 int rv;
	
	 rv = socketpair(AF_UNIX,SOCK_STREAM,0,sv);
	 printf("call 1 rv = %d sv = %d %d\n",rv,sv[0],sv[1]);
	 close(0);
	 rv = socketpair(AF_UNIX,SOCK_STREAM,0,sv);
	 printf("call 2 rv = %d sv = %d %d\n",rv,sv[0],sv[1]);
	 return(0);
	}
	[Daily-Planet] 78> z
	call 1 rv = 3 sv = 3 4
	call 2 rv = 0 sv = 0 5
	[Daily-Planet] 79> 

Alternatively, one can look upon this as a bug in the manpage, in that
it incorrectly documents the return value.  But in the kernel code
(kern/uipc_syscalls.c, in socketpair()), I find

	error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, rsv),
	    2 * sizeof (int));
	retval[0] = sv[0];		/* XXX ??? */
	retval[1] = sv[1];		/* XXX ??? */
	return (error);

which certainly indicates that _someone_ wasn't sure it was the right
thing to do, and it definitely disagrees with the manpage.  You can fix
this either by making socketpair() return 0 by changing
kern/uipc_syscalls.c, or by making the manpage document it as returning
-1 on failure and >=0 on success.  But the current state - socketpair()
returning something that according to the manpage cannot happen - is
definitely wrong.

					der Mouse

			    mouse@collatz.mcrcim.mcgill.edu