1
0
forked from aniani/vim

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.
This commit is contained in:
Bram Moolenaar
2018-05-05 21:01:00 +02:00
parent b833c1ef7b
commit b0b98d5230
7 changed files with 79 additions and 29 deletions

View File

@@ -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 UNUSED,
}
# 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 *channel, ch_part_T part)
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)
# if GTK_CHECK_VERSION(3,0,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 *channel, ch_part_T part)
# 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 *channel, ch_part_T part)
# 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.