diff options
| author | Helmut Eller | 2010-11-04 15:53:28 -0400 |
|---|---|---|
| committer | Chong Yidong | 2010-11-04 15:53:28 -0400 |
| commit | c2e124a95b5f1dcb7d8e7f2ea1549d30fd54bc17 (patch) | |
| tree | 9a59b397539ce1b30123a79448ede155124863c7 /src/process.c | |
| parent | 68ae6cda9e2a55c23d9680953bf9a402616e6901 (diff) | |
| download | emacs-c2e124a95b5f1dcb7d8e7f2ea1549d30fd54bc17.tar.gz emacs-c2e124a95b5f1dcb7d8e7f2ea1549d30fd54bc17.zip | |
Backport 2010-03-25T08:48:52Z!mituharu@math.s.chiba-u.ac.jp from trunk
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/process.c b/src/process.c index 567300e2f64..77490adaa79 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -3573,8 +3573,6 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3573 | { | 3573 | { |
| 3574 | int optn, optbits; | 3574 | int optn, optbits; |
| 3575 | 3575 | ||
| 3576 | retry_connect: | ||
| 3577 | |||
| 3578 | s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); | 3576 | s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol); |
| 3579 | if (s < 0) | 3577 | if (s < 0) |
| 3580 | { | 3578 | { |
| @@ -3691,6 +3689,38 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3691 | #endif | 3689 | #endif |
| 3692 | #endif | 3690 | #endif |
| 3693 | #endif | 3691 | #endif |
| 3692 | if (xerrno == EINTR) | ||
| 3693 | { | ||
| 3694 | /* Unlike most other syscalls connect() cannot be called | ||
| 3695 | again. (That would return EALREADY.) The proper way to | ||
| 3696 | wait for completion is select(). */ | ||
| 3697 | int sc; | ||
| 3698 | SELECT_TYPE fdset; | ||
| 3699 | retry_select: | ||
| 3700 | FD_ZERO (&fdset); | ||
| 3701 | FD_SET (s, &fdset); | ||
| 3702 | QUIT; | ||
| 3703 | sc = select (s + 1, (SELECT_TYPE *)0, &fdset, (SELECT_TYPE *)0, | ||
| 3704 | (EMACS_TIME *)0); | ||
| 3705 | if (sc == -1) | ||
| 3706 | { | ||
| 3707 | if (errno == EINTR) | ||
| 3708 | goto retry_select; | ||
| 3709 | else | ||
| 3710 | report_file_error ("select failed", Qnil); | ||
| 3711 | } | ||
| 3712 | eassert (sc > 0); | ||
| 3713 | { | ||
| 3714 | int len = sizeof xerrno; | ||
| 3715 | eassert (FD_ISSET (s, &fdset)); | ||
| 3716 | if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1) | ||
| 3717 | report_file_error ("getsockopt failed", Qnil); | ||
| 3718 | if (xerrno != 0) | ||
| 3719 | errno = xerrno, report_file_error ("error during connect", Qnil); | ||
| 3720 | else | ||
| 3721 | break; | ||
| 3722 | } | ||
| 3723 | } | ||
| 3694 | 3724 | ||
| 3695 | immediate_quit = 0; | 3725 | immediate_quit = 0; |
| 3696 | 3726 | ||
| @@ -3698,9 +3728,6 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3698 | specpdl_ptr = specpdl + count1; | 3728 | specpdl_ptr = specpdl + count1; |
| 3699 | emacs_close (s); | 3729 | emacs_close (s); |
| 3700 | s = -1; | 3730 | s = -1; |
| 3701 | |||
| 3702 | if (xerrno == EINTR) | ||
| 3703 | goto retry_connect; | ||
| 3704 | } | 3731 | } |
| 3705 | 3732 | ||
| 3706 | if (s >= 0) | 3733 | if (s >= 0) |