diff options
Diffstat (limited to 'src')
| -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 077385d6f6c..f3bbfe05dac 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-11-04 Kenichi Handa <handa@m17n.org> | 6 | 2010-11-04 Kenichi Handa <handa@m17n.org> |
| 2 | 7 | ||
| 3 | * font.c (font_delete_unmatched): Check Vface_ignored_fonts. | 8 | * font.c (font_delete_unmatched): Check Vface_ignored_fonts. |
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) |