comparison src/channel.c @ 13778:5f6c61a71c02 v8.0.1761

patch 8.0.1761: job in terminal window with no output channel is killed commit https://github.com/vim/vim/commit/4e9d443a25b451e3f2de62e9eeea439aa4c3f039 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 24 20:54:07 2018 +0200 patch 8.0.1761: job in terminal window with no output channel is killed Problem: Job in terminal window with no output channel is killed. Solution: Keep the job running when the input is a tty. (Ozaki Kiichi, closes #2734)
author Christian Brabandt <cb@256bit.org>
date Tue, 24 Apr 2018 21:00:07 +0200
parents 3ab6198c1f9a
children c01864ecf233
comparison
equal deleted inserted replaced
13777:bdecc420bd2c 13778:5f6c61a71c02
343 || channel->ch_part[PART_ERR].ch_bufref.br_buf != NULL) 343 || channel->ch_part[PART_ERR].ch_bufref.br_buf != NULL)
344 && has_err_msg); 344 && has_err_msg);
345 } 345 }
346 346
347 /* 347 /*
348 * Return TRUE if "channel" is closeable (i.e. all readable fds are closed).
349 */
350 static int
351 channel_can_close(channel_T *channel)
352 {
353 return channel->ch_to_be_closed == 0;
354 }
355
356 /*
348 * Close a channel and free all its resources. 357 * Close a channel and free all its resources.
349 */ 358 */
350 static void 359 static void
351 channel_free_contents(channel_T *channel) 360 channel_free_contents(channel_T *channel)
352 { 361 {
890 899
891 channel->CH_SOCK_FD = (sock_T)sd; 900 channel->CH_SOCK_FD = (sock_T)sd;
892 channel->ch_nb_close_cb = nb_close_cb; 901 channel->ch_nb_close_cb = nb_close_cb;
893 channel->ch_hostname = (char *)vim_strsave((char_u *)hostname); 902 channel->ch_hostname = (char *)vim_strsave((char_u *)hostname);
894 channel->ch_port = port_in; 903 channel->ch_port = port_in;
895 channel->ch_to_be_closed |= (1 << PART_SOCK); 904 channel->ch_to_be_closed |= (1U << PART_SOCK);
896 905
897 #ifdef FEAT_GUI 906 #ifdef FEAT_GUI
898 channel_gui_register_one(channel, PART_SOCK); 907 channel_gui_register_one(channel, PART_SOCK);
899 #endif 908 #endif
900 909
986 fd_close(*fd); 995 fd_close(*fd);
987 } 996 }
988 } 997 }
989 *fd = INVALID_FD; 998 *fd = INVALID_FD;
990 999
991 channel->ch_to_be_closed &= ~(1 << part); 1000 /* channel is closed, may want to end the job if it was the last */
1001 channel->ch_to_be_closed &= ~(1U << part);
992 } 1002 }
993 } 1003 }
994 1004
995 void 1005 void
996 channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err) 1006 channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err)
997 { 1007 {
998 if (in != INVALID_FD) 1008 if (in != INVALID_FD)
999 { 1009 {
1000 ch_close_part(channel, PART_IN); 1010 ch_close_part(channel, PART_IN);
1001 channel->CH_IN_FD = in; 1011 channel->CH_IN_FD = in;
1012 # if defined(UNIX)
1013 /* Do not end the job when all output channels are closed, wait until
1014 * the job ended. */
1015 if (isatty(in))
1016 channel->ch_to_be_closed |= (1U << PART_IN);
1017 # endif
1002 } 1018 }
1003 if (out != INVALID_FD) 1019 if (out != INVALID_FD)
1004 { 1020 {
1005 # if defined(FEAT_GUI) 1021 # if defined(FEAT_GUI)
1006 channel_gui_unregister_one(channel, PART_OUT); 1022 channel_gui_unregister_one(channel, PART_OUT);
1007 # endif 1023 # endif
1008 ch_close_part(channel, PART_OUT); 1024 ch_close_part(channel, PART_OUT);
1009 channel->CH_OUT_FD = out; 1025 channel->CH_OUT_FD = out;
1010 channel->ch_to_be_closed |= (1 << PART_OUT); 1026 channel->ch_to_be_closed |= (1U << PART_OUT);
1011 # if defined(FEAT_GUI) 1027 # if defined(FEAT_GUI)
1012 channel_gui_register_one(channel, PART_OUT); 1028 channel_gui_register_one(channel, PART_OUT);
1013 # endif 1029 # endif
1014 } 1030 }
1015 if (err != INVALID_FD) 1031 if (err != INVALID_FD)
1017 # if defined(FEAT_GUI) 1033 # if defined(FEAT_GUI)
1018 channel_gui_unregister_one(channel, PART_ERR); 1034 channel_gui_unregister_one(channel, PART_ERR);
1019 # endif 1035 # endif
1020 ch_close_part(channel, PART_ERR); 1036 ch_close_part(channel, PART_ERR);
1021 channel->CH_ERR_FD = err; 1037 channel->CH_ERR_FD = err;
1022 channel->ch_to_be_closed |= (1 << PART_ERR); 1038 channel->ch_to_be_closed |= (1U << PART_ERR);
1023 # if defined(FEAT_GUI) 1039 # if defined(FEAT_GUI)
1024 channel_gui_register_one(channel, PART_ERR); 1040 channel_gui_register_one(channel, PART_ERR);
1025 # endif 1041 # endif
1026 } 1042 }
1027 } 1043 }
4198 ch_log(NULL, "looking for messages on channels"); 4214 ch_log(NULL, "looking for messages on channels");
4199 did_log_msg = FALSE; 4215 did_log_msg = FALSE;
4200 } 4216 }
4201 while (channel != NULL) 4217 while (channel != NULL)
4202 { 4218 {
4203 if (channel->ch_to_be_closed == 0) 4219 if (channel_can_close(channel))
4204 { 4220 {
4205 channel->ch_to_be_closed = (1 << PART_COUNT); 4221 channel->ch_to_be_closed = (1U << PART_COUNT);
4206 channel_close_now(channel); 4222 channel_close_now(channel);
4207 /* channel may have been freed, start over */ 4223 /* channel may have been freed, start over */
4208 channel = first_channel; 4224 channel = first_channel;
4209 continue; 4225 continue;
4210 } 4226 }
5078 { 5094 {
5079 return job->jv_channel != NULL && channel_still_useful(job->jv_channel); 5095 return job->jv_channel != NULL && channel_still_useful(job->jv_channel);
5080 } 5096 }
5081 5097
5082 /* 5098 /*
5099 * Return TRUE if the channel of "job" is closeable.
5100 */
5101 static int
5102 job_channel_can_close(job_T *job)
5103 {
5104 return job->jv_channel != NULL && channel_can_close(job->jv_channel);
5105 }
5106
5107 /*
5083 * Return TRUE if the job should not be freed yet. Do not free the job when 5108 * Return TRUE if the job should not be freed yet. Do not free the job when
5084 * it has not ended yet and there is a "stoponexit" flag, an exit callback 5109 * it has not ended yet and there is a "stoponexit" flag, an exit callback
5085 * or when the associated channel will do something with the job output. 5110 * or when the associated channel will do something with the job output.
5086 */ 5111 */
5087 static int 5112 static int
5207 return; 5232 return;
5208 5233
5209 /* Ready to cleanup the job. */ 5234 /* Ready to cleanup the job. */
5210 job->jv_status = JOB_FINISHED; 5235 job->jv_status = JOB_FINISHED;
5211 5236
5237 /* When only channel-in is kept open, close explicitly. */
5238 if (job->jv_channel != NULL)
5239 ch_close_part(job->jv_channel, PART_IN);
5240
5212 if (job->jv_exit_cb != NULL) 5241 if (job->jv_exit_cb != NULL)
5213 { 5242 {
5214 typval_T argv[3]; 5243 typval_T argv[3];
5215 typval_T rettv; 5244 typval_T rettv;
5216 int dummy; 5245 int dummy;
5411 job_T *job; 5440 job_T *job;
5412 5441
5413 for (job = first_job; job != NULL; job = job->jv_next) 5442 for (job = first_job; job != NULL; job = job->jv_next)
5414 /* Only should check if the channel has been closed, if the channel is 5443 /* Only should check if the channel has been closed, if the channel is
5415 * open the job won't exit. */ 5444 * open the job won't exit. */
5416 if (job->jv_status == JOB_STARTED && job->jv_exit_cb != NULL 5445 if ((job->jv_status == JOB_STARTED && !job_channel_still_useful(job))
5417 && !job_channel_still_useful(job)) 5446 || (job->jv_status == JOB_FINISHED
5447 && job_channel_can_close(job)))
5418 return TRUE; 5448 return TRUE;
5419 return FALSE; 5449 return FALSE;
5420 } 5450 }
5421 5451
5422 #define MAX_CHECK_ENDED 8 5452 #define MAX_CHECK_ENDED 8