summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2002-06-20 18:52:54 +0000
committeralfred <alfred@FreeBSD.org>2002-06-20 18:52:54 +0000
commit619c88aeeb99f6aa38801e896d23cbb5def3a151 (patch)
treee87489ee79235af36bbac2f16018487df412f86e /sys
parentc2afd32ef72eac57b98d33e52cb7d01c26da2dce (diff)
downloadFreeBSD-src-619c88aeeb99f6aa38801e896d23cbb5def3a151.zip
FreeBSD-src-619c88aeeb99f6aa38801e896d23cbb5def3a151.tar.gz
Implement SO_NOSIGPIPE option for sockets. This allows one to request that
an EPIPE error return not generate SIGPIPE on sockets. Submitted by: lioux Inspired by: Darwin
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_generic.c3
-rw-r--r--sys/kern/uipc_socket.c2
-rw-r--r--sys/kern/uipc_syscalls.c3
-rw-r--r--sys/sys/socket.h1
4 files changed, 7 insertions, 2 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index bec5cca..1bdd913 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -420,7 +420,8 @@ dofilewrite(td, fp, fd, buf, nbyte, offset, flags)
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
- if (error == EPIPE) {
+ /* Socket layer is responsible for issuing SIGPIPE. */
+ if (error == EPIPE && fp->f_type != DTYPE_SOCKET) {
PROC_LOCK(td->td_proc);
psignal(td->td_proc, SIGPIPE);
PROC_UNLOCK(td->td_proc);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 6458ce0..2b9e0be 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1179,6 +1179,7 @@ sosetopt(so, sopt)
case SO_REUSEPORT:
case SO_OOBINLINE:
case SO_TIMESTAMP:
+ case SO_NOSIGPIPE:
error = sooptcopyin(sopt, &optval, sizeof optval,
sizeof optval);
if (error)
@@ -1362,6 +1363,7 @@ sogetopt(so, sopt)
case SO_BROADCAST:
case SO_OOBINLINE:
case SO_TIMESTAMP:
+ case SO_NOSIGPIPE:
optval = so->so_options & sopt->sopt_name;
integer:
error = sooptcopyout(sopt, &optval, sizeof optval);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index b44e644..60e5719 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -649,7 +649,8 @@ sendit(td, s, mp, flags)
if (auio.uio_resid != len && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
- if (error == EPIPE) {
+ /* Generation of SIGPIPE can be controlled per socket */
+ if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE)) {
PROC_LOCK(td->td_proc);
psignal(td->td_proc, SIGPIPE);
PROC_UNLOCK(td->td_proc);
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
index 8e2ec8b..4254c72 100644
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -82,6 +82,7 @@ typedef _BSD_SOCKLEN_T_ socklen_t;
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */
#define SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */
+#define SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */
#define SO_ACCEPTFILTER 0x1000 /* there is an accept filter */
/*
OpenPOWER on IntegriCloud