diff options
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/process.c | 37 |
2 files changed, 37 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index a2e5262c02b..870c805a92c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2010-03-25 Helmut Eller <eller.helmut@gmail.com> | ||
| 2 | |||
| 3 | * process.c (Fmake_network_process): Call `select' for interrupted | ||
| 4 | `connect' rather than creating new socket (Bug#5173). | ||
| 5 | |||
| 1 | 2010-03-24 Jan Djärv <jan.h.d@swipnet.se> | 6 | 2010-03-24 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 7 | ||
| 3 | * frame.c (x_get_arg): Handle RES_TYPE_BOOLEAN_NUMBER (bug #5736). | 8 | * frame.c (x_get_arg): Handle RES_TYPE_BOOLEAN_NUMBER (bug #5736). |
diff --git a/src/process.c b/src/process.c index 5d2d64e3ddc..789befc2a6b 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -3534,8 +3534,6 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3534 | { | 3534 | { |
| 3535 | int optn, optbits; | 3535 | int optn, optbits; |
| 3536 | 3536 | ||
| 3537 | retry_connect: | ||
| 3538 | |||
| 3539 | s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); | 3537 | s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); |
| 3540 | if (s < 0) | 3538 | if (s < 0) |
| 3541 | { | 3539 | { |
| @@ -3652,6 +3650,38 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3652 | #endif | 3650 | #endif |
| 3653 | #endif | 3651 | #endif |
| 3654 | #endif | 3652 | #endif |
| 3653 | if (xerrno == EINTR) | ||
| 3654 | { | ||
| 3655 | /* Unlike most other syscalls connect() cannot be called | ||
| 3656 | again. (That would return EALREADY.) The proper way to | ||
| 3657 | wait for completion is select(). */ | ||
| 3658 | int sc; | ||
| 3659 | SELECT_TYPE fdset; | ||
| 3660 | retry_select: | ||
| 3661 | FD_ZERO (&fdset); | ||
| 3662 | FD_SET (s, &fdset); | ||
| 3663 | QUIT; | ||
| 3664 | sc = select (s + 1, (SELECT_TYPE *)0, &fdset, (SELECT_TYPE *)0, | ||
| 3665 | (EMACS_TIME *)0); | ||
| 3666 | if (sc == -1) | ||
| 3667 | { | ||
| 3668 | if (errno == EINTR) | ||
| 3669 | goto retry_select; | ||
| 3670 | else | ||
| 3671 | report_file_error ("select failed", Qnil); | ||
| 3672 | } | ||
| 3673 | eassert (sc > 0); | ||
| 3674 | { | ||
| 3675 | int len = sizeof xerrno; | ||
| 3676 | eassert (FD_ISSET (s, &fdset)); | ||
| 3677 | if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1) | ||
| 3678 | report_file_error ("getsockopt failed", Qnil); | ||
| 3679 | if (xerrno != 0) | ||
| 3680 | errno = xerrno, report_file_error ("error during connect", Qnil); | ||
| 3681 | else | ||
| 3682 | break; | ||
| 3683 | } | ||
| 3684 | } | ||
| 3655 | 3685 | ||
| 3656 | immediate_quit = 0; | 3686 | immediate_quit = 0; |
| 3657 | 3687 | ||
| @@ -3659,9 +3689,6 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3659 | specpdl_ptr = specpdl + count1; | 3689 | specpdl_ptr = specpdl + count1; |
| 3660 | emacs_close (s); | 3690 | emacs_close (s); |
| 3661 | s = -1; | 3691 | s = -1; |
| 3662 | |||
| 3663 | if (xerrno == EINTR) | ||
| 3664 | goto retry_connect; | ||
| 3665 | } | 3692 | } |
| 3666 | 3693 | ||
| 3667 | if (s >= 0) | 3694 | if (s >= 0) |