changeset 21217:18acb2723ec5

(current_lock_owner): If lock file data doesn't include the uptime, assume the lock is from this system boot. (get_boot_time): New function. (lock_file_1): Include boot time in the lock text. (current_lock_owner): Parse and compare the boot time.
author Richard M. Stallman <rms@gnu.org>
date Thu, 19 Mar 1998 06:32:34 +0000
parents 54c89f745c5d
children f99248b85ee8
files src/filelock.c
diffstat 1 files changed, 47 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/filelock.c	Wed Mar 18 20:04:56 1998 +0000
+++ b/src/filelock.c	Thu Mar 19 06:32:34 1998 +0000
@@ -37,6 +37,8 @@
 #include "lisp.h"
 #include "buffer.h"
 
+#include <time.h>
+#include <utmp.h>
 #include <errno.h>
 #ifndef errno
 extern int errno;
@@ -80,6 +82,28 @@
    --karl@cs.umb.edu/karl@hq.ileaf.com.  */
 
 
+/* Return the time of the last system boot.  */
+
+static time_t boot_time;
+
+static time_t
+get_boot_time ()
+{
+  struct utmp ut, *utp;
+
+  if (boot_time)
+    return boot_time;
+
+  utmpname ("/var/log/wtmp");
+  ut.ut_type = BOOT_TIME;
+  utp = getutid (&ut);
+  endutent ();
+
+  if (!utp)
+    return boot_time = 1;
+  return boot_time = utp->ut_time;
+}
+
 /* Here is the structure that stores information about a lock.  */
 
 typedef struct
@@ -87,6 +111,7 @@
   char *user;
   char *host;
   unsigned long pid;
+  time_t boot_time;
 } lock_info_type;
 
 /* When we read the info back, we might need this much more,
@@ -146,10 +171,10 @@
   else
     host_name = "";
   lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
-			  + LOCK_PID_MAX + 5);
+				  + LOCK_PID_MAX + 5);
 
-  sprintf (lock_info_str, "%s@%s.%lu", user_name, host_name,
-           (unsigned long) getpid ());
+  sprintf (lock_info_str, "%s@%s.%lu:%lu", user_name, host_name,
+           (unsigned long) getpid (), (unsigned long) get_boot_time ());
 
   err = symlink (lock_info_str, lfname);
   if (errno == EEXIST && force)
@@ -178,7 +203,7 @@
 #endif
   int o, p, len, ret;
   int local_owner = 0;
-  char *at, *dot;
+  char *at, *dot, *colon;
   char *lfinfo = 0;
   int bufsize = 50;
   /* Read arbitrarily-long contents of symlink.  Similar code in
@@ -209,21 +234,30 @@
       local_owner = 1;
     }
   
-  /* Parse USER@HOST.PID.  If can't parse, return -1.  */
+  /* Parse USER@HOST.PID:BOOT_TIME.  If can't parse, return -1.  */
   /* The USER is everything before the first @.  */
   at = index (lfinfo, '@');
   dot = rindex (lfinfo, '.');
-  if (!at || !dot) {
-    xfree (lfinfo);
-    return -1;
-  }
+  if (!at || !dot)
+    {
+      xfree (lfinfo);
+      return -1;
+    }
   len = at - lfinfo;
   owner->user = (char *) xmalloc (len + 1);
   strncpy (owner->user, lfinfo, len);
   owner->user[len] = 0;
   
-  /* The PID is everything after the last `.'.  */
+  /* The PID is everything from the last `.' to the `:'.  */
   owner->pid = atoi (dot + 1);
+  colon = dot;
+  while (*colon && *colon != ':')
+    colon++;
+  /* After the `:', if there is one, comes the boot time.  */
+  if (*colon == ':')
+    owner->boot_time = atoi (colon + 1);
+  else
+    owner->boot_time = 0;
 
   /* The host is everything in between.  */
   len = dot - at - 1;
@@ -241,7 +275,9 @@
       if (owner->pid == getpid ())
         ret = 2; /* We own it.  */
       else if (owner->pid > 0
-               && (kill (owner->pid, 0) >= 0 || errno == EPERM))
+               && (kill (owner->pid, 0) >= 0 || errno == EPERM)
+	       && (owner->boot_time == 0
+		   || owner->boot_time == get_boot_time ()))
         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.  */
@@ -465,7 +501,6 @@
 
   return ret;
 }
-
 
 /* Initialization functions.  */