aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorPaul Eggert2019-01-15 23:51:45 -0800
committerPaul Eggert2019-01-15 23:52:47 -0800
commite87e6a24c49542111e669b7d0f1a412024663f8e (patch)
treeba382d326874795c7b131a7995c67e660650a80c /src/process.c
parent6b9fa8804533a695094a930d634d2d6617e2b6c7 (diff)
downloademacs-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.c28
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)