diff options
| author | Paul Eggert | 2019-01-15 23:51:45 -0800 |
|---|---|---|
| committer | Paul Eggert | 2019-01-15 23:52:47 -0800 |
| commit | e87e6a24c49542111e669b7d0f1a412024663f8e (patch) | |
| tree | ba382d326874795c7b131a7995c67e660650a80c /src/process.c | |
| parent | 6b9fa8804533a695094a930d634d2d6617e2b6c7 (diff) | |
| download | emacs-e87e6a24c49542111e669b7d0f1a412024663f8e.tar.gz emacs-e87e6a24c49542111e669b7d0f1a412024663f8e.zip | |
Fix unlikely races with GnuTLS, datagrams
Retry some calls if interrupted at inopportune times.
These were found by code inspection.
* src/gnutls.c (gnutls_try_handshake): Simplify by using
new emacs_gnutls_handle_error API.
(emacs_gnutls_write): Remove GNUTLS_E_AGAIN hack since
emacs_gnutls_handle_error now does that.
Use emacs_gnutls_handle_error only on errors.
(emacs_gnutls_read): Retry if gnutls_record_recv returns
GNUTLS_E_INTERRUPTED, to be consistent with emacs_read.
(emacs_gnutls_handle_error): Return 0 on fatal errors,
-1 (setting errno) on ordinary errors, to simplify callers.
Assume that ERR is negative, since it always is now.
Map non-fatal GnuTLS errors to errno values as best we can.
* src/process.c (read_process_output) [DATAGRAM_SOCKETS]:
Retry recvfrom if it is interrupted, to be consistent with
how things are handled when not a datagram channel.
(send_process) [DATAGRAM_SOCEKTS]: If sendto is interrupted,
process pending signals and retry it, to be consistent with
how things are handled when not a datagram channel.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/src/process.c b/src/process.c index 06555bac4c0..c0741403b57 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -5840,7 +5840,8 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars, | |||
| 5840 | 5840 | ||
| 5841 | /* Read pending output from the process channel, | 5841 | /* Read pending output from the process channel, |
| 5842 | starting with our buffered-ahead character if we have one. | 5842 | starting with our buffered-ahead character if we have one. |
| 5843 | Yield number of decoded characters read. | 5843 | Yield number of decoded characters read, |
| 5844 | or -1 (setting errno) if there is a read error. | ||
| 5844 | 5845 | ||
| 5845 | This function reads at most 4096 characters. | 5846 | This function reads at most 4096 characters. |
| 5846 | If you want to read all available subprocess output, | 5847 | If you want to read all available subprocess output, |
| @@ -5870,8 +5871,10 @@ read_process_output (Lisp_Object proc, int channel) | |||
| 5870 | if (DATAGRAM_CHAN_P (channel)) | 5871 | if (DATAGRAM_CHAN_P (channel)) |
| 5871 | { | 5872 | { |
| 5872 | socklen_t len = datagram_address[channel].len; | 5873 | socklen_t len = datagram_address[channel].len; |
| 5873 | nbytes = recvfrom (channel, chars + carryover, readmax, | 5874 | do |
| 5874 | 0, datagram_address[channel].sa, &len); | 5875 | nbytes = recvfrom (channel, chars + carryover, readmax, |
| 5876 | 0, datagram_address[channel].sa, &len); | ||
| 5877 | while (nbytes < 0 && errno == EINTR); | ||
| 5875 | } | 5878 | } |
| 5876 | else | 5879 | else |
| 5877 | #endif | 5880 | #endif |
| @@ -5921,8 +5924,6 @@ read_process_output (Lisp_Object proc, int channel) | |||
| 5921 | 5924 | ||
| 5922 | p->decoding_carryover = 0; | 5925 | p->decoding_carryover = 0; |
| 5923 | 5926 | ||
| 5924 | /* At this point, NBYTES holds number of bytes just received | ||
| 5925 | (including the one in proc_buffered_char[channel]). */ | ||
| 5926 | if (nbytes <= 0) | 5927 | if (nbytes <= 0) |
| 5927 | { | 5928 | { |
| 5928 | if (nbytes < 0 || coding->mode & CODING_MODE_LAST_BLOCK) | 5929 | if (nbytes < 0 || coding->mode & CODING_MODE_LAST_BLOCK) |
| @@ -5930,6 +5931,9 @@ read_process_output (Lisp_Object proc, int channel) | |||
| 5930 | coding->mode |= CODING_MODE_LAST_BLOCK; | 5931 | coding->mode |= CODING_MODE_LAST_BLOCK; |
| 5931 | } | 5932 | } |
| 5932 | 5933 | ||
| 5934 | /* At this point, NBYTES holds number of bytes just received | ||
| 5935 | (including the one in proc_buffered_char[channel]). */ | ||
| 5936 | |||
| 5933 | /* Ignore carryover, it's been added by a previous iteration already. */ | 5937 | /* Ignore carryover, it's been added by a previous iteration already. */ |
| 5934 | p->nbytes_read += nbytes; | 5938 | p->nbytes_read += nbytes; |
| 5935 | 5939 | ||
| @@ -6372,9 +6376,17 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len, | |||
| 6372 | #ifdef DATAGRAM_SOCKETS | 6376 | #ifdef DATAGRAM_SOCKETS |
| 6373 | if (DATAGRAM_CHAN_P (outfd)) | 6377 | if (DATAGRAM_CHAN_P (outfd)) |
| 6374 | { | 6378 | { |
| 6375 | rv = sendto (outfd, cur_buf, cur_len, | 6379 | while (true) |
| 6376 | 0, datagram_address[outfd].sa, | 6380 | { |
| 6377 | datagram_address[outfd].len); | 6381 | rv = sendto (outfd, cur_buf, cur_len, 0, |
| 6382 | datagram_address[outfd].sa, | ||
| 6383 | datagram_address[outfd].len); | ||
| 6384 | if (! (rv < 0 && errno == EINTR)) | ||
| 6385 | break; | ||
| 6386 | if (pending_signals) | ||
| 6387 | process_pending_signals (); | ||
| 6388 | } | ||
| 6389 | |||
| 6378 | if (rv >= 0) | 6390 | if (rv >= 0) |
| 6379 | written = rv; | 6391 | written = rv; |
| 6380 | else if (errno == EMSGSIZE) | 6392 | else if (errno == EMSGSIZE) |