|
Karsten Hopp |
83c5f2 |
To: vim_dev@googlegroups.com
|
|
Karsten Hopp |
83c5f2 |
Subject: Patch 7.3.315
|
|
Karsten Hopp |
83c5f2 |
Fcc: outbox
|
|
Karsten Hopp |
83c5f2 |
From: Bram Moolenaar <Bram@moolenaar.net>
|
|
Karsten Hopp |
83c5f2 |
Mime-Version: 1.0
|
|
Karsten Hopp |
83c5f2 |
Content-Type: text/plain; charset=UTF-8
|
|
Karsten Hopp |
83c5f2 |
Content-Transfer-Encoding: 8bit
|
|
Karsten Hopp |
83c5f2 |
------------
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
Patch 7.3.315
|
|
Karsten Hopp |
83c5f2 |
Problem: Opening a window before forking causes problems for GTK.
|
|
Karsten Hopp |
83c5f2 |
Solution: Fork first, create the window in the child and report back to the
|
|
Karsten Hopp |
83c5f2 |
parent process whether it worked. If successful the parent exits,
|
|
Karsten Hopp |
83c5f2 |
if unsuccessful the child exits and the parent continues in the
|
|
Karsten Hopp |
83c5f2 |
terminal. (Tim Starling)
|
|
Karsten Hopp |
83c5f2 |
Files: src/gui.c
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
*** ../vim-7.3.314/src/gui.c 2011-08-10 17:44:41.000000000 +0200
|
|
Karsten Hopp |
83c5f2 |
--- src/gui.c 2011-09-14 17:34:30.000000000 +0200
|
|
Karsten Hopp |
83c5f2 |
***************
|
|
Karsten Hopp |
83c5f2 |
*** 37,42 ****
|
|
Karsten Hopp |
83c5f2 |
--- 37,60 ----
|
|
Karsten Hopp |
83c5f2 |
static void gui_set_bg_color __ARGS((char_u *name));
|
|
Karsten Hopp |
83c5f2 |
static win_T *xy2win __ARGS((int x, int y));
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
+ #if defined(UNIX) && !defined(__BEOS__) && !defined(MACOS_X) \
|
|
Karsten Hopp |
83c5f2 |
+ && !defined(__APPLE__)
|
|
Karsten Hopp |
83c5f2 |
+ # define MAY_FORK
|
|
Karsten Hopp |
83c5f2 |
+ static void gui_do_fork __ARGS((void));
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ static int gui_read_child_pipe __ARGS((int fd));
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ /* Return values for gui_read_child_pipe */
|
|
Karsten Hopp |
83c5f2 |
+ enum {
|
|
Karsten Hopp |
83c5f2 |
+ GUI_CHILD_IO_ERROR,
|
|
Karsten Hopp |
83c5f2 |
+ GUI_CHILD_OK,
|
|
Karsten Hopp |
83c5f2 |
+ GUI_CHILD_FAILED
|
|
Karsten Hopp |
83c5f2 |
+ };
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ #endif /* MAY_FORK */
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ static void gui_attempt_start __ARGS((void));
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
static int can_update_cursor = TRUE; /* can display the cursor */
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
/*
|
|
Karsten Hopp |
83c5f2 |
***************
|
|
Karsten Hopp |
83c5f2 |
*** 59,105 ****
|
|
Karsten Hopp |
83c5f2 |
gui_start()
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
char_u *old_term;
|
|
Karsten Hopp |
83c5f2 |
- #if defined(UNIX) && !defined(__BEOS__) && !defined(MACOS_X) \
|
|
Karsten Hopp |
83c5f2 |
- && !defined(__APPLE__)
|
|
Karsten Hopp |
83c5f2 |
- # define MAY_FORK
|
|
Karsten Hopp |
83c5f2 |
- int dofork = TRUE;
|
|
Karsten Hopp |
83c5f2 |
- #endif
|
|
Karsten Hopp |
83c5f2 |
static int recursive = 0;
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
old_term = vim_strsave(T_NAME);
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
- /*
|
|
Karsten Hopp |
83c5f2 |
- * Set_termname() will call gui_init() to start the GUI.
|
|
Karsten Hopp |
83c5f2 |
- * Set the "starting" flag, to indicate that the GUI will start.
|
|
Karsten Hopp |
83c5f2 |
- *
|
|
Karsten Hopp |
83c5f2 |
- * We don't want to open the GUI shell until after we've read .gvimrc,
|
|
Karsten Hopp |
83c5f2 |
- * otherwise we don't know what font we will use, and hence we don't know
|
|
Karsten Hopp |
83c5f2 |
- * what size the shell should be. So if there are errors in the .gvimrc
|
|
Karsten Hopp |
83c5f2 |
- * file, they will have to go to the terminal: Set full_screen to FALSE.
|
|
Karsten Hopp |
83c5f2 |
- * full_screen will be set to TRUE again by a successful termcapinit().
|
|
Karsten Hopp |
83c5f2 |
- */
|
|
Karsten Hopp |
83c5f2 |
settmode(TMODE_COOK); /* stop RAW mode */
|
|
Karsten Hopp |
83c5f2 |
if (full_screen)
|
|
Karsten Hopp |
83c5f2 |
cursor_on(); /* needed for ":gui" in .vimrc */
|
|
Karsten Hopp |
83c5f2 |
- gui.starting = TRUE;
|
|
Karsten Hopp |
83c5f2 |
full_screen = FALSE;
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! #ifdef FEAT_GUI_GTK
|
|
Karsten Hopp |
83c5f2 |
! gui.event_time = GDK_CURRENT_TIME;
|
|
Karsten Hopp |
83c5f2 |
! #endif
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
#ifdef MAY_FORK
|
|
Karsten Hopp |
83c5f2 |
! if (!gui.dofork || vim_strchr(p_go, GO_FORG) || recursive)
|
|
Karsten Hopp |
83c5f2 |
! dofork = FALSE;
|
|
Karsten Hopp |
83c5f2 |
#endif
|
|
Karsten Hopp |
83c5f2 |
! ++recursive;
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! termcapinit((char_u *)"builtin_gui");
|
|
Karsten Hopp |
83c5f2 |
! gui.starting = recursive - 1;
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
if (!gui.in_use) /* failed to start GUI */
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
! termcapinit(old_term); /* back to old term settings */
|
|
Karsten Hopp |
83c5f2 |
settmode(TMODE_RAW); /* restart RAW mode */
|
|
Karsten Hopp |
83c5f2 |
#ifdef FEAT_TITLE
|
|
Karsten Hopp |
83c5f2 |
set_title_defaults(); /* set 'title' and 'icon' again */
|
|
Karsten Hopp |
83c5f2 |
--- 77,123 ----
|
|
Karsten Hopp |
83c5f2 |
gui_start()
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
char_u *old_term;
|
|
Karsten Hopp |
83c5f2 |
static int recursive = 0;
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
old_term = vim_strsave(T_NAME);
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
settmode(TMODE_COOK); /* stop RAW mode */
|
|
Karsten Hopp |
83c5f2 |
if (full_screen)
|
|
Karsten Hopp |
83c5f2 |
cursor_on(); /* needed for ":gui" in .vimrc */
|
|
Karsten Hopp |
83c5f2 |
full_screen = FALSE;
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! ++recursive;
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
#ifdef MAY_FORK
|
|
Karsten Hopp |
83c5f2 |
! /*
|
|
Karsten Hopp |
83c5f2 |
! * Quit the current process and continue in the child.
|
|
Karsten Hopp |
83c5f2 |
! * Makes "gvim file" disconnect from the shell it was started in.
|
|
Karsten Hopp |
83c5f2 |
! * Don't do this when Vim was started with "-f" or the 'f' flag is present
|
|
Karsten Hopp |
83c5f2 |
! * in 'guioptions'.
|
|
Karsten Hopp |
83c5f2 |
! */
|
|
Karsten Hopp |
83c5f2 |
! if (gui.dofork && !vim_strchr(p_go, GO_FORG) && recursive <= 1)
|
|
Karsten Hopp |
83c5f2 |
! {
|
|
Karsten Hopp |
83c5f2 |
! gui_do_fork();
|
|
Karsten Hopp |
83c5f2 |
! }
|
|
Karsten Hopp |
83c5f2 |
! else
|
|
Karsten Hopp |
83c5f2 |
#endif
|
|
Karsten Hopp |
83c5f2 |
! {
|
|
Karsten Hopp |
83c5f2 |
! gui_attempt_start();
|
|
Karsten Hopp |
83c5f2 |
! }
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
if (!gui.in_use) /* failed to start GUI */
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
! /* Back to old term settings
|
|
Karsten Hopp |
83c5f2 |
! *
|
|
Karsten Hopp |
83c5f2 |
! * FIXME: If we got here because a child process failed and flagged to
|
|
Karsten Hopp |
83c5f2 |
! * the parent to resume, and X11 is enabled with FEAT_TITLE, this will
|
|
Karsten Hopp |
83c5f2 |
! * hit an X11 I/O error and do a longjmp(), leaving recursive
|
|
Karsten Hopp |
83c5f2 |
! * permanently set to 1. This is probably not as big a problem as it
|
|
Karsten Hopp |
83c5f2 |
! * sounds, because gui_mch_init() in both gui_x11.c and gui_gtk_x11.c
|
|
Karsten Hopp |
83c5f2 |
! * return "OK" unconditionally, so it would be very difficult to
|
|
Karsten Hopp |
83c5f2 |
! * actually hit this case.
|
|
Karsten Hopp |
83c5f2 |
! */
|
|
Karsten Hopp |
83c5f2 |
! termcapinit(old_term);
|
|
Karsten Hopp |
83c5f2 |
settmode(TMODE_RAW); /* restart RAW mode */
|
|
Karsten Hopp |
83c5f2 |
#ifdef FEAT_TITLE
|
|
Karsten Hopp |
83c5f2 |
set_title_defaults(); /* set 'title' and 'icon' again */
|
|
Karsten Hopp |
83c5f2 |
***************
|
|
Karsten Hopp |
83c5f2 |
*** 108,113 ****
|
|
Karsten Hopp |
83c5f2 |
--- 126,166 ----
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
vim_free(old_term);
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
+ #ifdef FEAT_AUTOCMD
|
|
Karsten Hopp |
83c5f2 |
+ /* If the GUI started successfully, trigger the GUIEnter event, otherwise
|
|
Karsten Hopp |
83c5f2 |
+ * the GUIFailed event. */
|
|
Karsten Hopp |
83c5f2 |
+ gui_mch_update();
|
|
Karsten Hopp |
83c5f2 |
+ apply_autocmds(gui.in_use ? EVENT_GUIENTER : EVENT_GUIFAILED,
|
|
Karsten Hopp |
83c5f2 |
+ NULL, NULL, FALSE, curbuf);
|
|
Karsten Hopp |
83c5f2 |
+ #endif
|
|
Karsten Hopp |
83c5f2 |
+ --recursive;
|
|
Karsten Hopp |
83c5f2 |
+ }
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ /*
|
|
Karsten Hopp |
83c5f2 |
+ * Set_termname() will call gui_init() to start the GUI.
|
|
Karsten Hopp |
83c5f2 |
+ * Set the "starting" flag, to indicate that the GUI will start.
|
|
Karsten Hopp |
83c5f2 |
+ *
|
|
Karsten Hopp |
83c5f2 |
+ * We don't want to open the GUI shell until after we've read .gvimrc,
|
|
Karsten Hopp |
83c5f2 |
+ * otherwise we don't know what font we will use, and hence we don't know
|
|
Karsten Hopp |
83c5f2 |
+ * what size the shell should be. So if there are errors in the .gvimrc
|
|
Karsten Hopp |
83c5f2 |
+ * file, they will have to go to the terminal: Set full_screen to FALSE.
|
|
Karsten Hopp |
83c5f2 |
+ * full_screen will be set to TRUE again by a successful termcapinit().
|
|
Karsten Hopp |
83c5f2 |
+ */
|
|
Karsten Hopp |
83c5f2 |
+ static void
|
|
Karsten Hopp |
83c5f2 |
+ gui_attempt_start()
|
|
Karsten Hopp |
83c5f2 |
+ {
|
|
Karsten Hopp |
83c5f2 |
+ static int recursive = 0;
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ ++recursive;
|
|
Karsten Hopp |
83c5f2 |
+ gui.starting = TRUE;
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ #ifdef FEAT_GUI_GTK
|
|
Karsten Hopp |
83c5f2 |
+ gui.event_time = GDK_CURRENT_TIME;
|
|
Karsten Hopp |
83c5f2 |
+ #endif
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ termcapinit((char_u *)"builtin_gui");
|
|
Karsten Hopp |
83c5f2 |
+ gui.starting = recursive - 1;
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_X11)
|
|
Karsten Hopp |
83c5f2 |
if (gui.in_use)
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
***************
|
|
Karsten Hopp |
83c5f2 |
*** 123,218 ****
|
|
Karsten Hopp |
83c5f2 |
display_errors();
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
#endif
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! #if defined(MAY_FORK) && !defined(__QNXNTO__)
|
|
Karsten Hopp |
83c5f2 |
! /*
|
|
Karsten Hopp |
83c5f2 |
! * Quit the current process and continue in the child.
|
|
Karsten Hopp |
83c5f2 |
! * Makes "gvim file" disconnect from the shell it was started in.
|
|
Karsten Hopp |
83c5f2 |
! * Don't do this when Vim was started with "-f" or the 'f' flag is present
|
|
Karsten Hopp |
83c5f2 |
! * in 'guioptions'.
|
|
Karsten Hopp |
83c5f2 |
! */
|
|
Karsten Hopp |
83c5f2 |
! if (gui.in_use && dofork)
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
! int pipefd[2]; /* pipe between parent and child */
|
|
Karsten Hopp |
83c5f2 |
! int pipe_error;
|
|
Karsten Hopp |
83c5f2 |
! char dummy;
|
|
Karsten Hopp |
83c5f2 |
! pid_t pid = -1;
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! /* Setup a pipe between the child and the parent, so that the parent
|
|
Karsten Hopp |
83c5f2 |
! * knows when the child has done the setsid() call and is allowed to
|
|
Karsten Hopp |
83c5f2 |
! * exit. */
|
|
Karsten Hopp |
83c5f2 |
! pipe_error = (pipe(pipefd) < 0);
|
|
Karsten Hopp |
83c5f2 |
! pid = fork();
|
|
Karsten Hopp |
83c5f2 |
! if (pid > 0) /* Parent */
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
! /* Give the child some time to do the setsid(), otherwise the
|
|
Karsten Hopp |
83c5f2 |
! * exit() may kill the child too (when starting gvim from inside a
|
|
Karsten Hopp |
83c5f2 |
! * gvim). */
|
|
Karsten Hopp |
83c5f2 |
! if (pipe_error)
|
|
Karsten Hopp |
83c5f2 |
! ui_delay(300L, TRUE);
|
|
Karsten Hopp |
83c5f2 |
! else
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
! /* The read returns when the child closes the pipe (or when
|
|
Karsten Hopp |
83c5f2 |
! * the child dies for some reason). */
|
|
Karsten Hopp |
83c5f2 |
! close(pipefd[1]);
|
|
Karsten Hopp |
83c5f2 |
! ignored = (int)read(pipefd[0], &dummy, (size_t)1);
|
|
Karsten Hopp |
83c5f2 |
! close(pipefd[0]);
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! /* When swapping screens we may need to go to the next line, e.g.,
|
|
Karsten Hopp |
83c5f2 |
! * after a hit-enter prompt and using ":gui". */
|
|
Karsten Hopp |
83c5f2 |
! if (newline_on_exit)
|
|
Karsten Hopp |
83c5f2 |
! mch_errmsg("\r\n");
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! /*
|
|
Karsten Hopp |
83c5f2 |
! * The parent must skip the normal exit() processing, the child
|
|
Karsten Hopp |
83c5f2 |
! * will do it. For example, GTK messes up signals when exiting.
|
|
Karsten Hopp |
83c5f2 |
! */
|
|
Karsten Hopp |
83c5f2 |
! _exit(0);
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! # if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
|
|
Karsten Hopp |
83c5f2 |
/*
|
|
Karsten Hopp |
83c5f2 |
! * Change our process group. On some systems/shells a CTRL-C in the
|
|
Karsten Hopp |
83c5f2 |
! * shell where Vim was started would otherwise kill gvim!
|
|
Karsten Hopp |
83c5f2 |
*/
|
|
Karsten Hopp |
83c5f2 |
! if (pid == 0) /* child */
|
|
Karsten Hopp |
83c5f2 |
# if defined(HAVE_SETSID)
|
|
Karsten Hopp |
83c5f2 |
! (void)setsid();
|
|
Karsten Hopp |
83c5f2 |
# else
|
|
Karsten Hopp |
83c5f2 |
! (void)setpgid(0, 0);
|
|
Karsten Hopp |
83c5f2 |
# endif
|
|
Karsten Hopp |
83c5f2 |
# endif
|
|
Karsten Hopp |
83c5f2 |
! if (!pipe_error)
|
|
Karsten Hopp |
83c5f2 |
! {
|
|
Karsten Hopp |
83c5f2 |
! close(pipefd[0]);
|
|
Karsten Hopp |
83c5f2 |
! close(pipefd[1]);
|
|
Karsten Hopp |
83c5f2 |
! }
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
# if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
|
|
Karsten Hopp |
83c5f2 |
! /* Tell the session manager our new PID */
|
|
Karsten Hopp |
83c5f2 |
! gui_mch_forked();
|
|
Karsten Hopp |
83c5f2 |
# endif
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
- #else
|
|
Karsten Hopp |
83c5f2 |
- # if defined(__QNXNTO__)
|
|
Karsten Hopp |
83c5f2 |
- if (gui.in_use && dofork)
|
|
Karsten Hopp |
83c5f2 |
- procmgr_daemon(0, PROCMGR_DAEMON_KEEPUMASK | PROCMGR_DAEMON_NOCHDIR |
|
|
Karsten Hopp |
83c5f2 |
- PROCMGR_DAEMON_NOCLOSE | PROCMGR_DAEMON_NODEVNULL);
|
|
Karsten Hopp |
83c5f2 |
- # endif
|
|
Karsten Hopp |
83c5f2 |
- #endif
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! #ifdef FEAT_AUTOCMD
|
|
Karsten Hopp |
83c5f2 |
! /* If the GUI started successfully, trigger the GUIEnter event, otherwise
|
|
Karsten Hopp |
83c5f2 |
! * the GUIFailed event. */
|
|
Karsten Hopp |
83c5f2 |
! gui_mch_update();
|
|
Karsten Hopp |
83c5f2 |
! apply_autocmds(gui.in_use ? EVENT_GUIENTER : EVENT_GUIFAILED,
|
|
Karsten Hopp |
83c5f2 |
! NULL, NULL, FALSE, curbuf);
|
|
Karsten Hopp |
83c5f2 |
#endif
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! --recursive;
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
/*
|
|
Karsten Hopp |
83c5f2 |
* Call this when vim starts up, whether or not the GUI is started
|
|
Karsten Hopp |
83c5f2 |
*/
|
|
Karsten Hopp |
83c5f2 |
--- 176,346 ----
|
|
Karsten Hopp |
83c5f2 |
display_errors();
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
#endif
|
|
Karsten Hopp |
83c5f2 |
+ --recursive;
|
|
Karsten Hopp |
83c5f2 |
+ }
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! #ifdef MAY_FORK
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! /* for waitpid() */
|
|
Karsten Hopp |
83c5f2 |
! # if defined(HAVE_SYS_WAIT_H) || defined(HAVE_UNION_WAIT)
|
|
Karsten Hopp |
83c5f2 |
! # include <sys/wait.h>
|
|
Karsten Hopp |
83c5f2 |
! # endif
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! /*
|
|
Karsten Hopp |
83c5f2 |
! * Create a new process, by forking. In the child, start the GUI, and in
|
|
Karsten Hopp |
83c5f2 |
! * the parent, exit.
|
|
Karsten Hopp |
83c5f2 |
! *
|
|
Karsten Hopp |
83c5f2 |
! * If something goes wrong, this will return with gui.in_use still set
|
|
Karsten Hopp |
83c5f2 |
! * to FALSE, in which case the caller should continue execution without
|
|
Karsten Hopp |
83c5f2 |
! * the GUI.
|
|
Karsten Hopp |
83c5f2 |
! *
|
|
Karsten Hopp |
83c5f2 |
! * If the child fails to start the GUI, then the child will exit and the
|
|
Karsten Hopp |
83c5f2 |
! * parent will return. If the child succeeds, then the parent will exit
|
|
Karsten Hopp |
83c5f2 |
! * and the child will return.
|
|
Karsten Hopp |
83c5f2 |
! */
|
|
Karsten Hopp |
83c5f2 |
! static void
|
|
Karsten Hopp |
83c5f2 |
! gui_do_fork()
|
|
Karsten Hopp |
83c5f2 |
! {
|
|
Karsten Hopp |
83c5f2 |
! #ifdef __QNXNTO__
|
|
Karsten Hopp |
83c5f2 |
! procmgr_daemon(0, PROCMGR_DAEMON_KEEPUMASK | PROCMGR_DAEMON_NOCHDIR |
|
|
Karsten Hopp |
83c5f2 |
! PROCMGR_DAEMON_NOCLOSE | PROCMGR_DAEMON_NODEVNULL);
|
|
Karsten Hopp |
83c5f2 |
! gui_attempt_start();
|
|
Karsten Hopp |
83c5f2 |
! return;
|
|
Karsten Hopp |
83c5f2 |
! #else
|
|
Karsten Hopp |
83c5f2 |
! int pipefd[2]; /* pipe between parent and child */
|
|
Karsten Hopp |
83c5f2 |
! int pipe_error;
|
|
Karsten Hopp |
83c5f2 |
! int status;
|
|
Karsten Hopp |
83c5f2 |
! int exit_status;
|
|
Karsten Hopp |
83c5f2 |
! pid_t pid = -1;
|
|
Karsten Hopp |
83c5f2 |
! FILE *parent_file;
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! /* Setup a pipe between the child and the parent, so that the parent
|
|
Karsten Hopp |
83c5f2 |
! * knows when the child has done the setsid() call and is allowed to
|
|
Karsten Hopp |
83c5f2 |
! * exit. */
|
|
Karsten Hopp |
83c5f2 |
! pipe_error = (pipe(pipefd) < 0);
|
|
Karsten Hopp |
83c5f2 |
! pid = fork();
|
|
Karsten Hopp |
83c5f2 |
! if (pid < 0) /* Fork error */
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
! EMSG(_("E851: Failed to create a new process for the GUI"));
|
|
Karsten Hopp |
83c5f2 |
! return;
|
|
Karsten Hopp |
83c5f2 |
! }
|
|
Karsten Hopp |
83c5f2 |
! else if (pid > 0) /* Parent */
|
|
Karsten Hopp |
83c5f2 |
! {
|
|
Karsten Hopp |
83c5f2 |
! /* Give the child some time to do the setsid(), otherwise the
|
|
Karsten Hopp |
83c5f2 |
! * exit() may kill the child too (when starting gvim from inside a
|
|
Karsten Hopp |
83c5f2 |
! * gvim). */
|
|
Karsten Hopp |
83c5f2 |
! if (!pipe_error)
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
! /* The read returns when the child closes the pipe (or when
|
|
Karsten Hopp |
83c5f2 |
! * the child dies for some reason). */
|
|
Karsten Hopp |
83c5f2 |
! close(pipefd[1]);
|
|
Karsten Hopp |
83c5f2 |
! status = gui_read_child_pipe(pipefd[0]);
|
|
Karsten Hopp |
83c5f2 |
! if (status == GUI_CHILD_FAILED)
|
|
Karsten Hopp |
83c5f2 |
{
|
|
Karsten Hopp |
83c5f2 |
! /* The child failed to start the GUI, so the caller must
|
|
Karsten Hopp |
83c5f2 |
! * continue. There may be more error information written
|
|
Karsten Hopp |
83c5f2 |
! * to stderr by the child. */
|
|
Karsten Hopp |
83c5f2 |
! # ifdef __NeXT__
|
|
Karsten Hopp |
83c5f2 |
! wait4(pid, &exit_status, 0, (struct rusage *)0);
|
|
Karsten Hopp |
83c5f2 |
! # else
|
|
Karsten Hopp |
83c5f2 |
! waitpid(pid, &exit_status, 0);
|
|
Karsten Hopp |
83c5f2 |
! # endif
|
|
Karsten Hopp |
83c5f2 |
! EMSG(_("E852: The child process failed to start the GUI"));
|
|
Karsten Hopp |
83c5f2 |
! return;
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
! else if (status == GUI_CHILD_IO_ERROR)
|
|
Karsten Hopp |
83c5f2 |
! {
|
|
Karsten Hopp |
83c5f2 |
! pipe_error = TRUE;
|
|
Karsten Hopp |
83c5f2 |
! }
|
|
Karsten Hopp |
83c5f2 |
! /* else GUI_CHILD_OK: parent exit */
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! if (pipe_error)
|
|
Karsten Hopp |
83c5f2 |
! ui_delay(300L, TRUE);
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! /* When swapping screens we may need to go to the next line, e.g.,
|
|
Karsten Hopp |
83c5f2 |
! * after a hit-enter prompt and using ":gui". */
|
|
Karsten Hopp |
83c5f2 |
! if (newline_on_exit)
|
|
Karsten Hopp |
83c5f2 |
! mch_errmsg("\r\n");
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
/*
|
|
Karsten Hopp |
83c5f2 |
! * The parent must skip the normal exit() processing, the child
|
|
Karsten Hopp |
83c5f2 |
! * will do it. For example, GTK messes up signals when exiting.
|
|
Karsten Hopp |
83c5f2 |
*/
|
|
Karsten Hopp |
83c5f2 |
! _exit(0);
|
|
Karsten Hopp |
83c5f2 |
! }
|
|
Karsten Hopp |
83c5f2 |
! /* Child */
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! # if defined(HAVE_SETSID) || defined(HAVE_SETPGID)
|
|
Karsten Hopp |
83c5f2 |
! /*
|
|
Karsten Hopp |
83c5f2 |
! * Change our process group. On some systems/shells a CTRL-C in the
|
|
Karsten Hopp |
83c5f2 |
! * shell where Vim was started would otherwise kill gvim!
|
|
Karsten Hopp |
83c5f2 |
! */
|
|
Karsten Hopp |
83c5f2 |
# if defined(HAVE_SETSID)
|
|
Karsten Hopp |
83c5f2 |
! (void)setsid();
|
|
Karsten Hopp |
83c5f2 |
# else
|
|
Karsten Hopp |
83c5f2 |
! (void)setpgid(0, 0);
|
|
Karsten Hopp |
83c5f2 |
# endif
|
|
Karsten Hopp |
83c5f2 |
# endif
|
|
Karsten Hopp |
83c5f2 |
! if (!pipe_error)
|
|
Karsten Hopp |
83c5f2 |
! close(pipefd[0]);
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
# if defined(FEAT_GUI_GNOME) && defined(FEAT_SESSION)
|
|
Karsten Hopp |
83c5f2 |
! /* Tell the session manager our new PID */
|
|
Karsten Hopp |
83c5f2 |
! gui_mch_forked();
|
|
Karsten Hopp |
83c5f2 |
# endif
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ if (!pipe_error)
|
|
Karsten Hopp |
83c5f2 |
+ parent_file = fdopen(pipefd[1], "w");
|
|
Karsten Hopp |
83c5f2 |
+ else
|
|
Karsten Hopp |
83c5f2 |
+ parent_file = NULL;
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ /* Try to start the GUI */
|
|
Karsten Hopp |
83c5f2 |
+ gui_attempt_start();
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
+ /* Notify the parent */
|
|
Karsten Hopp |
83c5f2 |
+ if (parent_file != NULL)
|
|
Karsten Hopp |
83c5f2 |
+ {
|
|
Karsten Hopp |
83c5f2 |
+ fputs(gui.in_use ? "ok" : "fail", parent_file);
|
|
Karsten Hopp |
83c5f2 |
+ fclose(parent_file);
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! /* If we failed to start the GUI, exit now. */
|
|
Karsten Hopp |
83c5f2 |
! if (!gui.in_use)
|
|
Karsten Hopp |
83c5f2 |
! exit(1);
|
|
Karsten Hopp |
83c5f2 |
#endif
|
|
Karsten Hopp |
83c5f2 |
+ }
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
! /*
|
|
Karsten Hopp |
83c5f2 |
! * Read from a pipe assumed to be connected to the child process (this
|
|
Karsten Hopp |
83c5f2 |
! * function is called from the parent).
|
|
Karsten Hopp |
83c5f2 |
! * Return GUI_CHILD_OK if the child successfully started the GUI,
|
|
Karsten Hopp |
83c5f2 |
! * GUY_CHILD_FAILED if the child failed, or GUI_CHILD_IO_ERROR if there was
|
|
Karsten Hopp |
83c5f2 |
! * some other error.
|
|
Karsten Hopp |
83c5f2 |
! *
|
|
Karsten Hopp |
83c5f2 |
! * The file descriptor will be closed before the function returns.
|
|
Karsten Hopp |
83c5f2 |
! */
|
|
Karsten Hopp |
83c5f2 |
! static int
|
|
Karsten Hopp |
83c5f2 |
! gui_read_child_pipe(int fd)
|
|
Karsten Hopp |
83c5f2 |
! {
|
|
Karsten Hopp |
83c5f2 |
! size_t bytes_read;
|
|
Karsten Hopp |
83c5f2 |
! FILE *file;
|
|
Karsten Hopp |
83c5f2 |
! char buffer[10];
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! file = fdopen(fd, "r");
|
|
Karsten Hopp |
83c5f2 |
! if (!file)
|
|
Karsten Hopp |
83c5f2 |
! return GUI_CHILD_IO_ERROR;
|
|
Karsten Hopp |
83c5f2 |
!
|
|
Karsten Hopp |
83c5f2 |
! bytes_read = fread(buffer, sizeof(char), sizeof(buffer)-1, file);
|
|
Karsten Hopp |
83c5f2 |
! buffer[bytes_read] = '\0';
|
|
Karsten Hopp |
83c5f2 |
! fclose(file);
|
|
Karsten Hopp |
83c5f2 |
! if (strcmp(buffer, "ok") == 0)
|
|
Karsten Hopp |
83c5f2 |
! return GUI_CHILD_OK;
|
|
Karsten Hopp |
83c5f2 |
! return GUI_CHILD_FAILED;
|
|
Karsten Hopp |
83c5f2 |
}
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
+ #endif /* MAY_FORK */
|
|
Karsten Hopp |
83c5f2 |
+
|
|
Karsten Hopp |
83c5f2 |
/*
|
|
Karsten Hopp |
83c5f2 |
* Call this when vim starts up, whether or not the GUI is started
|
|
Karsten Hopp |
83c5f2 |
*/
|
|
Karsten Hopp |
83c5f2 |
*** ../vim-7.3.314/src/version.c 2011-09-14 19:01:38.000000000 +0200
|
|
Karsten Hopp |
83c5f2 |
--- src/version.c 2011-09-14 19:02:45.000000000 +0200
|
|
Karsten Hopp |
83c5f2 |
***************
|
|
Karsten Hopp |
83c5f2 |
*** 711,712 ****
|
|
Karsten Hopp |
83c5f2 |
--- 711,714 ----
|
|
Karsten Hopp |
83c5f2 |
{ /* Add new patch number below this line */
|
|
Karsten Hopp |
83c5f2 |
+ /**/
|
|
Karsten Hopp |
83c5f2 |
+ 315,
|
|
Karsten Hopp |
83c5f2 |
/**/
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
--
|
|
Karsten Hopp |
83c5f2 |
A)bort, R)etry, B)ang it with a large hammer
|
|
Karsten Hopp |
83c5f2 |
|
|
Karsten Hopp |
83c5f2 |
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
|
|
Karsten Hopp |
83c5f2 |
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
|
|
Karsten Hopp |
83c5f2 |
\\\ an exciting new programming language -- http://www.Zimbu.org ///
|
|
Karsten Hopp |
83c5f2 |
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|