Mercurial > vim
comparison src/os_unix.c @ 13847:fa0dcdaec6a3 v8.0.1795
patch 8.0.1795: lose contact with jobs when :gui forks
commit https://github.com/vim/vim/commit/b0b98d523036d534755bf1cf79d1595e61c3f7ce
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat May 5 21:01:00 2018 +0200
patch 8.0.1795: lose contact with jobs when :gui forks
Problem: Lose contact with jobs when :gui forks.
Solution: Don't fork when there is a running job. Make log message for a
died job clearer. Also close the terminal when stderr and stdout
are the same FD.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 05 May 2018 21:15:05 +0200 |
parents | 5f6c61a71c02 |
children | ea0e6c71ba51 |
comparison
equal
deleted
inserted
replaced
13846:8518f28bcda9 | 13847:fa0dcdaec6a3 |
---|---|
5640 { | 5640 { |
5641 int in_fd = use_file_for_in || use_null_for_in | 5641 int in_fd = use_file_for_in || use_null_for_in |
5642 ? INVALID_FD : fd_in[1] < 0 ? pty_master_fd : fd_in[1]; | 5642 ? INVALID_FD : fd_in[1] < 0 ? pty_master_fd : fd_in[1]; |
5643 int out_fd = use_file_for_out || use_null_for_out | 5643 int out_fd = use_file_for_out || use_null_for_out |
5644 ? INVALID_FD : fd_out[0] < 0 ? pty_master_fd : fd_out[0]; | 5644 ? INVALID_FD : fd_out[0] < 0 ? pty_master_fd : fd_out[0]; |
5645 /* When using pty_master_fd only set it for stdout, do not duplicate it | |
5646 * for stderr, it only needs to be read once. */ | |
5645 int err_fd = use_out_for_err || use_file_for_err || use_null_for_err | 5647 int err_fd = use_out_for_err || use_file_for_err || use_null_for_err |
5646 ? INVALID_FD : fd_err[0] < 0 ? pty_master_fd : fd_err[0]; | 5648 ? INVALID_FD : fd_err[0] < 0 ? INVALID_FD : fd_err[0]; |
5647 | 5649 |
5648 channel_set_pipes(channel, in_fd, out_fd, err_fd); | 5650 channel_set_pipes(channel, in_fd, out_fd, err_fd); |
5649 channel_set_job(channel, job, options); | 5651 channel_set_job(channel, job, options); |
5650 } | 5652 } |
5651 else | 5653 else |
5699 wait_pid = waitpid(job->jv_pid, &status, WNOHANG); | 5701 wait_pid = waitpid(job->jv_pid, &status, WNOHANG); |
5700 # endif | 5702 # endif |
5701 if (wait_pid == -1) | 5703 if (wait_pid == -1) |
5702 { | 5704 { |
5703 /* process must have exited */ | 5705 /* process must have exited */ |
5706 if (job->jv_status < JOB_ENDED) | |
5707 ch_log(job->jv_channel, "Job no longer exists: %s", | |
5708 strerror(errno)); | |
5704 goto return_dead; | 5709 goto return_dead; |
5705 } | 5710 } |
5706 if (wait_pid == 0) | 5711 if (wait_pid == 0) |
5707 return "run"; | 5712 return "run"; |
5708 if (WIFEXITED(status)) | 5713 if (WIFEXITED(status)) |
5709 { | 5714 { |
5710 /* LINTED avoid "bitwise operation on signed value" */ | 5715 /* LINTED avoid "bitwise operation on signed value" */ |
5711 job->jv_exitval = WEXITSTATUS(status); | 5716 job->jv_exitval = WEXITSTATUS(status); |
5717 if (job->jv_status < JOB_ENDED) | |
5718 ch_log(job->jv_channel, "Job exited with %d", job->jv_exitval); | |
5712 goto return_dead; | 5719 goto return_dead; |
5713 } | 5720 } |
5714 if (WIFSIGNALED(status)) | 5721 if (WIFSIGNALED(status)) |
5715 { | 5722 { |
5716 job->jv_exitval = -1; | 5723 job->jv_exitval = -1; |
5724 if (job->jv_status < JOB_ENDED) | |
5725 ch_log(job->jv_channel, "Job terminated by a signal"); | |
5717 goto return_dead; | 5726 goto return_dead; |
5718 } | 5727 } |
5719 return "run"; | 5728 return "run"; |
5720 | 5729 |
5721 return_dead: | 5730 return_dead: |
5722 if (job->jv_status < JOB_ENDED) | 5731 if (job->jv_status < JOB_ENDED) |
5723 { | |
5724 ch_log(job->jv_channel, "Job ended"); | |
5725 job->jv_status = JOB_ENDED; | 5732 job->jv_status = JOB_ENDED; |
5726 } | |
5727 return "dead"; | 5733 return "dead"; |
5728 } | 5734 } |
5729 | 5735 |
5730 job_T * | 5736 job_T * |
5731 mch_detect_ended_job(job_T *job_list) | 5737 mch_detect_ended_job(job_T *job_list) |
5855 ch_log(channel, "using pty %s on fd %d", | 5861 ch_log(channel, "using pty %s on fd %d", |
5856 job->jv_tty_out, pty_master_fd); | 5862 job->jv_tty_out, pty_master_fd); |
5857 job->jv_channel = channel; /* ch_refcount was set by add_channel() */ | 5863 job->jv_channel = channel; /* ch_refcount was set by add_channel() */ |
5858 channel->ch_keep_open = TRUE; | 5864 channel->ch_keep_open = TRUE; |
5859 | 5865 |
5860 channel_set_pipes(channel, pty_master_fd, pty_master_fd, pty_master_fd); | 5866 /* Only set the pty_master_fd for stdout, do not duplicate it for stderr, |
5867 * it only needs to be read once. */ | |
5868 channel_set_pipes(channel, pty_master_fd, pty_master_fd, INVALID_FD); | |
5861 channel_set_job(channel, job, options); | 5869 channel_set_job(channel, job, options); |
5862 return OK; | 5870 return OK; |
5863 } | 5871 } |
5864 #endif | 5872 #endif |
5865 | 5873 |