comparison src/filelock.c @ 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 d1699afbc43e
children 7f00d0edbd29
comparison
equal deleted inserted replaced
21216:54c89f745c5d 21217:18acb2723ec5
35 #endif /* USG */ 35 #endif /* USG */
36 36
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;
43 #endif 45 #endif
44 46
78 Ethan Jacobson, Kimbo Mundy, and others. 80 Ethan Jacobson, Kimbo Mundy, and others.
79 81
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
86 { 110 {
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,
93 enough for decimal representation plus null. */ 118 enough for decimal representation plus null. */
94 #define LOCK_PID_MAX (4 * sizeof (unsigned long)) 119 #define LOCK_PID_MAX (4 * sizeof (unsigned long))
144 if (STRINGP (Fsystem_name ())) 169 if (STRINGP (Fsystem_name ()))
145 host_name = (char *)XSTRING (Fsystem_name ())->data; 170 host_name = (char *)XSTRING (Fsystem_name ())->data;
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)
156 { 181 {
157 unlink (lfname); 182 unlink (lfname);
176 #ifndef index 201 #ifndef index
177 extern char *rindex (), *index (); 202 extern char *rindex (), *index ();
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
185 file-symlink-p in fileio.c. */ 210 file-symlink-p in fileio.c. */
186 do 211 do
207 { 232 {
208 owner = (lock_info_type *) alloca (sizeof (lock_info_type)); 233 owner = (lock_info_type *) alloca (sizeof (lock_info_type));
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;
230 owner->host = (char *) xmalloc (len + 1); 264 owner->host = (char *) xmalloc (len + 1);
231 strncpy (owner->host, at + 1, len); 265 strncpy (owner->host, at + 1, len);
239 && strcmp (owner->host, XSTRING (Fsystem_name ())->data) == 0) 273 && strcmp (owner->host, XSTRING (Fsystem_name ())->data) == 0)
240 { 274 {
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. */
248 else if (unlink (lfname) < 0) 284 else if (unlink (lfname) < 0)
249 ret = -1; 285 ret = -1;
463 if (owner > 0) 499 if (owner > 0)
464 FREE_LOCK_INFO (locker); 500 FREE_LOCK_INFO (locker);
465 501
466 return ret; 502 return ret;
467 } 503 }
468
469 504
470 /* Initialization functions. */ 505 /* Initialization functions. */
471 506
472 syms_of_filelock () 507 syms_of_filelock ()
473 { 508 {