(Fset_buffer_multibyte): Fix arg for chars_in_text.
[bpt/emacs.git] / src / filelock.c
index d30571a..a3735bc 100644 (file)
@@ -58,14 +58,14 @@ extern int errno;
    that's too unreliable.  Hence the separate file, which could
    theoretically be updated by daemons running separately -- but this
    whole idea is unimplemented; in practice, at least in our
-   environment, it seems such stale locks arise fiarly infrequently, and
+   environment, it seems such stale locks arise fairly infrequently, and
    Emacs' standard methods of dealing with clashes suffice.
 
    We use symlinks instead of normal files because (1) they can be
    stored more efficiently on the filesystem, since the kernel knows
    they will be small, and (2) all the info about the lock can be read
    in a single system call (readlink).  Although we could use regular
-   files to be useful on old systems lacking symlinks, noawdays
+   files to be useful on old systems lacking symlinks, nowadays
    virtually all such systems are probably single-user anyway, so it
    didn't seem worth the complication.
    
@@ -86,11 +86,12 @@ typedef struct
 {
   char *user;
   char *host;
-  int pid;
+  unsigned long pid;
 } lock_info_type;
 
-/* When we read the info back, we might need this much more.  */
-#define LOCK_PID_MAX 21 /* enough for signed 64 bits plus null */
+/* When we read the info back, we might need this much more,
+   enough for decimal representation plus null.  */
+#define LOCK_PID_MAX (4 * sizeof (unsigned long))
 
 /* Free the two dynamically-allocated pieces in PTR.  */
 #define FREE_LOCK_INFO(i) do { xfree ((i).user); xfree ((i).host); } while (0)
@@ -99,7 +100,7 @@ typedef struct
 /* Write the name of the lock file for FN into LFNAME.  Length will be
    that of FN plus two more for the leading `.#' plus one for the null.  */
 #define MAKE_LOCK_NAME(lock, file) \
-  (lock = (char *) alloca (XSTRING (file)->size + 2 + 1), \
+  (lock = (char *) alloca (XSTRING (file)->size_byte + 2 + 1), \
    fill_in_lock_file_name (lock, (file)))
 
 static void
@@ -132,11 +133,23 @@ lock_file_1 (lfname, force)
      int force;
 {
   register int err;
-  char *user_name = XSTRING (Fuser_login_name (Qnil))->data;
-  char *host_name = XSTRING (Fsystem_name ())->data;
-  char *lock_info_str = alloca (strlen (user_name) + strlen (host_name) + 21);
+  char *user_name;
+  char *host_name;
+  char *lock_info_str;
 
-  sprintf (lock_info_str, "%s@%s.%d", user_name, host_name, getpid ());
+  if (STRINGP (Fuser_login_name (Qnil)))
+    user_name = (char *)XSTRING (Fuser_login_name (Qnil))->data;
+  else
+    user_name = "";
+  if (STRINGP (Fsystem_name ()))
+    host_name = (char *)XSTRING (Fsystem_name ())->data;
+  else
+    host_name = "";
+  lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
+                         + LOCK_PID_MAX + 5);
+
+  sprintf (lock_info_str, "%s@%s.%lu", user_name, host_name,
+           (unsigned long) getpid ());
 
   err = symlink (lock_info_str, lfname);
   if (errno == EEXIST && force)
@@ -192,7 +205,7 @@ current_lock_owner (owner, lfname)
      read it to determine return value, so allocate it.  */
   if (!owner)
     {
-      owner = alloca (sizeof (lock_info_type));
+      owner = (lock_info_type *) alloca (sizeof (lock_info_type));
       local_owner = 1;
     }
   
@@ -222,21 +235,20 @@ current_lock_owner (owner, lfname)
   xfree (lfinfo);
   
   /* On current host?  */
-  if (strcmp (owner->host, XSTRING (Fsystem_name ())->data) == 0)
+  if (STRINGP (Fsystem_name ())
+      && strcmp (owner->host, XSTRING (Fsystem_name ())->data) == 0)
     {
       if (owner->pid == getpid ())
         ret = 2; /* We own it.  */
-      
-      if (owner->pid > 0
+      else if (owner->pid > 0
                && (kill (owner->pid, 0) >= 0 || errno == EPERM))
         ret = 1; /* An existing process on this machine owns it.  */
-      
       /* The owner process is dead or has a strange pid (<=0), so try to
          zap the lockfile.  */
-      if (unlink (lfname) < 0)
+      else if (unlink (lfname) < 0)
         ret = -1;
-      
-      ret = 0;
+      else
+       ret = 0;
     }
   else
     { /* If we wanted to support the check for stale locks on remote machines,
@@ -264,7 +276,7 @@ lock_if_free (clasher, lfname)
      lock_info_type *clasher;
      register char *lfname; 
 {
-  while (lock_file_1 (lfname, 0) == 0)
+  if (lock_file_1 (lfname, 0) == 0)
     {
       int locker;
 
@@ -279,11 +291,8 @@ lock_if_free (clasher, lfname)
         }
       else if (locker == 1)
         return 1;  /* Someone else has it.  */
-      else if (locker == -1)
-        return -1; /* Something's wrong.  */
 
-       /* If some other error, or no such lock, try to lock again.  */
-       /* Is there a case where we loop forever?  */
+      return -1; /* Something's wrong.  */
     }
   return 0;
 }
@@ -336,9 +345,9 @@ lock_file (fn)
     return;
 
   /* Else consider breaking the lock */
-  locker = alloca (strlen (lock_info.user) + strlen (lock_info.host)
-                   + LOCK_PID_MAX + 9);
-  sprintf (locker, "%s@%s (pid %d)", lock_info.user, lock_info.host,
+  locker = (char *) alloca (strlen (lock_info.user) + strlen (lock_info.host)
+                           + LOCK_PID_MAX + 9);
+  sprintf (locker, "%s@%s (pid %lu)", lock_info.user, lock_info.host,
            lock_info.pid);
   FREE_LOCK_INFO (lock_info);
   
@@ -376,7 +385,14 @@ unlock_all_files ()
     {
       b = XBUFFER (XCONS (XCONS (tail)->car)->cdr);
       if (STRINGP (b->file_truename) && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b))
-       unlock_file (b->file_truename);
+       {
+         register char *lfname;
+
+         MAKE_LOCK_NAME (lfname, b->file_truename);
+
+         if (current_lock_owner (0, lfname) == 2)
+           unlink (lfname);
+       }
     }
 }
 \f
@@ -412,6 +428,7 @@ if it should normally be locked.")
 
 /* Unlock the file visited in buffer BUFFER.  */
 
+void
 unlock_buffer (buffer)
      struct buffer *buffer;
 {
@@ -452,31 +469,6 @@ t if it is locked by you, else a string of the name of the locker.")
 \f
 /* Initialization functions.  */
 
-init_filelock ()
-{
-#if 0
-  char *new_name;
-
-  lock_dir = egetenv ("EMACSLOCKDIR");
-  if (! lock_dir)
-    lock_dir = PATH_LOCK;
-
-  /* Copy the name in case egetenv got it from a Lisp string.  */
-  new_name = (char *) xmalloc (strlen (lock_dir) + 2);
-  strcpy (new_name, lock_dir);
-  lock_dir = new_name;
-
-  /* Make sure it ends with a slash.  */
-  if (lock_dir[strlen (lock_dir) - 1] != '/')
-    strcat (lock_dir, "/");
-
-  superlock_file = (char *) xmalloc ((strlen (lock_dir)
-                                     + sizeof (SUPERLOCK_NAME)));
-  strcpy (superlock_file, lock_dir);
-  strcat (superlock_file, SUPERLOCK_NAME);
-#endif
-}
-
 syms_of_filelock ()
 {
   defsubr (&Sunlock_buffer);