Module Name:    src
Committed By:   christos
Date:           Wed Jan 25 00:28:36 UTC 2012

Modified Files:
        src/lib/libc/sys: dup.2 fcntl.2 getsockopt.2 kqueue.2 open.2 pipe.2
            socket.2
        src/sys/kern: kern_descrip.c kern_event.c sys_descrip.c sys_generic.c
            sys_pipe.c uipc_socket.c uipc_syscalls.c
        src/sys/sys: fcntl.h filedesc.h socket.h

Log Message:
As discussed in tech-kern, provide the means to prevent delivery of SIGPIPE
on EPIPE for all file descriptor types:

- provide O_NOSIGPIPE for open,kqueue1,pipe2,dup3,fcntl(F_{G,S}ETFL) [NetBSD]
- provide SOCK_NOSIGPIPE for socket,socketpair [NetBSD]
- provide SO_NOSIGPIPE for {g,s}seckopt [NetBSD/FreeBSD/MacOSX]
- provide F_{G,S}ETNOSIGPIPE for fcntl [MacOSX]


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/lib/libc/sys/dup.2 src/lib/libc/sys/pipe.2
cvs rdiff -u -r1.39 -r1.40 src/lib/libc/sys/fcntl.2
cvs rdiff -u -r1.34 -r1.35 src/lib/libc/sys/getsockopt.2
cvs rdiff -u -r1.31 -r1.32 src/lib/libc/sys/kqueue.2
cvs rdiff -u -r1.50 -r1.51 src/lib/libc/sys/open.2
cvs rdiff -u -r1.37 -r1.38 src/lib/libc/sys/socket.2
cvs rdiff -u -r1.217 -r1.218 src/sys/kern/kern_descrip.c
cvs rdiff -u -r1.74 -r1.75 src/sys/kern/kern_event.c
cvs rdiff -u -r1.23 -r1.24 src/sys/kern/sys_descrip.c
cvs rdiff -u -r1.127 -r1.128 src/sys/kern/sys_generic.c
cvs rdiff -u -r1.134 -r1.135 src/sys/kern/sys_pipe.c
cvs rdiff -u -r1.206 -r1.207 src/sys/kern/uipc_socket.c
cvs rdiff -u -r1.150 -r1.151 src/sys/kern/uipc_syscalls.c
cvs rdiff -u -r1.41 -r1.42 src/sys/sys/fcntl.h
cvs rdiff -u -r1.61 -r1.62 src/sys/sys/filedesc.h
cvs rdiff -u -r1.104 -r1.105 src/sys/sys/socket.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/sys/dup.2
diff -u src/lib/libc/sys/dup.2:1.27 src/lib/libc/sys/dup.2:1.28
--- src/lib/libc/sys/dup.2:1.27	Fri Jul 22 07:02:39 2011
+++ src/lib/libc/sys/dup.2	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: dup.2,v 1.27 2011/07/22 11:02:39 wiz Exp $
+.\"	$NetBSD: dup.2,v 1.28 2012/01/25 00:28:35 christos Exp $
 .\"
 .\" Copyright (c) 1980, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)dup.2	8.1 (Berkeley) 6/4/93
 .\"
-.Dd July 16, 2011
+.Dd January 23, 2012
 .Dt DUP 2
 .Os
 .Sh NAME
@@ -118,6 +118,11 @@ Set the
 property.
 .It Dv O_NONBLOCK
 Sets non-blocking I/O.
+.It Dv O_NOSIGPIPE
+Return
+.Er EPIPE
+instead of raising
+.Dv SIGPIPE .
 .El
 .Sh RETURN VALUES
 The value \-1 is returned if an error occurs in either call.
Index: src/lib/libc/sys/pipe.2
diff -u src/lib/libc/sys/pipe.2:1.27 src/lib/libc/sys/pipe.2:1.28
--- src/lib/libc/sys/pipe.2:1.27	Fri Jul 22 07:02:39 2011
+++ src/lib/libc/sys/pipe.2	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: pipe.2,v 1.27 2011/07/22 11:02:39 wiz Exp $
+.\"	$NetBSD: pipe.2,v 1.28 2012/01/25 00:28:35 christos Exp $
 .\"
 .\" Copyright (c) 1980, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)pipe.2	8.1 (Berkeley) 6/4/93
 .\"
-.Dd July 15, 2011
+.Dd January 23, 2012
 .Dt PIPE 2
 .Os
 .Sh NAME
@@ -97,6 +97,11 @@ Set the
 property.
 .It Dv O_NONBLOCK
 Sets non-blocking I/O.
+.It Dv O_NOSIGPIPE
+Return
+.Er EPIPE
+instead of raising
+.Dv SIGPIPE .
 .El
 .Sh RETURN VALUES
 On successful creation of the pipe, zero is returned.

Index: src/lib/libc/sys/fcntl.2
diff -u src/lib/libc/sys/fcntl.2:1.39 src/lib/libc/sys/fcntl.2:1.40
--- src/lib/libc/sys/fcntl.2:1.39	Mon Jun 27 04:21:08 2011
+++ src/lib/libc/sys/fcntl.2	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: fcntl.2,v 1.39 2011/06/27 08:21:08 wiz Exp $
+.\"	$NetBSD: fcntl.2,v 1.40 2012/01/25 00:28:35 christos Exp $
 .\"
 .\" Copyright (c) 1983, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)fcntl.2	8.2 (Berkeley) 1/12/94
 .\"
-.Dd June 25, 2011
+.Dd January 23, 2012
 .Dt FCNTL 2
 .Os
 .Sh NAME
@@ -146,35 +146,32 @@ Close all file descriptors greater than 
 .Ar fd .
 .It Dv F_MAXFD
 Return the maximum file descriptor number currently open by the process.
+.It Dv F_GETNOSIGPIPE
+Return if the
+.Dv O_NOSIGPIPE
+flag is set in the file descriptor.
+.It Dv F_SETNOSIGPIPE
+Set or clear the
+.Dv O_NOSIGPIPE
+in the file descriptor.
 .El
 .Pp
-The flags for the
+The set of valid flags for the
 .Dv F_GETFL
 and
 .Dv F_SETFL
 flags are as follows:
-.Bl -tag -width O_NONBLOCKX
-.It Dv O_NONBLOCK
-Non-blocking I/O; if no data is available to a
-.Xr read 2
-call, or if a
-.Xr write 2
-operation would block,
-the read or write call returns \-1 with the error
-.Er EAGAIN .
-.It Dv O_APPEND
-Force each write to append at the end of file;
-corresponds to the
-.Dv O_APPEND
-flag of
+.Dv O_APPEND ,
+.Dv O_ASYNC ,
+.Dv O_FSYNC ,
+.Dv O_NONBLOCK ,
+.Dv O_DSYNC ,
+.Dv O_RSYNC ,
+.Dv O_ALT_IO ,
+.Dv O_DIRECT ,
+.Dv O_NOSIGPIPE .
+These flags are described in
 .Xr open 2 .
-.It Dv O_ASYNC
-Enable the
-.Dv SIGIO
-signal to be sent to the process group
-when I/O is possible, e.g.,
-upon availability of data to be read.
-.El
 .Pp
 Several commands are available for doing advisory file locking;
 they all operate on the following structure:

Index: src/lib/libc/sys/getsockopt.2
diff -u src/lib/libc/sys/getsockopt.2:1.34 src/lib/libc/sys/getsockopt.2:1.35
--- src/lib/libc/sys/getsockopt.2:1.34	Mon Jun 29 04:38:07 2009
+++ src/lib/libc/sys/getsockopt.2	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: getsockopt.2,v 1.34 2009/06/29 08:38:07 wiz Exp $
+.\"	$NetBSD: getsockopt.2,v 1.35 2012/01/25 00:28:35 christos Exp $
 .\"
 .\" Copyright (c) 1983, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)getsockopt.2	8.4 (Berkeley) 5/2/95
 .\"
-.Dd June 28, 2009
+.Dd January 23, 2012
 .Dt GETSOCKOPT 2
 .Os
 .Sh NAME
@@ -167,6 +167,10 @@ and set with
 .It Dv SO_RCVTIMEO Ta "set timeout value for input"
 .It Dv SO_TIMESTAMP Ta "enables reception of a timestamp with datagrams"
 .It Dv SO_ACCEPTFILTER Ta "set accept filter on listening socket"
+.It Dv SO_NOSIGPIPE Ta
+controls generation of
+.Dv SIGPIPE
+for the socket
 .It Dv SO_TYPE Ta "get the type of the socket (get only)"
 .It Dv SO_ERROR Ta "get and clear error on the socket (get only)"
 .El

Index: src/lib/libc/sys/kqueue.2
diff -u src/lib/libc/sys/kqueue.2:1.31 src/lib/libc/sys/kqueue.2:1.32
--- src/lib/libc/sys/kqueue.2:1.31	Sun Jun 26 12:42:41 2011
+++ src/lib/libc/sys/kqueue.2	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: kqueue.2,v 1.31 2011/06/26 16:42:41 christos Exp $
+.\"	$NetBSD: kqueue.2,v 1.32 2012/01/25 00:28:35 christos Exp $
 .\"
 .\" Copyright (c) 2000 Jonathan Lemon
 .\" All rights reserved.
@@ -32,7 +32,7 @@
 .\"
 .\" $FreeBSD: src/lib/libc/sys/kqueue.2,v 1.22 2001/06/27 19:55:57 dd Exp $
 .\"
-.Dd June 24, 2011
+.Dd January 23, 2012
 .Dt KQUEUE 2
 .Os
 .Sh NAME
@@ -92,6 +92,11 @@ on the returned file descriptor:
 Set the close on exec property.
 .It Dv O_NONBLOCK
 Sets non-blocking I/O.
+.It Dv O_NOSIGPIPE
+Return
+.Er EPIPE
+instead of raising
+.Dv SIGPIPE .
 .El
 The queue is not inherited by a child created with
 .Xr fork 2 .

Index: src/lib/libc/sys/open.2
diff -u src/lib/libc/sys/open.2:1.50 src/lib/libc/sys/open.2:1.51
--- src/lib/libc/sys/open.2:1.50	Wed Apr 20 15:57:58 2011
+++ src/lib/libc/sys/open.2	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: open.2,v 1.50 2011/04/20 19:57:58 christos Exp $
+.\"	$NetBSD: open.2,v 1.51 2012/01/25 00:28:35 christos Exp $
 .\"
 .\" Copyright (c) 1980, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)open.2	8.2 (Berkeley) 11/16/93
 .\"
-.Dd April 20, 2011
+.Dd January 23, 2012
 .Dt OPEN 2
 .Os
 .Sh NAME
@@ -99,6 +99,11 @@ Set the
 on
 .Xr exec 3
 flag.
+.It Dv O_NOSIGPIPE
+Return
+.Er EPIPE
+instead of raising
+.Dv SIGPIPE .
 .It Dv O_DSYNC
 If set, write operations will be performed according to synchronized
 I/O data integrity completion:
@@ -153,6 +158,12 @@ using an interface that supports scatter
 element of the request must meet the above alignment constraints.
 .It Dv O_DIRECTORY
 Fail if the file is not a directory.
+.It Dv O_ASYNC
+Enable the
+.Dv SIGIO
+signal to be sent to the process group
+when I/O is possible, e.g.,
+upon availability of data to be read.
 .El
 .Pp
 Opening a file with

Index: src/lib/libc/sys/socket.2
diff -u src/lib/libc/sys/socket.2:1.37 src/lib/libc/sys/socket.2:1.38
--- src/lib/libc/sys/socket.2:1.37	Sun Jun 26 12:42:41 2011
+++ src/lib/libc/sys/socket.2	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-.\"	$NetBSD: socket.2,v 1.37 2011/06/26 16:42:41 christos Exp $
+.\"	$NetBSD: socket.2,v 1.38 2012/01/25 00:28:35 christos Exp $
 .\"
 .\" Copyright (c) 1983, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -86,6 +86,11 @@ The following flags are valid:
 Set the close on exec property.
 .It Dv SOCK_NONBLOCK
 Sets non-blocking I/O.
+.It Dv SOCK_NOSIGPIPE
+Return
+.Er EPIPE
+instead of raising
+.Dv SIGPIPE .
 .El
 .Pp
 A

Index: src/sys/kern/kern_descrip.c
diff -u src/sys/kern/kern_descrip.c:1.217 src/sys/kern/kern_descrip.c:1.218
--- src/sys/kern/kern_descrip.c:1.217	Sun Sep 25 09:40:37 2011
+++ src/sys/kern/kern_descrip.c	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_descrip.c,v 1.217 2011/09/25 13:40:37 chs Exp $	*/
+/*	$NetBSD: kern_descrip.c,v 1.218 2012/01/25 00:28:35 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.217 2011/09/25 13:40:37 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.218 2012/01/25 00:28:35 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -500,22 +500,27 @@ fd_getvnode(unsigned fd, file_t **fpp)
  * to a socket.
  */
 int
-fd_getsock(unsigned fd, struct socket **sop)
+fd_getsock1(unsigned fd, struct socket **sop, file_t **fp)
 {
-	file_t *fp;
-
-	fp = fd_getfile(fd);
-	if (__predict_false(fp == NULL)) {
+	*fp = fd_getfile(fd);
+	if (__predict_false(*fp == NULL)) {
 		return EBADF;
 	}
-	if (__predict_false(fp->f_type != DTYPE_SOCKET)) {
+	if (__predict_false((*fp)->f_type != DTYPE_SOCKET)) {
 		fd_putfile(fd);
 		return ENOTSOCK;
 	}
-	*sop = fp->f_data;
+	*sop = (*fp)->f_data;
 	return 0;
 }
 
+int
+fd_getsock(unsigned fd, struct socket **sop)
+{
+	file_t *fp;
+	return fd_getsock1(fd, sop, &fp);
+}
+
 /*
  * Look up the file structure corresponding to a file descriptor
  * and return it with a reference held on the file, not the

Index: src/sys/kern/kern_event.c
diff -u src/sys/kern/kern_event.c:1.74 src/sys/kern/kern_event.c:1.75
--- src/sys/kern/kern_event.c:1.74	Thu Nov 17 17:41:55 2011
+++ src/sys/kern/kern_event.c	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_event.c,v 1.74 2011/11/17 22:41:55 rmind Exp $	*/
+/*	$NetBSD: kern_event.c,v 1.75 2012/01/25 00:28:35 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.74 2011/11/17 22:41:55 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.75 2012/01/25 00:28:35 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -725,7 +725,7 @@ kqueue1(struct lwp *l, int flags, regist
 
 	if ((error = fd_allocfile(&fp, &fd)) != 0)
 		return error;
-	fp->f_flag = FREAD | FWRITE | (flags & FNONBLOCK);
+	fp->f_flag = FREAD | FWRITE | (flags & (FNONBLOCK|FNOSIGPIPE));
 	fp->f_type = DTYPE_KQUEUE;
 	fp->f_ops = &kqueueops;
 	kq = kmem_zalloc(sizeof(*kq), KM_SLEEP);

Index: src/sys/kern/sys_descrip.c
diff -u src/sys/kern/sys_descrip.c:1.23 src/sys/kern/sys_descrip.c:1.24
--- src/sys/kern/sys_descrip.c:1.23	Mon Oct 31 17:31:29 2011
+++ src/sys/kern/sys_descrip.c	Tue Jan 24 19:28:36 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_descrip.c,v 1.23 2011/10/31 21:31:29 christos Exp $	*/
+/*	$NetBSD: sys_descrip.c,v 1.24 2012/01/25 00:28:36 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_descrip.c,v 1.23 2011/10/31 21:31:29 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_descrip.c,v 1.24 2012/01/25 00:28:36 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -403,6 +403,18 @@ sys_fcntl(struct lwp *l, const struct sy
 		    ((long)SCARG(uap, arg) & FD_CLOEXEC) != 0);
 		break;
 
+	case F_GETNOSIGPIPE:
+		*retval = (fp->f_flag & FNOSIGPIPE) != 0;
+		break;
+
+	case F_SETNOSIGPIPE:
+		if (SCARG(uap, arg))
+			fp->f_flag |= FNOSIGPIPE;
+		else
+			fp->f_flag &= ~FNOSIGPIPE;
+		*retval = 0;
+		break;
+
 	case F_GETFL:
 		*retval = OFLAGS(fp->f_flag);
 		break;

Index: src/sys/kern/sys_generic.c
diff -u src/sys/kern/sys_generic.c:1.127 src/sys/kern/sys_generic.c:1.128
--- src/sys/kern/sys_generic.c:1.127	Wed Jul 27 10:35:34 2011
+++ src/sys/kern/sys_generic.c	Tue Jan 24 19:28:36 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_generic.c,v 1.127 2011/07/27 14:35:34 uebayasi Exp $	*/
+/*	$NetBSD: sys_generic.c,v 1.128 2012/01/25 00:28:36 christos Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.127 2011/07/27 14:35:34 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.128 2012/01/25 00:28:36 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -357,7 +357,7 @@ dofilewrite(int fd, struct file *fp, con
 		if (auio.uio_resid != cnt && (error == ERESTART ||
 		    error == EINTR || error == EWOULDBLOCK))
 			error = 0;
-		if (error == EPIPE) {
+		if (error == EPIPE && !(fp->f_flag & FNOSIGPIPE)) {
 			mutex_enter(proc_lock);
 			psignal(curproc, SIGPIPE);
 			mutex_exit(proc_lock);
@@ -484,7 +484,7 @@ do_filewritev(int fd, const struct iovec
 		if (auio.uio_resid != cnt && (error == ERESTART ||
 		    error == EINTR || error == EWOULDBLOCK))
 			error = 0;
-		if (error == EPIPE) {
+		if (error == EPIPE && !(fp->f_flag & FNOSIGPIPE)) {
 			mutex_enter(proc_lock);
 			psignal(curproc, SIGPIPE);
 			mutex_exit(proc_lock);

Index: src/sys/kern/sys_pipe.c
diff -u src/sys/kern/sys_pipe.c:1.134 src/sys/kern/sys_pipe.c:1.135
--- src/sys/kern/sys_pipe.c:1.134	Thu Oct 20 14:18:21 2011
+++ src/sys/kern/sys_pipe.c	Tue Jan 24 19:28:36 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_pipe.c,v 1.134 2011/10/20 18:18:21 njoly Exp $	*/
+/*	$NetBSD: sys_pipe.c,v 1.135 2012/01/25 00:28:36 christos Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.134 2011/10/20 18:18:21 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.135 2012/01/25 00:28:36 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -251,7 +251,7 @@ pipe1(struct lwp *l, register_t *retval,
 	int fd, error;
 	proc_t *p;
 
-	if (flags & ~(O_CLOEXEC|O_NONBLOCK))
+	if (flags & ~(O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE))
 		return EINVAL;
 	p = curproc;
 	rpipe = wpipe = NULL;

Index: src/sys/kern/uipc_socket.c
diff -u src/sys/kern/uipc_socket.c:1.206 src/sys/kern/uipc_socket.c:1.207
--- src/sys/kern/uipc_socket.c:1.206	Tue Dec 20 18:56:28 2011
+++ src/sys/kern/uipc_socket.c	Tue Jan 24 19:28:36 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_socket.c,v 1.206 2011/12/20 23:56:28 christos Exp $	*/
+/*	$NetBSD: uipc_socket.c,v 1.207 2012/01/25 00:28:36 christos Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.206 2011/12/20 23:56:28 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.207 2012/01/25 00:28:36 christos Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_sock_counters.h"
@@ -589,7 +589,8 @@ fsocreate(int domain, struct socket **so
 	if ((error = fd_allocfile(&fp, &fd)) != 0)
 		return error;
 	fd_set_exclose(l, fd, (flags & SOCK_CLOEXEC) != 0);
-	fp->f_flag = FREAD|FWRITE|((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0);
+	fp->f_flag = FREAD|FWRITE|((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
+	    ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
 	fp->f_type = DTYPE_SOCKET;
 	fp->f_ops = &socketops;
 	error = socreate(domain, &so, type, protocol, l, NULL);
@@ -1719,6 +1720,7 @@ sosetopt1(struct socket *so, const struc
 	case SO_REUSEPORT:
 	case SO_OOBINLINE:
 	case SO_TIMESTAMP:
+	case SO_NOSIGPIPE:
 #ifdef SO_OTIMESTAMP
 	case SO_OTIMESTAMP:
 #endif
@@ -1919,6 +1921,7 @@ sogetopt1(struct socket *so, struct sock
 	case SO_BROADCAST:
 	case SO_OOBINLINE:
 	case SO_TIMESTAMP:
+	case SO_NOSIGPIPE:
 #ifdef SO_OTIMESTAMP
 	case SO_OTIMESTAMP:
 #endif

Index: src/sys/kern/uipc_syscalls.c
diff -u src/sys/kern/uipc_syscalls.c:1.150 src/sys/kern/uipc_syscalls.c:1.151
--- src/sys/kern/uipc_syscalls.c:1.150	Wed Dec 21 10:26:57 2011
+++ src/sys/kern/uipc_syscalls.c	Tue Jan 24 19:28:36 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_syscalls.c,v 1.150 2011/12/21 15:26:57 christos Exp $	*/
+/*	$NetBSD: uipc_syscalls.c,v 1.151 2012/01/25 00:28:36 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.150 2011/12/21 15:26:57 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.151 2012/01/25 00:28:36 christos Exp $");
 
 #include "opt_pipe.h"
 
@@ -229,7 +229,8 @@ do_sys_accept(struct lwp *l, int sock, s
 		panic("accept");
 	fp2->f_type = DTYPE_SOCKET;
 	fp2->f_flag = (fp->f_flag & ~clrflags) |
-	    ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0); 
+	    ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
+	    ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
 	fp2->f_ops = &socketops;
 	fp2->f_data = so2;
 	error = soaccept(so2, nam);
@@ -407,7 +408,6 @@ makesocket(struct lwp *l, file_t **fp, i
 {
 	int error;
 	struct socket *so;
-	int fnonblock = (flags & SOCK_NONBLOCK) ? FNONBLOCK : 0; 
 
 	if ((error = socreate(domain, &so, type, proto, l, soo)) != 0)
 		return error;
@@ -417,7 +417,9 @@ makesocket(struct lwp *l, file_t **fp, i
 		return error;
 	}
 	fd_set_exclose(l, *fd, (flags & SOCK_CLOEXEC) != 0);
-	(*fp)->f_flag = FREAD|FWRITE|fnonblock;
+	(*fp)->f_flag = FREAD|FWRITE|
+	    ((flags & SOCK_NONBLOCK) ? FNONBLOCK : 0)|
+	    ((flags & SOCK_NOSIGPIPE) ? FNOSIGPIPE : 0);
 	(*fp)->f_type = DTYPE_SOCKET;
 	(*fp)->f_ops = &socketops;
 	(*fp)->f_data = so;
@@ -533,6 +535,7 @@ do_sys_sendmsg(struct lwp *l, int s, str
 	struct iovec	aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL;
 	struct mbuf	*to, *control;
 	struct socket	*so;
+	file_t		*fp;
 	struct uio	auio;
 	size_t		len, iovsz;
 	int		i, error;
@@ -606,7 +609,7 @@ do_sys_sendmsg(struct lwp *l, int s, str
 		memcpy(ktriov, auio.uio_iov, iovsz);
 	}
 
-	if ((error = fd_getsock(s, &so)) != 0)
+	if ((error = fd_getsock1(s, &so, &fp)) != 0)
 		goto bad;
 
 	if (mp->msg_name)
@@ -625,7 +628,8 @@ do_sys_sendmsg(struct lwp *l, int s, str
 		if (auio.uio_resid != len && (error == ERESTART ||
 		    error == EINTR || error == EWOULDBLOCK))
 			error = 0;
-		if (error == EPIPE && (flags & MSG_NOSIGNAL) == 0) {
+		if (error == EPIPE && (fp->f_flag & FNOSIGPIPE) == 0 &&
+		    (flags & MSG_NOSIGNAL) == 0) {
 			mutex_enter(proc_lock);
 			psignal(l->l_proc, SIGPIPE);
 			mutex_exit(proc_lock);
@@ -946,6 +950,7 @@ sys_setsockopt(struct lwp *l, const stru
 	} */
 	struct sockopt	sopt;
 	struct socket	*so;
+	file_t		*fp;
 	int		error;
 	unsigned int	len;
 
@@ -956,7 +961,7 @@ sys_setsockopt(struct lwp *l, const stru
 	if (len > MCLBYTES)
 		return (EINVAL);
 
-	if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
+	if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
 		return (error);
 
 	sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), len);
@@ -968,6 +973,10 @@ sys_setsockopt(struct lwp *l, const stru
 	}
 
 	error = sosetopt(so, &sopt);
+	if (so->so_options & SO_NOSIGPIPE)
+		fp->f_flag |= FNOSIGPIPE;
+	else
+		fp->f_flag &= ~FNOSIGPIPE;
 
  out:
 	sockopt_destroy(&sopt);
@@ -988,6 +997,7 @@ sys_getsockopt(struct lwp *l, const stru
 	} */
 	struct sockopt	sopt;
 	struct socket	*so;
+	file_t		*fp;
 	unsigned int	valsize, len;
 	int		error;
 
@@ -998,11 +1008,15 @@ sys_getsockopt(struct lwp *l, const stru
 	} else
 		valsize = 0;
 
-	if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
+	if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
 		return (error);
 
 	sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), 0);
 
+	if (fp->f_flag & FNOSIGPIPE)
+		so->so_options |= SO_NOSIGPIPE;
+	else
+		so->so_options &= ~SO_NOSIGPIPE;
 	error = sogetopt(so, &sopt);
 	if (error)
 		goto out;
@@ -1034,7 +1048,7 @@ pipe1(struct lwp *l, register_t *retval,
 	int		fd, error;
 	proc_t		*p;
 
-	if (flags & ~(O_CLOEXEC|O_NONBLOCK))
+	if (flags & ~(O_CLOEXEC|O_NONBLOCK|O_NOSIGPIPE))
 		return EINVAL;
 	p = curproc;
 	if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0)

Index: src/sys/sys/fcntl.h
diff -u src/sys/sys/fcntl.h:1.41 src/sys/sys/fcntl.h:1.42
--- src/sys/sys/fcntl.h:1.41	Tue Aug  9 00:19:17 2011
+++ src/sys/sys/fcntl.h	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: fcntl.h,v 1.41 2011/08/09 04:19:17 manu Exp $	*/
+/*	$NetBSD: fcntl.h,v 1.42 2012/01/25 00:28:35 christos Exp $	*/
 
 /*-
  * Copyright (c) 1983, 1990, 1993
@@ -117,6 +117,9 @@
 #if defined(_INCOMPLETE_XOPEN_C063) || defined(_KERNEL)
 #define	O_SEARCH	0x00800000	/* skip search permission checks */
 #endif
+#if defined(_NETBSD_SOURCE)
+#define	O_NOSIGPIPE	0x01000000	/* don't deliver sigpipe */
+#endif
 
 #ifdef _KERNEL
 /* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */
@@ -127,7 +130,7 @@
 #define	O_MASK		(O_ACCMODE|O_NONBLOCK|O_APPEND|O_SHLOCK|O_EXLOCK|\
 			 O_ASYNC|O_SYNC|O_CREAT|O_TRUNC|O_EXCL|O_DSYNC|\
 			 O_RSYNC|O_NOCTTY|O_ALT_IO|O_NOFOLLOW|O_DIRECT|\
-			 O_DIRECTORY|O_CLOEXEC)
+			 O_DIRECTORY|O_CLOEXEC|O_NOSIGPIPE)
 
 #define	FMARK		0x00001000	/* mark during gc() */
 #define	FDEFER		0x00002000	/* defer for next gc pass */
@@ -137,7 +140,7 @@
 #define	FKIOCTL		0x80000000	/* kernel originated ioctl */
 /* bits settable by fcntl(F_SETFL, ...) */
 #define	FCNTLFLAGS	(FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FDSYNC|FRSYNC|FALTIO|\
-			 FDIRECT)
+			 FDIRECT|FNOSIGPIPE)
 /* bits to save after open(2) */
 #define	FMASK		(FREAD|FWRITE|FCNTLFLAGS)
 #endif /* _KERNEL */
@@ -155,6 +158,7 @@
 #define	O_NDELAY	O_NONBLOCK	/* compat */
 #endif
 #if defined(_KERNEL)
+#define	FNOSIGPIPE	O_NOSIGPIPE	/* kernel */
 #define	FNONBLOCK	O_NONBLOCK	/* kernel */
 #define	FFSYNC		O_SYNC		/* kernel */
 #define	FDSYNC		O_DSYNC		/* kernel */
@@ -185,6 +189,8 @@
 #define	F_CLOSEM	10		/* close all fds >= to the one given */
 #define	F_MAXFD		11		/* return the max open fd */
 #define	F_DUPFD_CLOEXEC	12		/* close on exec duplicated fd */
+#define	F_GETNOSIGPIPE	13		/* get SIGPIPE disposition */
+#define	F_SETNOSIGPIPE	14		/* set SIGPIPE disposition */
 #endif
 
 /* file descriptor flags (F_GETFD, F_SETFD) */

Index: src/sys/sys/filedesc.h
diff -u src/sys/sys/filedesc.h:1.61 src/sys/sys/filedesc.h:1.62
--- src/sys/sys/filedesc.h:1.61	Sun Jun 26 12:43:12 2011
+++ src/sys/sys/filedesc.h	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: filedesc.h,v 1.61 2011/06/26 16:43:12 christos Exp $	*/
+/*	$NetBSD: filedesc.h,v 1.62 2012/01/25 00:28:35 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -200,6 +200,7 @@ file_t	*fd_getfile2(proc_t *, unsigned);
 void	fd_putfile(unsigned);
 int	fd_getvnode(unsigned, file_t **);
 int	fd_getsock(unsigned, struct socket **);
+int	fd_getsock1(unsigned, struct socket **, file_t **);
 void	fd_putvnode(unsigned);
 void	fd_putsock(unsigned);
 int	fd_close(unsigned);

Index: src/sys/sys/socket.h
diff -u src/sys/sys/socket.h:1.104 src/sys/sys/socket.h:1.105
--- src/sys/sys/socket.h:1.104	Fri Jan 20 09:08:07 2012
+++ src/sys/sys/socket.h	Tue Jan 24 19:28:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: socket.h,v 1.104 2012/01/20 14:08:07 joerg Exp $	*/
+/*	$NetBSD: socket.h,v 1.105 2012/01/25 00:28:35 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -110,6 +110,7 @@ typedef	_BSD_SSIZE_T_	ssize_t;
 
 #define	SOCK_CLOEXEC	0x10000000	/* set close on exec on socket */
 #define	SOCK_NONBLOCK	0x20000000	/* set non blocking i/o socket */
+#define	SOCK_NOSIGPIPE	0x40000000	/* don't send sigpipe */
 #define	SOCK_FLAGS_MASK	0xf0000000	/* flags mask */
 
 /*
@@ -126,6 +127,7 @@ typedef	_BSD_SSIZE_T_	ssize_t;
 #define	SO_OOBINLINE	0x0100		/* leave received OOB data in line */
 #define	SO_REUSEPORT	0x0200		/* allow local address & port reuse */
 /* 	SO_OTIMESTAMP	0x0400		*/
+#define	SO_NOSIGPIPE	0x0800		/* no SIGPIPE from EPIPE */
 #define	SO_ACCEPTFILTER	0x1000		/* there is an accept filter */
 #define	SO_TIMESTAMP	0x2000		/* timestamp received dgram traffic */
 

Reply via email to