Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102893679
D35863.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D35863.diff
View Options
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -562,12 +562,16 @@
ktruio = cloneuio(auio);
#endif
cnt = auio->uio_resid;
- if ((error = fo_write(fp, auio, td->td_ucred, flags, td))) {
+ error = fo_write(fp, auio, td->td_ucred, flags, td);
+ /*
+ * Socket layer is responsible for special error handling,
+ * see sousrsend().
+ */
+ if (error != 0 && fp->f_type != DTYPE_SOCKET) {
if (auio->uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
- /* Socket layer is responsible for issuing SIGPIPE. */
- if (fp->f_type != DTYPE_SOCKET && error == EPIPE) {
+ if (error == EPIPE) {
PROC_LOCK(td->td_proc);
tdsignal(td, SIGPIPE);
PROC_UNLOCK(td->td_proc);
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -145,13 +145,7 @@
if (error)
return (error);
#endif
- error = sosend(so, 0, uio, 0, 0, 0, uio->uio_td);
- if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) {
- PROC_LOCK(uio->uio_td->td_proc);
- tdsignal(uio->uio_td, SIGPIPE);
- PROC_UNLOCK(uio->uio_td->td_proc);
- }
- return (error);
+ return (sousrsend(so, NULL, uio, NULL, 0, NULL));
}
static int
@@ -646,15 +640,10 @@
error = mac_socket_check_send(fp->f_cred, so);
if (error == 0)
#endif
- error = sosend(so, NULL, job->uiop, NULL, NULL, flags,
- td);
+ error = sousrsend(so, NULL, job->uiop, NULL, flags,
+ job->userproc);
if (td->td_ru.ru_msgsnd != ru_before)
job->msgsnd = 1;
- if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) {
- PROC_LOCK(job->userproc);
- kern_psignal(job->userproc, SIGPIPE);
- PROC_UNLOCK(job->userproc);
- }
}
done += cnt - job->uiop->uio_resid;
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1822,6 +1822,14 @@
return (error);
}
+/*
+ * Send to a socket from a kernel thread.
+ *
+ * XXXGL: in almost all cases uio is NULL and the mbuf is supplied.
+ * Exception is nfs/bootp_subr.c. It is arguable that the VNET context needs
+ * to be set at all. This function should just boil down to a static inline
+ * calling the protocol method.
+ */
int
sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
struct mbuf *top, struct mbuf *control, int flags, struct thread *td)
@@ -1835,6 +1843,47 @@
return (error);
}
+/*
+ * send(2), write(2) or aio_write(2) on a socket.
+ */
+int
+sousrsend(struct socket *so, struct sockaddr *addr, struct uio *uio,
+ struct mbuf *control, int flags, struct proc *userproc)
+{
+ struct thread *td;
+ ssize_t len;
+ int error;
+
+ td = uio->uio_td;
+ len = uio->uio_resid;
+ CURVNET_SET(so->so_vnet);
+ error = so->so_proto->pr_sosend(so, addr, uio, NULL, control, flags,
+ td);
+ CURVNET_RESTORE();
+ if (error != 0) {
+ if (uio->uio_resid != len &&
+ (so->so_proto->pr_flags & PR_ATOMIC) == 0 &&
+ (error == ERESTART || error == EINTR ||
+ error == EWOULDBLOCK))
+ error = 0;
+ /* Generation of SIGPIPE can be controlled per socket. */
+ if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0 &&
+ (flags & MSG_NOSIGNAL) == 0) {
+ if (userproc != NULL) {
+ /* aio(4) job */
+ PROC_LOCK(userproc);
+ kern_psignal(userproc, SIGPIPE);
+ PROC_UNLOCK(userproc);
+ } else {
+ PROC_LOCK(td->td_proc);
+ tdsignal(td, SIGPIPE);
+ PROC_UNLOCK(td->td_proc);
+ }
+ }
+ }
+ return (error);
+}
+
/*
* The part of soreceive() that implements reading non-inline out-of-band
* data from a socket. For more complete comments, see soreceive(), from
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -798,21 +798,7 @@
ktruio = cloneuio(&auio);
#endif
len = auio.uio_resid;
- error = sosend(so, mp->msg_name, &auio, 0, control, flags, td);
- if (error != 0) {
- if (auio.uio_resid != len &&
- (so->so_proto->pr_flags & PR_ATOMIC) == 0 &&
- (error == ERESTART || error == EINTR ||
- error == EWOULDBLOCK))
- error = 0;
- /* Generation of SIGPIPE can be controlled per socket */
- if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
- !(flags & MSG_NOSIGNAL)) {
- PROC_LOCK(td->td_proc);
- tdsignal(td, SIGPIPE);
- PROC_UNLOCK(td->td_proc);
- }
- }
+ error = sousrsend(so, mp->msg_name, &auio, control, flags, NULL);
if (error == 0)
td->td_retval[0] = len - auio.uio_resid;
#ifdef KTRACE
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -506,6 +506,8 @@
int sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
struct mbuf *top, struct mbuf *control, int flags,
struct thread *td);
+int sousrsend(struct socket *so, struct sockaddr *addr, struct uio *uio,
+ struct mbuf *control, int flags, struct proc *);
int sosend_dgram(struct socket *so, struct sockaddr *addr,
struct uio *uio, struct mbuf *top, struct mbuf *control,
int flags, struct thread *td);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 19, 10:12 AM (19 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14714675
Default Alt Text
D35863.diff (5 KB)
Attached To
Mode
D35863: sockets: provide sousrsend() that does socket specific error handling
Attached
Detach File
Event Timeline
Log In to Comment