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>