Handle MSG_NOSIGNAL flag in linux_send() by setting SO_NOSIGPIPE on socket
for the duration of the send() call. Such approach may be less than ideal in threading environment, when several threads share the same socket and it might happen that several of them are calling linux_send() at the same time with and without SO_NOSIGPIPE set. However, such race condition is very unlikely in practice, therefore this change provides practical improvement compared to the previous behaviour. PR: kern/76426 Submitted by: Steven Hartland <killing@multiplay.co.uk> MFC after: 3 days
This commit is contained in:
parent
7d3d18d907
commit
a5d845fec6
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user