1491 – if working with timed-out socket, SIGPIPE will kill program

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 1491 - if working with timed-out socket, SIGPIPE will kill program
Summary: if working with timed-out socket, SIGPIPE will kill program
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: x86 Linux
: P2 normal
Assignee: Walter Bright
URL:
Keywords: patch
Depends on:
Blocks:
Reported: 2007年09月10日 20:16 UTC by FeepingCreature
Modified: 2015年06月09日 05:14 UTC (History)
0 users

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description FeepingCreature 2007年09月10日 20:16:57 UTC
On linux, when trying to work with a socket that has already expired, the signal SIGPIPE is raised.
If unchecked, it will terminate the program.
Since there is a defined behavior for trying to work with timed-out sockets (send/receive return -1), we can safely ignore this signal.
The following patch for gdc's std/thread.d (should be equally applicable to dmd) implements this:
diff socket.d.old socket.d -u 
--- socket.d.old 2007年09月11日 03:05:54.000000000 +0200
+++ socket.d 2007年09月11日 03:10:30.000000000 +0200
@@ -126,6 +126,17 @@
 }
 }
 
+version (Win32) { }
+else
+{
+ extern(C)
+ {
+ typedef void function(int) sighandler_t;
+ sighandler_t signal(int signum, sighandler_t handler);
+ const int SIGPIPE=13;
+ const sighandler_t SIG_IGN=cast(sighandler_t)cast(void*)1;
+ }
+}
 
 static this()
 {
@@ -140,6 +151,10 @@
 if(val) // Request Winsock 2.2 for IPv6.
 throw new SocketException("Unable to initialize socket library", val);
 }
+ else
+ {
+ signal(SIGPIPE, SIG_IGN);
+ }
 }
Comment 1 FeepingCreature 2007年09月11日 23:30:27 UTC
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Ingo Oeser wrote:
> d-bugmail@puremagic.com wrote:
> 
>> On linux, when trying to work with a socket that has already expired, the
>> signal SIGPIPE is raised.
>> If unchecked, it will terminate the program.
>> Since there is a defined behavior for trying to work with timed-out
>> sockets (send/receive return -1), we can safely ignore this signal.
>> The following patch for gdc's std/thread.d (should be equally applicable
>> to dmd) implements this:
> 
> No! NACK!
> 
> Signals are a global state.
> 
> Libraries should never modify them in that manner, since
> the defaults are well documented in signal(7) and programs
> might expect this behaviour.
I disagree on this. The only behavior std/socket.d should exhibit is the
behavior documented in http://digitalmars.com/d/phobos/std_socket.html.
Unix signals are a platform specific feature that somebody writing a
platform independent program should _not_ have to mess with.
> 
> The default setting for SIGPIPE is to terminate the program, 
> which is correct for simple programs not handling signals at all.
> 
But this behavior is neither documented in std_socket.html, nor is it
platform independent, nor is there a platform independent way to
_prevent it_.
> The preferred solution in Linux is to provide the flag MSG_NOSIGNAL 
> in the flags parameter of send(2), sendto(2) and sendmsg(2).
> 
Okay, well great! If there's a proper way to suppress this behavior, by
all means, let's do that instead! But please, don't force the user to
write platform dependent code. That's what standard libraries are for.
> But this symbol must be generated by gen_unix.c first, if defined.
> (in function c_socket())
> 
> 
Right, my patch isn't very clean. It was mainly along the lines of "hey,
this worked for me" :)
> Best Regards
> 
> Ingo Oeser
 --downs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFG52pepEPJRr05fBERAkhJAJ9Bv4DsPUvQQwKJQ1yC8lbKSP4hrgCgg0AT
yPxQCb9/hgAt0vng8rKJ/zE=
=jS6v
-----END PGP SIGNATURE-----
Comment 2 FeepingCreature 2007年09月11日 23:50:39 UTC
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Alright, here's a revised version of the patch.
diff config/gen_unix.c.old config/gen_unix.c -u; diff -u
std/socket.d.old std/socket.d
- --- config/gen_unix.c.old 2007年09月12日 06:33:55.000000000 +0200
+++ config/gen_unix.c 2007年09月12日 06:29:01.000000000 +0200
@@ -667,6 +667,7 @@
 CES( MSG_OOB );
 CES( MSG_PEEK );
 CES( MSG_DONTROUTE );
+ CES( MSG_NOSIGNAL );
 printf("}\n");
 printf("\n");
 }
- --- std/socket.d.old 2007年09月11日 03:05:54.000000000 +0200
+++ std/socket.d 2007年09月12日 06:37:08.000000000 +0200
@@ -1335,6 +1335,11 @@
 //returns number of bytes actually sent, or -1 on error
 int send(void[] buf, SocketFlags flags)
 {
+ version(Windows) { }
+ else
+ {
+ flags |= MSG_NOSIGNAL;
+ }
 int sent = .send(sock, buf.ptr, buf.length, cast(int)flags);
 return sent;
 }
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFG528HpEPJRr05fBERAmUiAJ9ZeCIXYZ9i1nrAzxsu2VaamtoEEQCggw/r
C7/6C3M8RK0c/PTZzH7/dFM=
=ZjqC
-----END PGP SIGNATURE-----
Comment 3 FeepingCreature 2007年09月12日 20:15:19 UTC
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Ingo Oeser wrote:
> Downs wrote:
> 
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Alright, here's a revised version of the patch.
> 
> That one was much better. Could you please fix the sendTo()
> method calling .sendto(), too?
> 
> Many thanks!
> 
> 
> Best Regards
> 
> Ingo Oeser
Sorry, I forgot. Sec ..
diff config/gen_unix.c.old config/gen_unix.c -u; diff -u
std/socket.d.old std/socket.d
- --- config/gen_unix.c.old 2007年09月12日 06:33:55.000000000 +0200
+++ config/gen_unix.c 2007年09月12日 06:29:01.000000000 +0200
@@ -667,6 +667,7 @@
 CES( MSG_OOB );
 CES( MSG_PEEK );
 CES( MSG_DONTROUTE );
+ CES( MSG_NOSIGNAL );
 printf("}\n");
 printf("\n");
 }
- --- std/socket.d.old 2007年09月11日 03:05:54.000000000 +0200
+++ std/socket.d 2007年09月13日 03:10:54.000000000 +0200
@@ -1335,6 +1335,11 @@
 //returns number of bytes actually sent, or -1 on error
 int send(void[] buf, SocketFlags flags)
 {
+ version(Windows) { }
+ else
+ {
+ flags |= MSG_NOSIGNAL;
+ }
 int sent = .send(sock, buf.ptr, buf.length, cast(int)flags);
 return sent;
 }
@@ -1350,6 +1355,11 @@
 */
 int sendTo(void[] buf, SocketFlags flags, Address to)
 {
+ version(Windows) { }
+ else
+ {
+ flags |= MSG_NOSIGNAL;
+ }
 int sent = .sendto(sock, buf.ptr, buf.length,
cast(int)flags, to.name(), to.nameLen());
 return sent;
 }
@@ -1365,6 +1375,11 @@
 /// ditto
 int sendTo(void[] buf, SocketFlags flags)
 {
+ version(Windows) { }
+ else
+ {
+ flags |= MSG_NOSIGNAL;
+ }
 int sent = .sendto(sock, buf.ptr, buf.length,
cast(int)flags, null, 0);
 return sent;
 }
Excuse the copypaste, but I wasn't sure whether it was worth it making a
new private function for this.
 --downs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFG6I6apEPJRr05fBERAkDXAKCaDYixAXUHIc31yvaPMAGNC46liACfZ1Za
wx9sEDj0PtbwQHct6B6GxfQ=
=rpSm
-----END PGP SIGNATURE-----
Comment 4 Walter Bright 2007年11月03日 21:48:04 UTC
Fixed dmd 1.023


AltStyle によって変換されたページ (->オリジナル) /