diff options
-rw-r--r-- | sys/compat/linux/linux_socket.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index dd358ce..6f6f501 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -816,18 +816,41 @@ linux_send(struct thread *td, struct linux_send_args *args) caddr_t to; int tolen; } */ bsd_args; - int error; + int error, nosigpipe, onosigpipe; + socklen_t valsize; 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; - return (sendto(td, &bsd_args)); + 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; } struct linux_recv_args { |