# HG changeset patch # User Richard M. Stallman # Date 890289154 0 # Node ID 18acb2723ec5e53943d917f0a4decbf8bc9673df # Parent 54c89f745c5d6b4a47341d37fceef06e6ba9f8d3 (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. diff -r 54c89f745c5d -r 18acb2723ec5 src/filelock.c --- 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 +#include #include #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. */