Skip site navigation (1)Skip section navigation (2)
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>