Add kernel-only flag MSG_NOSIGNAL to be used in emulation layers to surpress
SIGPIPE signal for the duration of the sento-family syscalls. Use it to replace previously added hack in Linux layer based on temporarily setting SO_NOSIGPIPE flag. Suggested by: alfred
This commit is contained in:
parent
68d9d1e64e
commit
8d6e40c3f1
@ -322,6 +322,8 @@ linux_to_bsd_msg_flags(int flags)
|
||||
ret_flags |= MSG_EOR;
|
||||
if (flags & LINUX_MSG_WAITALL)
|
||||
ret_flags |= MSG_WAITALL;
|
||||
if (flags & LINUX_MSG_NOSIGNAL)
|
||||
ret_flags |= MSG_NOSIGNAL;
|
||||
#if 0 /* not handled */
|
||||
if (flags & LINUX_MSG_PROXY)
|
||||
;
|
||||
@ -335,8 +337,6 @@ linux_to_bsd_msg_flags(int flags)
|
||||
;
|
||||
if (flags & LINUX_MSG_ERRQUEUE)
|
||||
;
|
||||
if (flags & LINUX_MSG_NOSIGNAL)
|
||||
;
|
||||
#endif
|
||||
return ret_flags;
|
||||
}
|
||||
@ -816,41 +816,18 @@ linux_send(struct thread *td, struct linux_send_args *args)
|
||||
caddr_t to;
|
||||
int tolen;
|
||||
} */ bsd_args;
|
||||
int error, nosigpipe, onosigpipe;
|
||||
socklen_t valsize;
|
||||
int error;
|
||||
|
||||
if ((error = copyin(args, &linux_args, sizeof(linux_args))))
|
||||
return (error);
|
||||
|
||||
if (linux_args.flags & LINUX_MSG_NOSIGNAL) {
|
||||
valsize = sizeof(onosigpipe);
|
||||
error = kern_getsockopt(td, linux_args.s, SOL_SOCKET,
|
||||
SO_NOSIGPIPE, &onosigpipe, UIO_SYSSPACE,
|
||||
&valsize);
|
||||
if (error != 0)
|
||||
return error;
|
||||
if (onosigpipe == 0) {
|
||||
nosigpipe = 1;
|
||||
error = kern_setsockopt(td, linux_args.s, SOL_SOCKET,
|
||||
SO_NOSIGPIPE, &nosigpipe, UIO_SYSSPACE,
|
||||
sizeof(nosigpipe));
|
||||
if (error != 0)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
bsd_args.s = linux_args.s;
|
||||
bsd_args.buf = (caddr_t)PTRIN(linux_args.msg);
|
||||
bsd_args.len = linux_args.len;
|
||||
bsd_args.flags = linux_args.flags;
|
||||
bsd_args.to = NULL;
|
||||
bsd_args.tolen = 0;
|
||||
error = sendto(td, &bsd_args);
|
||||
if ((linux_args.flags & LINUX_MSG_NOSIGNAL) && (onosigpipe == 0)) {
|
||||
kern_setsockopt(td, linux_args.s, SOL_SOCKET,
|
||||
SO_NOSIGPIPE, &onosigpipe, UIO_SYSSPACE,
|
||||
sizeof(onosigpipe));
|
||||
}
|
||||
return error;
|
||||
return sendto(td, &bsd_args);
|
||||
}
|
||||
|
||||
struct linux_recv_args {
|
||||
|
@ -755,7 +755,8 @@ kern_sendit(td, s, mp, flags, control, segflg)
|
||||
error == EINTR || error == EWOULDBLOCK))
|
||||
error = 0;
|
||||
/* Generation of SIGPIPE can be controlled per socket */
|
||||
if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE)) {
|
||||
if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
|
||||
!(flags & MSG_NOSIGNAL)) {
|
||||
PROC_LOCK(td->td_proc);
|
||||
psignal(td->td_proc, SIGPIPE);
|
||||
PROC_UNLOCK(td->td_proc);
|
||||
|
@ -398,6 +398,7 @@ struct msghdr {
|
||||
#endif
|
||||
#ifdef _KERNEL
|
||||
#define MSG_SOCALLBCK 0x10000 /* for use by socket callbacks - soreceive (TCP) */
|
||||
#define MSG_NOSIGNAL 0x20000 /* for use with emulation layers */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user