From eller.helmut@gmail.com Wed Dec 9 15:36:26 2009 Received: (at submit) by emacsbugs.donarmstrong.com; 9 Dec 2009 23:36:26 +0000 X-Spam-Checker-Version: SpamAssassin 3.2.5-bugs.debian.org_2005_01_02 (2008-06-10) on rzlab.ucr.edu X-Spam-Level: X-Spam-Bayes: score:0.5 Bayes not run. spammytokens:Tokens not available. hammytokens:Tokens not available. X-Spam-Status: No, score=-0.4 required=4.0 tests=AWL,FOURLA,MURPHY_DRUGS_REL8 autolearn=no version=3.2.5-bugs.debian.org_2005_01_02 Received: from fencepost.gnu.org (fencepost.gnu.org [140.186.70.10]) by rzlab.ucr.edu (8.14.3/8.14.3/Debian-5) with ESMTP id nB9NaOvi011623 for ; Wed, 9 Dec 2009 15:36:25 -0800 Received: from mail.gnu.org ([199.232.76.166]:43512 helo=mx10.gnu.org) by fencepost.gnu.org with esmtp (Exim 4.67) (envelope-from ) id 1NIW51-0006Y4-TS for emacs-pretest-bug@gnu.org; Wed, 09 Dec 2009 18:36:24 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1NIW50-0004a8-3C for emacs-pretest-bug@gnu.org; Wed, 09 Dec 2009 18:36:23 -0500 Received: from dial-177248.pool.broadband44.net ([212.46.177.248]:42583 helo=ix) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1NIW4z-0004a2-DV for emacs-pretest-bug@gnu.org; Wed, 09 Dec 2009 18:36:21 -0500 Received: from helmut by ix with local (Exim 4.69) (envelope-from ) id 1NIVcz-0008Ee-Cx for emacs-pretest-bug@gnu.org; Thu, 10 Dec 2009 00:07:25 +0100 From: Helmut Eller To: emacs-pretest-bug@gnu.org Subject: 23.1.50; interrupted connect() not handled properly Date: Thu, 10 Dec 2009 00:07:25 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1.50 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) X-Greylist: delayed 1734 seconds by postgrey-1.27 at monty-python; Wed, 09 Dec 2009 18:36:20 EST --=-=-= Interrupts during connect() in make-network-process aren't handled properly. The following recipe to reproduce the problem is rather complicated. You'll need: - Qemu - a kernel with tuntap support (/dev/net/tun) - tunctl (from uml-utilities) - a linux image for Qemu. If you haven't one use http://www.nongnu.org/qemu/linux-0.2.img.bz2 - netcat The problem occurs during connect() and to make this period longer and more controllable we will use Qemu so that we can stop&resume the (virtual) TCP stack. Also note that we are dealing with signals here and that strace or gdb would interfere with the problem. * Prepare Qemu Our goal here is to start Qemu with a virtual network interface like so: qemu -hda linux-0.2.img -net nic -net tap,ifname=qtap0,script=no Before we can do that we need to create the qtap0 device: sudo tunctl -u USER -t qtap0 # replace USER with your user sudo ifconfig qtap0 192.168.255.1 up 192.168.255.1 will most likely work for you but any non-conflicting IP address will do. We'll also need netcat on the virtual machine. So let's copy it to the image: mkdir img sudo mount -o loop linux-0.2.img img sudo cp -L /bin/netcat img/usr/bin sudo umount img Now try qemu -hda linux-0.2.img -net nic -net tap,ifname=qtap0,script=no This should boot up a linux and present you a shell. In the shell configure the network device like so: sh-2.05b# ifconfig eth0 192.168.255.2 Make sure that you can ping that device from the host system with ping 192.168.255.2 If it doesn't work, check the output of route on the guest and the host. * Test netcat Next test netcat. Inside Qemu do: sh-2.05b# netcat -l -p 44444 and on the host: netcat 192.168.255.2 44444 Everything you type on the host should be echoed on the guest. When you abort with C-c the netcat inside Qemu should also abort. * Test Function Now we are almost ready to run real tests. Create a file connect-eintr.el containing the following function. (defun testit (vmpid) (switch-to-buffer "*Messages*") (signal-process vmpid 'SIGSTOP) (shell-command (concat (format "(sleep 0.4; kill -SIGSTOP %d; " (emacs-pid)) (format " sleep 0.1; kill -SIGCONT %d; " vmpid) (format " sleep 3; kill -SIGCONT %d;)&" (emacs-pid)))) (let ((sock (make-network-process :name "test" :service 44444 :host "192.168.255.2" :sentinel (lambda (x y) (error "sentinel: %s %s" x y))))) (process-send-string sock "foo") (process-send-string sock "bar") (process-send-string sock "baz\n") (message "ok"))) The function does the following steps: 1) stop Qemu 2) connect() 3) stop Emacs 4) resume Qemu 5) resume Emacs 6) write some output to the socket >From 2 to 4 Emacs will be inside connect() and we have plenty of time to press a key to generate an interrupt. * Run the test Before running the function create a listening socket inside Qemu as above: sh-2.05b# netcat -l -p 44444 For the next step we need the process id of Qemu, lets call that QPID. Use QPID in the following command line: emacs -Q -load connect-eintr.el -eval '(testit QPID)' -f kill-emacs This starts Emacs and runs the test. If you're using X11 and and don't press any key, Emacs will terminate after a few seconds and foobarbaz will appear in Qemu. Restart netcat as above and re-run the test, but this time press a key after Emacs' frame appears. This time Emacs will not terminate, but instead an error message will be visible in the *Messages* buffer. Also the netcat process in Qemu will be terminated but without producing any output. This latter behavior is wrong. Emacs should handle interrupts generated by pressing keys more gracefully. The problem will also occur if you run Emacs without X11 but the SIGSTOP will return the terminal to the shell and you have to put Emacs into foreground again with the fg command. Your terminal is most likely messed up at that point but the error message should still be visible. * Probable Cause of the problem The cause of the problem is that Emacs closes the socket after being interrupted in connect(). That approach works with servers which accept many connections but fails for servers which serve one connection only as the example with netcat above did. * Proposed fix As described here: http://www.madore.org/~david/computers/connect-intr.html the recommended way to handle interrupts during connect() is to use select() on the socket. The socket will become writable when the connection is established or when an error occurs. The error can be obtained with getsockopt. The patch below implements just that. The only other addition is the introduction of two macros EWOULDBLOCK_P and EINPROGRESS_P which have the only purpose to reduce #ifdef/#ifndef clutter. Helmut --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=connect.patch --- process.c.~1.607.~ 2009-12-04 08:01:43.000000000 +0100 +++ process.c 2009-12-09 23:37:19.000000000 +0100 @@ -234,6 +234,18 @@ #endif /* NON_BLOCKING_CONNECT */ #endif /* BROKEN_NON_BLOCKING_CONNECT */ +#ifdef EWOULDBLOCK +# define EWOULDBLOCK_P(x) (x == EWOULDBLOCK) +#else +# define EWOULDBLOCK_P(x) (0) +#endif + +#ifdef EINPROGRESS +# define EINPROGRESS_P(x) (x == EINPROGRESS) +#else +# define EINPROGRESS_P(x) (0) +#endif + /* Define DATAGRAM_SOCKETS if datagrams can be used safely on this system. We need to read full packets, so we need a "non-destructive" select. So we require either native select, @@ -3338,9 +3350,8 @@ { #ifndef NON_BLOCKING_CONNECT error ("Non-blocking connect not supported"); -#else - is_non_blocking_client = 1; #endif + is_non_blocking_client = 1; } name = Fplist_get (contact, QCname); @@ -3566,10 +3577,8 @@ continue; } -#ifdef DATAGRAM_SOCKETS if (!is_server && socktype == SOCK_DGRAM) break; -#endif /* DATAGRAM_SOCKETS */ #ifdef NON_BLOCKING_CONNECT if (is_non_blocking_client) @@ -3655,26 +3664,44 @@ ret = connect (s, lres->ai_addr, lres->ai_addrlen); xerrno = errno; - turn_on_atimers (1); + turn_on_atimers (1); - if (ret == 0 || xerrno == EISCONN) - { + if (ret == 0 + || (EWOULDBLOCK_P (xerrno) && is_non_blocking_client) + || (EINPROGRESS_P (xerrno) && is_non_blocking_client)) /* The unwind-protect will be discarded afterwards. Likewise for immediate_quit. */ break; - } -#ifdef NON_BLOCKING_CONNECT -#ifdef EINPROGRESS - if (is_non_blocking_client && xerrno == EINPROGRESS) - break; -#else -#ifdef EWOULDBLOCK - if (is_non_blocking_client && xerrno == EWOULDBLOCK) - break; -#endif -#endif -#endif + if (xerrno == EINTR) + { + /* Unlike most other syscalls connect() cannot be called + again. (That would return EALREADY.) The proper way to + wait for completion is select(). */ + int sc; + fd_set fdset; + retry_select: + FD_ZERO (&fdset); + FD_SET (s, &fdset); + QUIT; + sc = select (s + 1, 0, &fdset, 0, 0); + if (sc == -1) + if (errno == EINTR) + goto retry_select; + else + report_file_error ("select failed", Qnil); + eassert (sc > 0); + { + int len = sizeof xerrno; + eassert (FD_ISSET (s, &fdset)); + if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1) + report_file_error ("getsockopt failed", Qnil); + if (xerrno != 0) + errno = xerrno, report_file_error ("error during connect", Qnil); + else + break; + } + } immediate_quit = 0; @@ -3682,9 +3709,6 @@ specpdl_ptr = specpdl + count1; emacs_close (s); s = -1; - - if (xerrno == EINTR) - goto retry_connect; } if (s >= 0) --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Jan 27 19:13:46 2010 Received: (at control) by debbugs.gnu.org; 28 Jan 2010 00:13:46 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1NaI14-0003WI-8V for submit@debbugs.gnu.org; Wed, 27 Jan 2010 19:13:46 -0500 Received: from fencepost.gnu.org ([140.186.70.10]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1NaI12-0003WB-1C for control@debbugs.gnu.org; Wed, 27 Jan 2010 19:13:44 -0500 Received: from rgm by fencepost.gnu.org with local (Exim 4.69) (envelope-from ) id 1NaI0y-0002kj-9B; Wed, 27 Jan 2010 19:13:40 -0500 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <19296.54964.237486.393967@fencepost.gnu.org> Date: Wed, 27 Jan 2010 19:13:40 -0500 From: Glenn Morris To: control Subject: control X-Attribution: GM X-Mailer: VM (www.wonderworks.com/vm), GNU Emacs (www.gnu.org/software/emacs) X-Hue: magenta X-Ran: jqeI@9]N2j9L=T5y{46XM$yis^=8-t%A[c3H.k}5+~~"#Nf)E5)8*?XxH+0T%:q./m!M*2 X-Debbugs-No-Ack: yes X-Spam-Score: -4.9 (----) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -4.9 (----) tags 5032 moreinfo reassign 5032 emacs,w32 reassign 5040 emacs,w32 severity 5042 wishlist reassign 5074 emacs,w32 severity 5105 minor tags 5173 patch severity 5183 minor severity 5184 minor submitter 5195 monnier@iro.umontreal.ca unarchive 5227 unmerge 5227 tags 5251 patch severity 5290 wishlist reassign 5299 emacs,w32 tags 5326 patch reopen 5336 severity 5336 serious retitle 5336 DOC file is arch dependent reassign 5349 emacs,ns severity 5433 wishlist close 5456 reassign 5464 emacs,w32 reassign 5465 emacs,w32 reassign 5480 emacs,gnus reassign 5482 emacs,w32 reassign 5484 emacs,etags tags 5484 patch From debbugs-submit-bounces@debbugs.gnu.org Thu Mar 25 05:00:06 2010 Received: (at 5173-done) by debbugs.gnu.org; 25 Mar 2010 09:00:06 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Nuiv7-0000iW-S0 for submit@debbugs.gnu.org; Thu, 25 Mar 2010 05:00:06 -0400 Received: from mathmail.math.s.chiba-u.ac.jp ([133.82.132.2]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Nuiv6-0000hu-5p for 5173-done@debbugs.gnu.org; Thu, 25 Mar 2010 05:00:05 -0400 Received: from church.math.s.chiba-u.ac.jp (church [133.82.132.36]) by mathmail.math.s.chiba-u.ac.jp (Postfix) with ESMTP id 27CD5C0557 for <5173-done@debbugs.gnu.org>; Thu, 25 Mar 2010 17:59:58 +0900 (JST) Date: Thu, 25 Mar 2010 17:59:58 +0900 Message-ID: From: YAMAMOTO Mitsuharu To: 5173-done@debbugs.gnu.org User-Agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.8 (=?ISO-8859-4?Q?Shij=F2?=) APEL/10.6 Emacs/22.3 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI) Organization: Faculty of Science, Chiba University MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Spam-Score: -1.8 (-) X-Debbugs-Envelope-To: 5173-done X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -1.8 (-) Closed with this change: revno: 99750 author: Helmut Eller committer: YAMAMOTO Mitsuharu branch nick: trunk timestamp: Thu 2010-03-25 17:48:52 +0900 message: Call `select' for interrupted `connect' rather than creating new socket (Bug#5173). From unknown Sat Sep 13 12:47:43 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Thu, 22 Apr 2010 11:24:03 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator