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