Mercurial > emacs
changeset 24349:b6c16b67b735
(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.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Fri, 19 Feb 1999 01:36:29 +0000 |
parents | 9365b6b93858 |
children | 1331218fcf2b |
files | src/filelock.c |
diffstat | 1 files changed, 106 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/filelock.c Fri Feb 19 01:34:48 1999 +0000 +++ b/src/filelock.c Fri Feb 19 01:36:29 1999 +0000 @@ -43,6 +43,7 @@ #include "buffer.h" #include "charset.h" #include "coding.h" +#include "systime.h" #include <time.h> #include <errno.h> @@ -94,18 +95,113 @@ static time_t boot_time; +extern Lisp_Object Vshell_file_name; + static time_t get_boot_time () { #ifdef BOOT_TIME struct utmp ut, *utp; + int fd; + EMACS_TIME time_before, after; + int counter; if (boot_time) return boot_time; - utmpname ("/var/log/wtmp"); + EMACS_GET_TIME (time_before); + + /* Try calculating the last boot time + from the uptime as obtained from /proc/uptime. */ + + while ((fd = open ("/proc/uptime", O_RDONLY)) >= 0) + { + char buf[BUFSIZ]; + int res; + double upsecs; + time_t uptime; + + read (fd, buf, BUFSIZ); + close (fd); + + res = sscanf (buf, "%lf", &upsecs); + + /* If the current time did not tick while we were getting the + uptime, we have a valid result. */ + EMACS_GET_TIME (after); + if (res == 1 && EMACS_SECS (after) == EMACS_SECS (time_before)) + { + boot_time = EMACS_SECS (time_before) - (time_t) upsecs; + return boot_time; + } + + /* Otherwise, try again to read the uptime. */ + time_before = after; + } + + /* Try to get boot time from the current wtmp file. */ + get_boot_time_1 ("/var/log/wtmp"); + + /* If we did not find a boot time in wtmp, look at wtmp, and so on. */ + for (counter = 0; counter < 20 && boot_time == 1; counter++) + { + char cmd_string[100]; + Lisp_Object tempname, filename; + int delete_flag = 0; + + filename = Qnil; + + sprintf (cmd_string, "/var/log/wtmp.%d", counter); + tempname = build_string (cmd_string); + if (! NILP (Ffile_exists_p (filename))) + filename = tempname; + else + { + sprintf (cmd_string, "/var/log/wtmp.%d.gz", counter); + tempname = build_string (cmd_string); + if (! NILP (Ffile_exists_p (tempname))) + { + Lisp_Object args[6]; + tempname = Fmake_temp_name (build_string ("wtmp")); + args[0] = Vshell_file_name; + args[1] = Qnil; + args[2] = Qnil; + args[3] = Qnil; + args[4] = build_string ("-c"); + sprintf (cmd_string, "gunzip < /var/log/wtmp.%d.gz > %s", + counter, XSTRING (tempname)->data); + args[5] = build_string (cmd_string); + Fcall_process (6, args); + filename = tempname; + delete_flag = 1; + } + } + + if (! NILP (filename)) + { + get_boot_time_1 (XSTRING (filename)->data); + if (delete_flag) + unlink (XSTRING (filename)->data); + } + } + + return boot_time; +#else + return 0; +#endif +} + +/* Try to get the boot time from wtmp file FILENAME. + This succeeds if that file contains a reboot record. + Success is indicated by setting BOOT_TIME. */ + +get_boot_time_1 (filename) + char *filename; +{ + struct utmp ut, *utp; + + utmpname (filename); setutent (); - boot_time = 1; while (1) { /* Find the next reboot record. */ @@ -123,11 +219,6 @@ break; } endutent (); - - return boot_time; -#else - return 0; -#endif } /* Here is the structure that stores information about a lock. */ @@ -218,7 +309,14 @@ return err == 0; } +/* Return 1 if times A and B are no more than one second apart. */ +int +within_one_second (a, b) + time_t a, b; +{ + return (a - b >= -1 && a - b <= 1); +} /* Return 0 if nobody owns the lock file LFNAME or the lock is obsolete, 1 if another process owns it (and set OWNER (if non-null) to info), @@ -309,7 +407,7 @@ else if (owner->pid > 0 && (kill (owner->pid, 0) >= 0 || errno == EPERM) && (owner->boot_time == 0 - || owner->boot_time == get_boot_time ())) + || within_one_second (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. */