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