diff options
| author | Richard M. Stallman | 1998-03-19 06:32:34 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1998-03-19 06:32:34 +0000 |
| commit | 15e88d2198ec14b01c55d028af763fed44b82386 (patch) | |
| tree | 7f734631e882326917ed8f782af6e24a1342ed05 /src | |
| parent | 5265a8423588dc93ce53ecb75cc6a8e712b59938 (diff) | |
| download | emacs-15e88d2198ec14b01c55d028af763fed44b82386.tar.gz emacs-15e88d2198ec14b01c55d028af763fed44b82386.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/filelock.c | 59 |
1 files changed, 47 insertions, 12 deletions
diff --git a/src/filelock.c b/src/filelock.c index a3735bcf101..2bb86bad337 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -37,6 +37,8 @@ Boston, MA 02111-1307, USA. */ | |||
| 37 | #include "lisp.h" | 37 | #include "lisp.h" |
| 38 | #include "buffer.h" | 38 | #include "buffer.h" |
| 39 | 39 | ||
| 40 | #include <time.h> | ||
| 41 | #include <utmp.h> | ||
| 40 | #include <errno.h> | 42 | #include <errno.h> |
| 41 | #ifndef errno | 43 | #ifndef errno |
| 42 | extern int errno; | 44 | extern int errno; |
| @@ -80,6 +82,28 @@ extern int errno; | |||
| 80 | --karl@cs.umb.edu/karl@hq.ileaf.com. */ | 82 | --karl@cs.umb.edu/karl@hq.ileaf.com. */ |
| 81 | 83 | ||
| 82 | 84 | ||
| 85 | /* Return the time of the last system boot. */ | ||
| 86 | |||
| 87 | static time_t boot_time; | ||
| 88 | |||
| 89 | static time_t | ||
| 90 | get_boot_time () | ||
| 91 | { | ||
| 92 | struct utmp ut, *utp; | ||
| 93 | |||
| 94 | if (boot_time) | ||
| 95 | return boot_time; | ||
| 96 | |||
| 97 | utmpname ("/var/log/wtmp"); | ||
| 98 | ut.ut_type = BOOT_TIME; | ||
| 99 | utp = getutid (&ut); | ||
| 100 | endutent (); | ||
| 101 | |||
| 102 | if (!utp) | ||
| 103 | return boot_time = 1; | ||
| 104 | return boot_time = utp->ut_time; | ||
| 105 | } | ||
| 106 | |||
| 83 | /* Here is the structure that stores information about a lock. */ | 107 | /* Here is the structure that stores information about a lock. */ |
| 84 | 108 | ||
| 85 | typedef struct | 109 | typedef struct |
| @@ -87,6 +111,7 @@ typedef struct | |||
| 87 | char *user; | 111 | char *user; |
| 88 | char *host; | 112 | char *host; |
| 89 | unsigned long pid; | 113 | unsigned long pid; |
| 114 | time_t boot_time; | ||
| 90 | } lock_info_type; | 115 | } lock_info_type; |
| 91 | 116 | ||
| 92 | /* When we read the info back, we might need this much more, | 117 | /* When we read the info back, we might need this much more, |
| @@ -146,10 +171,10 @@ lock_file_1 (lfname, force) | |||
| 146 | else | 171 | else |
| 147 | host_name = ""; | 172 | host_name = ""; |
| 148 | lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name) | 173 | lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name) |
| 149 | + LOCK_PID_MAX + 5); | 174 | + LOCK_PID_MAX + 5); |
| 150 | 175 | ||
| 151 | sprintf (lock_info_str, "%s@%s.%lu", user_name, host_name, | 176 | sprintf (lock_info_str, "%s@%s.%lu:%lu", user_name, host_name, |
| 152 | (unsigned long) getpid ()); | 177 | (unsigned long) getpid (), (unsigned long) get_boot_time ()); |
| 153 | 178 | ||
| 154 | err = symlink (lock_info_str, lfname); | 179 | err = symlink (lock_info_str, lfname); |
| 155 | if (errno == EEXIST && force) | 180 | if (errno == EEXIST && force) |
| @@ -178,7 +203,7 @@ current_lock_owner (owner, lfname) | |||
| 178 | #endif | 203 | #endif |
| 179 | int o, p, len, ret; | 204 | int o, p, len, ret; |
| 180 | int local_owner = 0; | 205 | int local_owner = 0; |
| 181 | char *at, *dot; | 206 | char *at, *dot, *colon; |
| 182 | char *lfinfo = 0; | 207 | char *lfinfo = 0; |
| 183 | int bufsize = 50; | 208 | int bufsize = 50; |
| 184 | /* Read arbitrarily-long contents of symlink. Similar code in | 209 | /* Read arbitrarily-long contents of symlink. Similar code in |
| @@ -209,21 +234,30 @@ current_lock_owner (owner, lfname) | |||
| 209 | local_owner = 1; | 234 | local_owner = 1; |
| 210 | } | 235 | } |
| 211 | 236 | ||
| 212 | /* Parse USER@HOST.PID. If can't parse, return -1. */ | 237 | /* Parse USER@HOST.PID:BOOT_TIME. If can't parse, return -1. */ |
| 213 | /* The USER is everything before the first @. */ | 238 | /* The USER is everything before the first @. */ |
| 214 | at = index (lfinfo, '@'); | 239 | at = index (lfinfo, '@'); |
| 215 | dot = rindex (lfinfo, '.'); | 240 | dot = rindex (lfinfo, '.'); |
| 216 | if (!at || !dot) { | 241 | if (!at || !dot) |
| 217 | xfree (lfinfo); | 242 | { |
| 218 | return -1; | 243 | xfree (lfinfo); |
| 219 | } | 244 | return -1; |
| 245 | } | ||
| 220 | len = at - lfinfo; | 246 | len = at - lfinfo; |
| 221 | owner->user = (char *) xmalloc (len + 1); | 247 | owner->user = (char *) xmalloc (len + 1); |
| 222 | strncpy (owner->user, lfinfo, len); | 248 | strncpy (owner->user, lfinfo, len); |
| 223 | owner->user[len] = 0; | 249 | owner->user[len] = 0; |
| 224 | 250 | ||
| 225 | /* The PID is everything after the last `.'. */ | 251 | /* The PID is everything from the last `.' to the `:'. */ |
| 226 | owner->pid = atoi (dot + 1); | 252 | owner->pid = atoi (dot + 1); |
| 253 | colon = dot; | ||
| 254 | while (*colon && *colon != ':') | ||
| 255 | colon++; | ||
| 256 | /* After the `:', if there is one, comes the boot time. */ | ||
| 257 | if (*colon == ':') | ||
| 258 | owner->boot_time = atoi (colon + 1); | ||
| 259 | else | ||
| 260 | owner->boot_time = 0; | ||
| 227 | 261 | ||
| 228 | /* The host is everything in between. */ | 262 | /* The host is everything in between. */ |
| 229 | len = dot - at - 1; | 263 | len = dot - at - 1; |
| @@ -241,7 +275,9 @@ current_lock_owner (owner, lfname) | |||
| 241 | if (owner->pid == getpid ()) | 275 | if (owner->pid == getpid ()) |
| 242 | ret = 2; /* We own it. */ | 276 | ret = 2; /* We own it. */ |
| 243 | else if (owner->pid > 0 | 277 | else if (owner->pid > 0 |
| 244 | && (kill (owner->pid, 0) >= 0 || errno == EPERM)) | 278 | && (kill (owner->pid, 0) >= 0 || errno == EPERM) |
| 279 | && (owner->boot_time == 0 | ||
| 280 | || owner->boot_time == get_boot_time ())) | ||
| 245 | ret = 1; /* An existing process on this machine owns it. */ | 281 | ret = 1; /* An existing process on this machine owns it. */ |
| 246 | /* The owner process is dead or has a strange pid (<=0), so try to | 282 | /* The owner process is dead or has a strange pid (<=0), so try to |
| 247 | zap the lockfile. */ | 283 | zap the lockfile. */ |
| @@ -465,7 +501,6 @@ t if it is locked by you, else a string of the name of the locker.") | |||
| 465 | 501 | ||
| 466 | return ret; | 502 | return ret; |
| 467 | } | 503 | } |
| 468 | |||
| 469 | 504 | ||
| 470 | /* Initialization functions. */ | 505 | /* Initialization functions. */ |
| 471 | 506 | ||