Date: Tue, 18 Jan 2005 18:54:59 GMT From: Steven Harltand <killing@multiplay.co.uk> To: FreeBSD-gnats-submit@freebsd.org Cc: "freebsd-emulation@FreeBSD.org" <freebsd-emulation@freebsd.org> Subject: Linux ABI doesn't support MSG_NOSIGNAL Message-ID: <200501181854.j0IIsxtr023145@dev1.multiplay.co.uk>
next in thread | raw e-mail | index | archive | help
>Submitter-Id: current-users
>Originator: Steven Hartland
>Organization: Multiplay UK
>Confidential: no
>Synopsis: Linux ABI doesn't support MSG_NOSIGNAL
>Severity: serious
>Priority: medium
>Category: kern
>Class: update
>Release: FreeBSD 5.2.1-RELEASE-p13 i386
>Environment:
System: FreeBSD dev1.multiplay.co.uk 5.2.1-RELEASE-p13 FreeBSD 5.2.1-RELEASE-p13 #0: Tue Jan 18 11:07:10 GMT 2005 root@dev1.multiplay.co.uk:/usr/src/sys/i386/compile/MPUK_SINGLE_200HZ i386
>Description:
The linux ABI doesnt support MSG_NOSIGNAL it just gets lost in linux_send.
The attached patch temporatly set SO_NOSIGPIPE on the socket fixing this issue.
Im not 100% sure this is the best way of doing it but it works.
>How-To-Repeat:
Set the MSG_NOSIGNAL on a long running send and close the reciever. SIGPIPE
should be ignored but its not currently, causing the sender to exit if not
caught manually.
>Fix:
Apply the following patch:
--- linux_socket.c.orig Tue Jan 18 10:41:32 2005
+++ linux_socket.c Tue Jan 18 11:02:37 2005
@@ -869,5 +869,48 @@
bsd_args.len = linux_args.len;
bsd_args.flags = linux_args.flags;
- return (osend(td, &bsd_args));
+ if ( linux_args.flags & LINUX_MSG_NOSIGNAL )
+ {
+ /* requested to ignore pipe so set SO_NOSIGPIPE temporarily */
+ int ret_send, ret_opt;
+ struct setsockopt_args /* {
+ int s;
+ int level;
+ int name;
+ caddr_t val;
+ int valsize;
+ } */ bsd_setsockopt_args;
+ caddr_t sg;
+ int *nosigpipe;
+
+ sg = stackgap_init();
+ nosigpipe = (int *)stackgap_alloc(&sg, sizeof(*nosigpipe));
+ *nosigpipe = 1;
+ bsd_setsockopt_args.s = linux_args.s;
+ bsd_setsockopt_args.level = SOL_SOCKET;
+ bsd_setsockopt_args.name = SO_NOSIGPIPE;
+ bsd_setsockopt_args.val = (caddr_t)nosigpipe;
+ bsd_setsockopt_args.valsize = sizeof(*nosigpipe);
+ ret_opt = setsockopt(td, &bsd_setsockopt_args);
+ if ( -1 == ret_opt )
+ {
+ return ret_opt;
+ }
+
+ ret_send = (osend(td, &bsd_args));
+ /* must clear the option */
+ *nosigpipe = 1;
+ bsd_setsockopt_args.val = (caddr_t)nosigpipe;
+ ret_opt = setsockopt(td, &bsd_setsockopt_args);
+ if ( -1 == ret_send || -1 == ret_opt )
+ {
+ return -1;
+ }
+
+ return ret_send;
+ }
+ else
+ {
+ return (osend(td, &bsd_args));
+ }
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501181854.j0IIsxtr023145>
