kern/76426: Linux ABI doesn't support MSG_NOSIGNAL
Steven Harltand
killing at multiplay.co.uk
Tue Jan 18 11:00:44 PST 2005
>Number: 76426
>Category: kern
>Synopsis: Linux ABI doesn't support MSG_NOSIGNAL
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: update
>Submitter-Id: current-users
>Arrival-Date: Tue Jan 18 19:00:43 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Steven Hartland
>Release: FreeBSD 5.2.1-RELEASE-p13 i386
>Organization:
Multiplay UK
>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 at 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));
+ }
}
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list