From owner-freebsd-emulation@FreeBSD.ORG Tue Jan 18 18:54:59 2005 Return-Path: Delivered-To: freebsd-emulation@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9656416A4CE; Tue, 18 Jan 2005 18:54:59 +0000 (GMT) Received: from dev1.multiplay.co.uk (dev1.multiplay.co.uk [212.42.16.81]) by mx1.FreeBSD.org (Postfix) with ESMTP id 073B943D45; Tue, 18 Jan 2005 18:54:59 +0000 (GMT) (envelope-from root@dev1.multiplay.co.uk) Received: from dev1.multiplay.co.uk (localhost.multiplay.co.uk [127.0.0.1]) j0IIsxf1023146; Tue, 18 Jan 2005 18:54:59 GMT (envelope-from root@dev1.multiplay.co.uk) Received: (from root@localhost) by dev1.multiplay.co.uk (8.12.10/8.12.10/Submit) id j0IIsxtr023145; Tue, 18 Jan 2005 18:54:59 GMT (envelope-from root) Date: Tue, 18 Jan 2005 18:54:59 GMT Message-Id: <200501181854.j0IIsxtr023145@dev1.multiplay.co.uk> To: FreeBSD-gnats-submit@freebsd.org From: Steven Harltand X-send-pr-version: 3.113 X-GNATS-Notify: cc: "freebsd-emulation@FreeBSD.org" Subject: Linux ABI doesn't support MSG_NOSIGNAL X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Steven Harltand List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Jan 2005 18:54:59 -0000 >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)); + } }