Mercurial > vim
diff src/channel.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 | c01864ecf233 |
children | 3e5c24ecc313 |
line wrap: on
line diff
--- a/src/channel.c +++ b/src/channel.c @@ -485,7 +485,7 @@ channel_read_fd(int fd) */ #ifdef FEAT_GUI_X11 static void -messageFromServer(XtPointer clientData, +messageFromServerX11(XtPointer clientData, int *unused1 UNUSED, XtInputId *unused2 UNUSED) { @@ -496,7 +496,7 @@ messageFromServer(XtPointer clientData, #ifdef FEAT_GUI_GTK # if GTK_CHECK_VERSION(3,0,0) static gboolean -messageFromServer(GIOChannel *unused1 UNUSED, +messageFromServerGtk3(GIOChannel *unused1 UNUSED, GIOCondition unused2 UNUSED, gpointer clientData) { @@ -506,7 +506,7 @@ messageFromServer(GIOChannel *unused1 UN } # else static void -messageFromServer(gpointer clientData, +messageFromServerGtk2(gpointer clientData, gint unused1 UNUSED, GdkInputCondition unused2 UNUSED) { @@ -526,41 +526,48 @@ channel_gui_register_one(channel_T *chan return; # ifdef FEAT_GUI_X11 - /* Tell notifier we are interested in being called - * when there is input on the editor connection socket. */ + /* Tell notifier we are interested in being called when there is input on + * the editor connection socket. */ if (channel->ch_part[part].ch_inputHandler == (XtInputId)NULL) + { + ch_log(channel, "Registering part %s with fd %d", + part_names[part], channel->ch_part[part].ch_fd); + channel->ch_part[part].ch_inputHandler = XtAppAddInput( (XtAppContext)app_context, channel->ch_part[part].ch_fd, (XtPointer)(XtInputReadMask + XtInputExceptMask), - messageFromServer, + messageFromServerX11, (XtPointer)(long)channel->ch_part[part].ch_fd); + } # else # ifdef FEAT_GUI_GTK - /* Tell gdk we are interested in being called when there - * is input on the editor connection socket. */ + /* Tell gdk we are interested in being called when there is input on the + * editor connection socket. */ if (channel->ch_part[part].ch_inputHandler == 0) + { + ch_log(channel, "Registering part %s with fd %d", + part_names[part], channel->ch_part[part].ch_fd); # if GTK_CHECK_VERSION(3,0,0) - { GIOChannel *chnnl = g_io_channel_unix_new( (gint)channel->ch_part[part].ch_fd); channel->ch_part[part].ch_inputHandler = g_io_add_watch( chnnl, G_IO_IN|G_IO_HUP|G_IO_ERR|G_IO_PRI, - messageFromServer, + messageFromServerGtk3, GINT_TO_POINTER(channel->ch_part[part].ch_fd)); g_io_channel_unref(chnnl); - } # else channel->ch_part[part].ch_inputHandler = gdk_input_add( (gint)channel->ch_part[part].ch_fd, (GdkInputCondition) ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION), - messageFromServer, + messageFromServerGtk2, (gpointer)(long)channel->ch_part[part].ch_fd); # endif + } # endif # endif } @@ -598,6 +605,7 @@ channel_gui_unregister_one(channel_T *ch # ifdef FEAT_GUI_X11 if (channel->ch_part[part].ch_inputHandler != (XtInputId)NULL) { + ch_log(channel, "Unregistering part %s", part_names[part]); XtRemoveInput(channel->ch_part[part].ch_inputHandler); channel->ch_part[part].ch_inputHandler = (XtInputId)NULL; } @@ -605,6 +613,7 @@ channel_gui_unregister_one(channel_T *ch # ifdef FEAT_GUI_GTK if (channel->ch_part[part].ch_inputHandler != 0) { + ch_log(channel, "Unregistering part %s", part_names[part]); # if GTK_CHECK_VERSION(3,0,0) g_source_remove(channel->ch_part[part].ch_inputHandler); # else @@ -3245,7 +3254,16 @@ ch_close_part_on_error( (int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT "); /* When reading is not possible close this part of the channel. Don't - * close the channel yet, there may be something to read on another part. */ + * close the channel yet, there may be something to read on another part. + * When stdout and stderr use the same FD we get the error only on one of + * them, also close the other. */ + if (part == PART_OUT || part == PART_ERR) + { + ch_part_T other = part == PART_OUT ? PART_ERR : PART_OUT; + + if (channel->ch_part[part].ch_fd == channel->ch_part[other].ch_fd) + ch_close_part(channel, other); + } ch_close_part(channel, part); #ifdef FEAT_GUI @@ -5115,6 +5133,22 @@ job_still_useful(job_T *job) return job_need_end_check(job) || job_channel_still_useful(job); } +#if defined(GUI_MAY_FORK) || defined(PROTO) +/* + * Return TRUE when there is any running job that we care about. + */ + int +job_any_running() +{ + job_T *job; + + for (job = first_job; job != NULL; job = job->jv_next) + if (job_still_useful(job)) + return TRUE; + return FALSE; +} +#endif + #if !defined(USE_ARGV) || defined(PROTO) /* * Escape one argument for an external command.