diff options
| author | Paul Eggert | 2015-04-25 16:16:58 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-04-25 16:17:50 -0700 |
| commit | 2c1b8604946efbcd8ec5dd6c6dda7541ce4fc3c0 (patch) | |
| tree | 41a33e3d526047d2ebe06cabb317e43681274e1f /src | |
| parent | 45e571035bffc0db059b1d686830da89df3d2d48 (diff) | |
| download | emacs-2c1b8604946efbcd8ec5dd6c6dda7541ce4fc3c0.tar.gz emacs-2c1b8604946efbcd8ec5dd6c6dda7541ce4fc3c0.zip | |
Don't freeze with unreadable processes
Don't freeze if an exiting process can't be read from. (Bug#19860).
This fixes a bug I introduced in
2014-07-08T07:24:07Z@eggert@cs.ucla.edu
"* process.c: Add sanity checks for file descriptors."
Dmitry Gutov did most of the legwork in finding the problem.
* src/process.c (wait_reading_process_output):
Treat non-running processes that can't be read from
the same as other non-running processes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/process.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/process.c b/src/process.c index c7455072962..3e04cb76387 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -4785,37 +4785,41 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4785 | if (wait_proc && wait_proc->raw_status_new) | 4785 | if (wait_proc && wait_proc->raw_status_new) |
| 4786 | update_status (wait_proc); | 4786 | update_status (wait_proc); |
| 4787 | if (wait_proc | 4787 | if (wait_proc |
| 4788 | && wait_proc->infd >= 0 | ||
| 4789 | && ! EQ (wait_proc->status, Qrun) | 4788 | && ! EQ (wait_proc->status, Qrun) |
| 4790 | && ! EQ (wait_proc->status, Qconnect)) | 4789 | && ! EQ (wait_proc->status, Qconnect)) |
| 4791 | { | 4790 | { |
| 4792 | bool read_some_bytes = false; | 4791 | bool read_some_bytes = false; |
| 4793 | 4792 | ||
| 4794 | clear_waiting_for_input (); | 4793 | clear_waiting_for_input (); |
| 4795 | XSETPROCESS (proc, wait_proc); | ||
| 4796 | 4794 | ||
| 4797 | /* Read data from the process, until we exhaust it. */ | 4795 | /* If data can be read from the process, do so until exhausted. */ |
| 4798 | while (true) | 4796 | if (wait_proc->infd >= 0) |
| 4799 | { | 4797 | { |
| 4800 | int nread = read_process_output (proc, wait_proc->infd); | 4798 | XSETPROCESS (proc, wait_proc); |
| 4801 | if (nread < 0) | 4799 | |
| 4800 | while (true) | ||
| 4802 | { | 4801 | { |
| 4803 | if (errno == EIO || errno == EAGAIN) | 4802 | int nread = read_process_output (proc, wait_proc->infd); |
| 4804 | break; | 4803 | if (nread < 0) |
| 4804 | { | ||
| 4805 | if (errno == EIO || errno == EAGAIN) | ||
| 4806 | break; | ||
| 4805 | #ifdef EWOULDBLOCK | 4807 | #ifdef EWOULDBLOCK |
| 4806 | if (errno == EWOULDBLOCK) | 4808 | if (errno == EWOULDBLOCK) |
| 4807 | break; | 4809 | break; |
| 4808 | #endif | 4810 | #endif |
| 4809 | } | 4811 | } |
| 4810 | else | 4812 | else |
| 4811 | { | 4813 | { |
| 4812 | if (got_some_input < nread) | 4814 | if (got_some_input < nread) |
| 4813 | got_some_input = nread; | 4815 | got_some_input = nread; |
| 4814 | if (nread == 0) | 4816 | if (nread == 0) |
| 4815 | break; | 4817 | break; |
| 4816 | read_some_bytes = true; | 4818 | read_some_bytes = true; |
| 4819 | } | ||
| 4817 | } | 4820 | } |
| 4818 | } | 4821 | } |
| 4822 | |||
| 4819 | if (read_some_bytes && do_display) | 4823 | if (read_some_bytes && do_display) |
| 4820 | redisplay_preserve_echo_area (10); | 4824 | redisplay_preserve_echo_area (10); |
| 4821 | 4825 | ||