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    ///