aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1999-02-19 01:36:29 +0000
committerRichard M. Stallman1999-02-19 01:36:29 +0000
commit9177d97852ed4594d49224c12e9a6bbbce7c0946 (patch)
tree48686bf7b5c0b1c8b2bbce1de20a2ffa3b96d218 /src
parent5bda49c640132d7eb25c4aa047b895622f3a4ff0 (diff)
downloademacs-9177d97852ed4594d49224c12e9a6bbbce7c0946.tar.gz
emacs-9177d97852ed4594d49224c12e9a6bbbce7c0946.zip
(within_one_second): New function.
(current_lock_owner): Use that. (get_boot_time): Use /proc/uptime if available. Otherwise, if nothing found in wtmp, try wtmp.1.gz and so on. (get_boot_time_1): New subroutine taken from get_boot_time.
Diffstat (limited to 'src')
-rw-r--r--src/filelock.c114
1 files changed, 106 insertions, 8 deletions
diff --git a/src/filelock.c b/src/filelock.c
index 6876cbdb5c1..39cfe68c8fd 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -43,6 +43,7 @@ Boston, MA 02111-1307, USA. */
43#include "buffer.h" 43#include "buffer.h"
44#include "charset.h" 44#include "charset.h"
45#include "coding.h" 45#include "coding.h"
46#include "systime.h"
46 47
47#include <time.h> 48#include <time.h>
48#include <errno.h> 49#include <errno.h>
@@ -94,18 +95,113 @@ extern int errno;
94 95
95static time_t boot_time; 96static time_t boot_time;
96 97
98extern Lisp_Object Vshell_file_name;
99
97static time_t 100static time_t
98get_boot_time () 101get_boot_time ()
99{ 102{
100#ifdef BOOT_TIME 103#ifdef BOOT_TIME
101 struct utmp ut, *utp; 104 struct utmp ut, *utp;
105 int fd;
106 EMACS_TIME time_before, after;
107 int counter;
102 108
103 if (boot_time) 109 if (boot_time)
104 return boot_time; 110 return boot_time;
105 111
106 utmpname ("/var/log/wtmp"); 112 EMACS_GET_TIME (time_before);
113
114 /* Try calculating the last boot time
115 from the uptime as obtained from /proc/uptime. */
116
117 while ((fd = open ("/proc/uptime", O_RDONLY)) >= 0)
118 {
119 char buf[BUFSIZ];
120 int res;
121 double upsecs;
122 time_t uptime;
123
124 read (fd, buf, BUFSIZ);
125 close (fd);
126
127 res = sscanf (buf, "%lf", &upsecs);
128
129 /* If the current time did not tick while we were getting the
130 uptime, we have a valid result. */
131 EMACS_GET_TIME (after);
132 if (res == 1 && EMACS_SECS (after) == EMACS_SECS (time_before))
133 {
134 boot_time = EMACS_SECS (time_before) - (time_t) upsecs;
135 return boot_time;
136 }
137
138 /* Otherwise, try again to read the uptime. */
139 time_before = after;
140 }
141
142 /* Try to get boot time from the current wtmp file. */
143 get_boot_time_1 ("/var/log/wtmp");
144
145 /* If we did not find a boot time in wtmp, look at wtmp, and so on. */
146 for (counter = 0; counter < 20 && boot_time == 1; counter++)
147 {
148 char cmd_string[100];
149 Lisp_Object tempname, filename;
150 int delete_flag = 0;
151
152 filename = Qnil;
153
154 sprintf (cmd_string, "/var/log/wtmp.%d", counter);
155 tempname = build_string (cmd_string);
156 if (! NILP (Ffile_exists_p (filename)))
157 filename = tempname;
158 else
159 {
160 sprintf (cmd_string, "/var/log/wtmp.%d.gz", counter);
161 tempname = build_string (cmd_string);
162 if (! NILP (Ffile_exists_p (tempname)))
163 {
164 Lisp_Object args[6];
165 tempname = Fmake_temp_name (build_string ("wtmp"));
166 args[0] = Vshell_file_name;
167 args[1] = Qnil;
168 args[2] = Qnil;
169 args[3] = Qnil;
170 args[4] = build_string ("-c");
171 sprintf (cmd_string, "gunzip < /var/log/wtmp.%d.gz > %s",
172 counter, XSTRING (tempname)->data);
173 args[5] = build_string (cmd_string);
174 Fcall_process (6, args);
175 filename = tempname;
176 delete_flag = 1;
177 }
178 }
179
180 if (! NILP (filename))
181 {
182 get_boot_time_1 (XSTRING (filename)->data);
183 if (delete_flag)
184 unlink (XSTRING (filename)->data);
185 }
186 }
187
188 return boot_time;
189#else
190 return 0;
191#endif
192}
193
194/* Try to get the boot time from wtmp file FILENAME.
195 This succeeds if that file contains a reboot record.
196 Success is indicated by setting BOOT_TIME. */
197
198get_boot_time_1 (filename)
199 char *filename;
200{
201 struct utmp ut, *utp;
202
203 utmpname (filename);
107 setutent (); 204 setutent ();
108 boot_time = 1;
109 while (1) 205 while (1)
110 { 206 {
111 /* Find the next reboot record. */ 207 /* Find the next reboot record. */
@@ -123,11 +219,6 @@ get_boot_time ()
123 break; 219 break;
124 } 220 }
125 endutent (); 221 endutent ();
126
127 return boot_time;
128#else
129 return 0;
130#endif
131} 222}
132 223
133/* Here is the structure that stores information about a lock. */ 224/* Here is the structure that stores information about a lock. */
@@ -218,7 +309,14 @@ lock_file_1 (lfname, force)
218 return err == 0; 309 return err == 0;
219} 310}
220 311
312/* Return 1 if times A and B are no more than one second apart. */
221 313
314int
315within_one_second (a, b)
316 time_t a, b;
317{
318 return (a - b >= -1 && a - b <= 1);
319}
222 320
223/* Return 0 if nobody owns the lock file LFNAME or the lock is obsolete, 321/* Return 0 if nobody owns the lock file LFNAME or the lock is obsolete,
224 1 if another process owns it (and set OWNER (if non-null) to info), 322 1 if another process owns it (and set OWNER (if non-null) to info),
@@ -309,7 +407,7 @@ current_lock_owner (owner, lfname)
309 else if (owner->pid > 0 407 else if (owner->pid > 0
310 && (kill (owner->pid, 0) >= 0 || errno == EPERM) 408 && (kill (owner->pid, 0) >= 0 || errno == EPERM)
311 && (owner->boot_time == 0 409 && (owner->boot_time == 0
312 || owner->boot_time == get_boot_time ())) 410 || within_one_second (owner->boot_time, get_boot_time ())))
313 ret = 1; /* An existing process on this machine owns it. */ 411 ret = 1; /* An existing process on this machine owns it. */
314 /* The owner process is dead or has a strange pid (<=0), so try to 412 /* The owner process is dead or has a strange pid (<=0), so try to
315 zap the lockfile. */ 413 zap the lockfile. */