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); + } }
-----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-----
-----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-----
-----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-----
Fixed dmd 1.023
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル