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 */