]> code.delx.au - gnu-emacs/blobdiff - src/xsmfns.c
; Revert "Ensure undo-boundary after insert-file-contents."
[gnu-emacs] / src / xsmfns.c
index 0e635d38ec67776ba7a9057618e986758cd13e60..42e23401c7dae794c534e79ad5b5fa118401f14c 100644 (file)
@@ -1,14 +1,14 @@
 /* Session management module for systems which understand the X Session
    management protocol.
 
-Copyright (C) 2002-2015 Free Software Foundation, Inc.
+Copyright (C) 2002-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -28,11 +28,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <unistd.h>
 #include <sys/param.h>
+#include <errno.h>
 #include <stdio.h>
 
 #include "lisp.h"
-#include "systime.h"
-#include "sysselect.h"
 #include "frame.h"
 #include "termhooks.h"
 #include "xterm.h"
@@ -168,8 +167,12 @@ smc_save_yourself_CB (SmcConn smcConn,
   int val_idx = 0, vp_idx = 0;
   int props_idx = 0;
   int i;
-  char *cwd = get_current_dir_name ();
   char *smid_opt, *chdir_opt = NULL;
+  Lisp_Object user_login_name = Fuser_login_name (Qnil);
+
+  // Must have these.
+  if (! STRINGP (Vinvocation_name) || ! STRINGP (user_login_name))
+    return;
 
   /* How to start a new instance of Emacs.  */
   props[props_idx] = &prop_ptr[props_idx];
@@ -197,11 +200,11 @@ smc_save_yourself_CB (SmcConn smcConn,
   props[props_idx]->type = xstrdup (SmARRAY8);
   props[props_idx]->num_vals = 1;
   props[props_idx]->vals = &values[val_idx++];
-  props[props_idx]->vals[0].length = SBYTES (Vuser_login_name);
-  props[props_idx]->vals[0].value = SDATA (Vuser_login_name);
+  props[props_idx]->vals[0].length = SBYTES (user_login_name);
+  props[props_idx]->vals[0].value = SDATA (user_login_name);
   ++props_idx;
 
-
+  char *cwd = get_current_dir_name ();
   if (cwd)
     {
       props[props_idx] = &prop_ptr[props_idx];
@@ -220,9 +223,8 @@ smc_save_yourself_CB (SmcConn smcConn,
   props[props_idx]->name = xstrdup (SmRestartCommand);
   props[props_idx]->type = xstrdup (SmLISTofARRAY8);
   /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */
-  if (INT_MAX - 3 < initial_argc)
+  if (INT_ADD_WRAPV (initial_argc, 3, &i))
     memory_full (SIZE_MAX);
-  i = 3 + initial_argc;
   props[props_idx]->num_vals = i;
   vp = xnmalloc (i, sizeof *vp);
   props[props_idx]->vals = vp;
@@ -372,6 +374,7 @@ create_client_leader_window (struct x_display_info *dpyinfo, char *client_ID)
                            -1, -1, 1, 1,
                            CopyFromParent, CopyFromParent, CopyFromParent);
 
+  validate_x_resource_name ();
   class_hints.res_name = SSDATA (Vx_resource_name);
   class_hints.res_class = SSDATA (Vx_resource_class);
   XSetClassHint (dpyinfo->display, w, &class_hints);
@@ -397,27 +400,37 @@ x_session_initialize (struct x_display_info *dpyinfo)
   SmcCallbacks callbacks;
   ptrdiff_t name_len = 0;
 
+  /* libSM seems to crash if pwd is missing - see bug#18851.  */
+  if (! get_current_dir_name ())
+    {
+      fprintf (stderr, "Disabling session management due to pwd error: %s\n",
+               emacs_strerror (errno));
+      return;
+    }
+
   ice_fd = -1;
   doing_interact = false;
 
   /* Check if we where started by the session manager.  If so, we will
      have a previous id.  */
-  if (! NILP (Vx_session_previous_id) && STRINGP (Vx_session_previous_id))
+  if (STRINGP (Vx_session_previous_id))
     previous_id = SSDATA (Vx_session_previous_id);
 
   /* Construct the path to the Emacs program.  */
-  if (! NILP (Vinvocation_directory))
+  if (STRINGP (Vinvocation_directory))
     name_len += SBYTES (Vinvocation_directory);
-  name_len += SBYTES (Vinvocation_name);
+  if (STRINGP (Vinvocation_name))
+    name_len += SBYTES (Vinvocation_name);
 
   /* This malloc will not be freed, but it is only done once, and hopefully
      not very large   */
   emacs_program = xmalloc (name_len + 1);
   char *z = emacs_program;
 
-  if (! NILP (Vinvocation_directory))
+  if (STRINGP (Vinvocation_directory))
     z = lispstpcpy (z, Vinvocation_directory);
-  lispstpcpy (z, Vinvocation_name);
+  if (STRINGP (Vinvocation_name))
+    lispstpcpy (z, Vinvocation_name);
 
   /* The SM protocol says all callbacks are mandatory, so set up all
      here and in the mask passed to SmcOpenConnection.  */
@@ -532,7 +545,7 @@ syms_of_xsmfns (void)
 Changing the value does not change the session id used by Emacs.
 The value is nil if no session manager is running.
 See also `x-session-previous-id', `emacs-save-session-functions',
-`emacs-session-save' and `emacs-session-restore'." */);
+`emacs-session-save' and `emacs-session-restore'.  */);
   Vx_session_id = Qnil;
 
   DEFVAR_LISP ("x-session-previous-id", Vx_session_previous_id,
@@ -555,7 +568,7 @@ The session id Emacs has while it is running is in the variable
 same, depending on how the session manager works.
 
 See also `emacs-save-session-functions', `emacs-session-save' and
-`emacs-session-restore'." */);
+`emacs-session-restore'.  */);
   Vx_session_previous_id = Qnil;
 
   defsubr (&Shandle_save_session);