diff options
| author | Andrea Corallo | 2020-08-09 15:03:23 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-08-09 15:03:23 +0200 |
| commit | 12a982d9789052d8e85efcacb4b311f4876c882a (patch) | |
| tree | a452a8e888c6ee9c85d6a487359b7a1c0c9fa15b /src/process.c | |
| parent | 80d7f710f2fab902e46aa3fddb8e1c1795420af3 (diff) | |
| parent | 8e82baf5a730ff542118ddba5b76afdc1db643f6 (diff) | |
| download | emacs-12a982d9789052d8e85efcacb4b311f4876c882a.tar.gz emacs-12a982d9789052d8e85efcacb4b311f4876c882a.zip | |
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 97 |
1 files changed, 46 insertions, 51 deletions
diff --git a/src/process.c b/src/process.c index 6e5bcf307ab..15634e4a8b0 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -5491,6 +5491,10 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5491 | } | 5491 | } |
| 5492 | else | 5492 | else |
| 5493 | { | 5493 | { |
| 5494 | #ifdef HAVE_GNUTLS | ||
| 5495 | int tls_nfds; | ||
| 5496 | fd_set tls_available; | ||
| 5497 | #endif | ||
| 5494 | /* Set the timeout for adaptive read buffering if any | 5498 | /* Set the timeout for adaptive read buffering if any |
| 5495 | process has non-zero read_output_skip and non-zero | 5499 | process has non-zero read_output_skip and non-zero |
| 5496 | read_output_delay, and we are not reading output for a | 5500 | read_output_delay, and we are not reading output for a |
| @@ -5560,7 +5564,36 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5560 | } | 5564 | } |
| 5561 | #endif | 5565 | #endif |
| 5562 | 5566 | ||
| 5563 | /* Non-macOS HAVE_GLIB builds call thread_select in xgselect.c. */ | 5567 | #ifdef HAVE_GNUTLS |
| 5568 | /* GnuTLS buffers data internally. We need to check if some | ||
| 5569 | data is available in the buffers manually before the select. | ||
| 5570 | And if so, we need to skip the select which could block. */ | ||
| 5571 | FD_ZERO (&tls_available); | ||
| 5572 | tls_nfds = 0; | ||
| 5573 | for (channel = 0; channel < FD_SETSIZE; ++channel) | ||
| 5574 | if (! NILP (chan_process[channel]) | ||
| 5575 | && FD_ISSET (channel, &Available)) | ||
| 5576 | { | ||
| 5577 | struct Lisp_Process *p = XPROCESS (chan_process[channel]); | ||
| 5578 | if (p | ||
| 5579 | && p->gnutls_p && p->gnutls_state | ||
| 5580 | && emacs_gnutls_record_check_pending (p->gnutls_state) > 0) | ||
| 5581 | { | ||
| 5582 | tls_nfds++; | ||
| 5583 | eassert (p->infd == channel); | ||
| 5584 | FD_SET (p->infd, &tls_available); | ||
| 5585 | } | ||
| 5586 | } | ||
| 5587 | /* If wait_proc is somebody else, we have to wait in select | ||
| 5588 | as usual. Otherwise, clobber the timeout. */ | ||
| 5589 | if (tls_nfds > 0 | ||
| 5590 | && (!wait_proc || | ||
| 5591 | (wait_proc->infd >= 0 | ||
| 5592 | && FD_ISSET (wait_proc->infd, &tls_available)))) | ||
| 5593 | timeout = make_timespec (0, 0); | ||
| 5594 | #endif | ||
| 5595 | |||
| 5596 | /* Non-macOS HAVE_GLIB builds call thread_select in xgselect.c. */ | ||
| 5564 | #if defined HAVE_GLIB && !defined HAVE_NS | 5597 | #if defined HAVE_GLIB && !defined HAVE_NS |
| 5565 | nfds = xg_select (max_desc + 1, | 5598 | nfds = xg_select (max_desc + 1, |
| 5566 | &Available, (check_write ? &Writeok : 0), | 5599 | &Available, (check_write ? &Writeok : 0), |
| @@ -5578,59 +5611,21 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5578 | #endif /* !HAVE_GLIB */ | 5611 | #endif /* !HAVE_GLIB */ |
| 5579 | 5612 | ||
| 5580 | #ifdef HAVE_GNUTLS | 5613 | #ifdef HAVE_GNUTLS |
| 5581 | /* GnuTLS buffers data internally. In lowat mode it leaves | 5614 | /* Merge tls_available into Available. */ |
| 5582 | some data in the TCP buffers so that select works, but | 5615 | if (tls_nfds > 0) |
| 5583 | with custom pull/push functions we need to check if some | ||
| 5584 | data is available in the buffers manually. */ | ||
| 5585 | if (nfds == 0) | ||
| 5586 | { | 5616 | { |
| 5587 | fd_set tls_available; | 5617 | if (nfds == 0 || (nfds < 0 && errno == EINTR)) |
| 5588 | int set = 0; | ||
| 5589 | |||
| 5590 | FD_ZERO (&tls_available); | ||
| 5591 | if (! wait_proc) | ||
| 5592 | { | 5618 | { |
| 5593 | /* We're not waiting on a specific process, so loop | 5619 | /* Fast path, just copy. */ |
| 5594 | through all the channels and check for data. | 5620 | nfds = tls_nfds; |
| 5595 | This is a workaround needed for some versions of | 5621 | Available = tls_available; |
| 5596 | the gnutls library -- 2.12.14 has been confirmed | ||
| 5597 | to need it. */ | ||
| 5598 | for (channel = 0; channel < FD_SETSIZE; ++channel) | ||
| 5599 | if (! NILP (chan_process[channel])) | ||
| 5600 | { | ||
| 5601 | struct Lisp_Process *p = | ||
| 5602 | XPROCESS (chan_process[channel]); | ||
| 5603 | if (p && p->gnutls_p && p->gnutls_state | ||
| 5604 | && ((emacs_gnutls_record_check_pending | ||
| 5605 | (p->gnutls_state)) | ||
| 5606 | > 0)) | ||
| 5607 | { | ||
| 5608 | nfds++; | ||
| 5609 | eassert (p->infd == channel); | ||
| 5610 | FD_SET (p->infd, &tls_available); | ||
| 5611 | set++; | ||
| 5612 | } | ||
| 5613 | } | ||
| 5614 | } | ||
| 5615 | else | ||
| 5616 | { | ||
| 5617 | /* Check this specific channel. */ | ||
| 5618 | if (wait_proc->gnutls_p /* Check for valid process. */ | ||
| 5619 | && wait_proc->gnutls_state | ||
| 5620 | /* Do we have pending data? */ | ||
| 5621 | && ((emacs_gnutls_record_check_pending | ||
| 5622 | (wait_proc->gnutls_state)) | ||
| 5623 | > 0)) | ||
| 5624 | { | ||
| 5625 | nfds = 1; | ||
| 5626 | eassert (0 <= wait_proc->infd); | ||
| 5627 | /* Set to Available. */ | ||
| 5628 | FD_SET (wait_proc->infd, &tls_available); | ||
| 5629 | set++; | ||
| 5630 | } | ||
| 5631 | } | 5622 | } |
| 5632 | if (set) | 5623 | else if (nfds > 0) |
| 5633 | Available = tls_available; | 5624 | /* Slow path, merge one by one. Note: nfds does not need |
| 5625 | to be accurate, just positive is enough. */ | ||
| 5626 | for (channel = 0; channel < FD_SETSIZE; ++channel) | ||
| 5627 | if (FD_ISSET(channel, &tls_available)) | ||
| 5628 | FD_SET(channel, &Available); | ||
| 5634 | } | 5629 | } |
| 5635 | #endif | 5630 | #endif |
| 5636 | } | 5631 | } |