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:
Maxim Sobolev 2005-03-08 16:11:41 +00:00
parent 68d9d1e64e
commit 8d6e40c3f1
3 changed files with 7 additions and 28 deletions

View File

@ -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 {

View File

@ -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);

View File

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