tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Adding an option to avoid SIGPIPE for all file descriptors
Hello,
In most programs the delivery of SIGPIPE (typically when one side
of a socket or pipe closes and the other side tries to write) is
annoying to handle, and the only solution to avoid it is to have
the main program do signal(SIGPIPE, SIG_IGN), so the the system
calls set errno = EPIPE instead. It would be nice if the default
was the other way around (you needed to ask for SIGPIPE to get it,
the same way you ask for SIGIO), but it is too late to do this now.
If you are a library writer who is dealing with pipes or sockets
you are at the mercy of the main program as to how this is going
to be handled. If you are a threaded program, the situation is even
more complicated. Setting the signal handler is an all or nothing
solution and other OS's have come up with many solutions for this.
Namely setsockopt SO_NOSIGPIPE (FreeBSD/MacOSX),
fcntl(F_SETNOSIGPIPE/F_GETNOSIGPIPE) (MacOSX). This has led to
even more complexity (what happens if the socket is closed on
SO_NOSIGPIPE? SO_NP_EXTENSIONS? ugh!). What I propose to do, and
the patch here implements it, is to handle the EPIPE disposition
at the file flags (regardless if the file descriptor is a socket or
not) and send SIGPIPE only if the flag O_NOSIGPIPE is clear. This
is actually simpler and less intrusive to implement (because it
does not special-case sockets, and the signal delivery is still
centralized for all file descriptors), plus it handles all current
and future file descriptor types or drivers that can return EPIPE.
Comments?
christos
Index: lib/libc/sys/dup.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/dup.2,v
retrieving revision 1.27
diff -u -p -u -r1.27 dup.2
--- lib/libc/sys/dup.2 22 Jul 2011 11:02:39 -0000 1.27
+++ lib/libc/sys/dup.2 24 Jan 2012 01:48:28 -0000
@@ -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: lib/libc/sys/fcntl.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/fcntl.2,v
retrieving revision 1.39
diff -u -p -u -r1.39 fcntl.2
--- lib/libc/sys/fcntl.2 27 Jun 2011 08:21:08 -0000 1.39
+++ lib/libc/sys/fcntl.2 24 Jan 2012 01:48:28 -0000
@@ -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,6 +146,14 @@ 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
Index: lib/libc/sys/getsockopt.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/getsockopt.2,v
retrieving revision 1.34
diff -u -p -u -r1.34 getsockopt.2
--- lib/libc/sys/getsockopt.2 29 Jun 2009 08:38:07 -0000 1.34
+++ lib/libc/sys/getsockopt.2 24 Jan 2012 01:48:29 -0000
@@ -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: lib/libc/sys/kqueue.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/kqueue.2,v
retrieving revision 1.31
diff -u -p -u -r1.31 kqueue.2
--- lib/libc/sys/kqueue.2 26 Jun 2011 16:42:41 -0000 1.31
+++ lib/libc/sys/kqueue.2 24 Jan 2012 01:48:29 -0000
@@ -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: lib/libc/sys/open.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/open.2,v
retrieving revision 1.50
diff -u -p -u -r1.50 open.2
--- lib/libc/sys/open.2 20 Apr 2011 19:57:58 -0000 1.50
+++ lib/libc/sys/open.2 24 Jan 2012 01:48:29 -0000
@@ -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:
Index: lib/libc/sys/pipe.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/pipe.2,v
retrieving revision 1.27
diff -u -p -u -r1.27 pipe.2
--- lib/libc/sys/pipe.2 22 Jul 2011 11:02:39 -0000 1.27
+++ lib/libc/sys/pipe.2 24 Jan 2012 01:48:29 -0000
@@ -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: lib/libc/sys/socket.2
===================================================================
RCS file: /cvsroot/src/lib/libc/sys/socket.2,v
retrieving revision 1.37
diff -u -p -u -r1.37 socket.2
--- lib/libc/sys/socket.2 26 Jun 2011 16:42:41 -0000 1.37
+++ lib/libc/sys/socket.2 24 Jan 2012 01:48:29 -0000
@@ -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: sys/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/sys/fcntl.h 9 Aug 2011 04:19:17 -0000 1.41
+++ sys/sys/fcntl.h 24 Jan 2012 01:48:30 -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 */
@@ -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: sys/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/sys/filedesc.h 26 Jun 2011 16:43:12 -0000 1.61
+++ sys/sys/filedesc.h 24 Jan 2012 01:48:30 -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/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/sys/socket.h 20 Jan 2012 14:08:07 -0000 1.104
+++ sys/sys/socket.h 24 Jan 2012 01:48:30 -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 */
Index: sys/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
--- sys/kern/kern_descrip.c 25 Sep 2011 13:40:37 -0000 1.217
+++ sys/kern/kern_descrip.c 24 Jan 2012 01:48:31 -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: sys/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
--- sys/kern/kern_event.c 17 Nov 2011 22:41:55 -0000 1.74
+++ sys/kern/kern_event.c 24 Jan 2012 01:48:32 -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: sys/kern/sys_descrip.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_descrip.c,v
retrieving revision 1.23
diff -u -p -u -r1.23 sys_descrip.c
--- sys/kern/sys_descrip.c 31 Oct 2011 21:31:29 -0000 1.23
+++ sys/kern/sys_descrip.c 24 Jan 2012 01:48:34 -0000
@@ -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: sys/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
--- sys/kern/sys_generic.c 27 Jul 2011 14:35:34 -0000 1.127
+++ sys/kern/sys_generic.c 24 Jan 2012 01:48:34 -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: sys/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
--- sys/kern/sys_pipe.c 20 Oct 2011 18:18:21 -0000 1.134
+++ sys/kern/sys_pipe.c 24 Jan 2012 01:48:35 -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: sys/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
--- sys/kern/uipc_socket.c 20 Dec 2011 23:56:28 -0000 1.206
+++ sys/kern/uipc_socket.c 24 Jan 2012 01:48:36 -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: sys/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
--- sys/kern/uipc_syscalls.c 21 Dec 2011 15:26:57 -0000 1.150
+++ sys/kern/uipc_syscalls.c 24 Jan 2012 01:48:36 -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)
Home |
Main Index |
Thread Index |
Old Index