Index: kern/kern_descrip.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_descrip.c,v
retrieving revision 1.217
diff -u -p -u -r1.217 kern_descrip.c
--- kern/kern_descrip.c	25 Sep 2011 13:40:37 -0000	1.217
+++ kern/kern_descrip.c	23 Jan 2012 23:05:53 -0000
@@ -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: kern/kern_event.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_event.c,v
retrieving revision 1.74
diff -u -p -u -r1.74 kern_event.c
--- kern/kern_event.c	17 Nov 2011 22:41:55 -0000	1.74
+++ kern/kern_event.c	23 Jan 2012 23:05:54 -0000
@@ -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: kern/sys_generic.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_generic.c,v
retrieving revision 1.127
diff -u -p -u -r1.127 sys_generic.c
--- kern/sys_generic.c	27 Jul 2011 14:35:34 -0000	1.127
+++ kern/sys_generic.c	23 Jan 2012 23:05:56 -0000
@@ -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: kern/sys_pipe.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_pipe.c,v
retrieving revision 1.134
diff -u -p -u -r1.134 sys_pipe.c
--- kern/sys_pipe.c	20 Oct 2011 18:18:21 -0000	1.134
+++ kern/sys_pipe.c	23 Jan 2012 23:05:57 -0000
@@ -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: kern/uipc_socket.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v
retrieving revision 1.206
diff -u -p -u -r1.206 uipc_socket.c
--- kern/uipc_socket.c	20 Dec 2011 23:56:28 -0000	1.206
+++ kern/uipc_socket.c	23 Jan 2012 23:05:58 -0000
@@ -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: kern/uipc_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.150
diff -u -p -u -r1.150 uipc_syscalls.c
--- kern/uipc_syscalls.c	21 Dec 2011 15:26:57 -0000	1.150
+++ kern/uipc_syscalls.c	23 Jan 2012 23:05:58 -0000
@@ -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: sys/fcntl.h
===================================================================
RCS file: /cvsroot/src/sys/sys/fcntl.h,v
retrieving revision 1.41
diff -u -p -u -r1.41 fcntl.h
--- sys/fcntl.h	9 Aug 2011 04:19:17 -0000	1.41
+++ sys/fcntl.h	23 Jan 2012 23:05:59 -0000
@@ -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 */
@@ -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 */
Index: sys/filedesc.h
===================================================================
RCS file: /cvsroot/src/sys/sys/filedesc.h,v
retrieving revision 1.61
diff -u -p -u -r1.61 filedesc.h
--- sys/filedesc.h	26 Jun 2011 16:43:12 -0000	1.61
+++ sys/filedesc.h	23 Jan 2012 23:05:59 -0000
@@ -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: sys/socket.h
===================================================================
RCS file: /cvsroot/src/sys/sys/socket.h,v
retrieving revision 1.104
diff -u -p -u -r1.104 socket.h
--- sys/socket.h	20 Jan 2012 14:08:07 -0000	1.104
+++ sys/socket.h	23 Jan 2012 23:05:59 -0000
@@ -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 */