(linenum→info "unix/slp.c:2238")

emacs/22.1/src/filelock.c

    1: /* Lock files for editing.
    2:    Copyright (C) 1985, 1986, 1987, 1993, 1994, 1996, 1998, 1999, 2000, 2001,
    3:                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    4: 
    5: This file is part of GNU Emacs.
    6: 
    7: GNU Emacs is free software; you can redistribute it and/or modify
    8: it under the terms of the GNU General Public License as published by
    9: the Free Software Foundation; either version 2, or (at your option)
   10: any later version.
   11: 
   12: GNU Emacs is distributed in the hope that it will be useful,
   13: but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: GNU General Public License for more details.
   16: 
   17: You should have received a copy of the GNU General Public License
   18: along with GNU Emacs; see the file COPYING.  If not, write to
   19: the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   20: Boston, MA 02110-1301, USA.  */
   21: 
   22: 
   23: #include <config.h>
   24: #include <sys/types.h>
   25: #include <sys/stat.h>
   26: #include <signal.h>
   27: #include <stdio.h>
   28: 
   29: #ifdef HAVE_PWD_H
   30: #include <pwd.h>
   31: #endif
   32: 
   33: #include <sys/file.h>
   34: #ifdef HAVE_FCNTL_H
   35: #include <fcntl.h>
   36: #endif
   37: #ifdef HAVE_STRING_H
   38: #include <string.h>
   39: #endif
   40: 
   41: #ifdef HAVE_UNISTD_H
   42: #include <unistd.h>
   43: #endif
   44: 
   45: #ifdef __FreeBSD__
   46: #include <sys/sysctl.h>
   47: #endif /* __FreeBSD__ */
   48: 
   49: #include <errno.h>
   50: #ifndef errno
   51: extern int errno;
   52: #endif
   53: 
   54: #include "lisp.h"
   55: #include "buffer.h"
   56: #include "charset.h"
   57: #include "coding.h"
   58: #include "systime.h"
   59: 
   60: /* The directory for writing temporary files.  */
   61: 
   62: Lisp_Object Vtemporary_file_directory;
   63: 
   64: #ifdef CLASH_DETECTION
   65: 
   66: #include <utmp.h>
   67: 
   68: #if !defined (S_ISLNK) && defined (S_IFLNK)
   69: #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
   70: #endif
   71: 
   72: /* A file whose last-modified time is just after the most recent boot.
   73:    Define this to be NULL to disable checking for this file.  */
   74: #ifndef BOOT_TIME_FILE
   75: #define BOOT_TIME_FILE "/var/run/random-seed"
   76: #endif
   77: 
   78: #ifndef WTMP_FILE
   79: #define WTMP_FILE "/var/log/wtmp"
   80: #endif
   81: 
   82: /* The strategy: to lock a file FN, create a symlink .#FN in FN's
   83:    directory, with link data `user@host.pid'.  This avoids a single
   84:    mount (== failure) point for lock files.
   85: 
   86:    When the host in the lock data is the current host, we can check if
   87:    the pid is valid with kill.
   88: 
   89:    Otherwise, we could look at a separate file that maps hostnames to
   90:    reboot times to see if the remote pid can possibly be valid, since we
   91:    don't want Emacs to have to communicate via pipes or sockets or
   92:    whatever to other processes, either locally or remotely; rms says
   93:    that's too unreliable.  Hence the separate file, which could
   94:    theoretically be updated by daemons running separately -- but this
   95:    whole idea is unimplemented; in practice, at least in our
   96:    environment, it seems such stale locks arise fairly infrequently, and
   97:    Emacs' standard methods of dealing with clashes suffice.
   98: 
   99:    We use symlinks instead of normal files because (1) they can be
  100:    stored more efficiently on the filesystem, since the kernel knows
  101:    they will be small, and (2) all the info about the lock can be read
  102:    in a single system call (readlink).  Although we could use regular
  103:    files to be useful on old systems lacking symlinks, nowadays
  104:    virtually all such systems are probably single-user anyway, so it
  105:    didn't seem worth the complication.
  106: 
  107:    Similarly, we don't worry about a possible 14-character limit on
  108:    file names, because those are all the same systems that don't have
  109:    symlinks.
  110: 
  111:    This is compatible with the locking scheme used by Interleaf (which
  112:    has contributed this implementation for Emacs), and was designed by
  113:    Ethan Jacobson, Kimbo Mundy, and others.
  114: 
  115:    --karl@cs.umb.edu/karl@hq.ileaf.com.  */
  116: 
  117: ^L
  118: /* Return the time of the last system boot.  */
  119: 
  120: static time_t boot_time;
  121: static int boot_time_initialized;
  122: 
  123: extern Lisp_Object Vshell_file_name;
  124: 
  125: #ifdef BOOT_TIME
  126: static void get_boot_time_1 P_ ((char *, int));
  127: #endif
  128: 
  129: static time_t
  130: get_boot_time ()
  131: {
  132: #if defined (BOOT_TIME) && ! defined (NO_WTMP_FILE)
  133:   int counter;
  134: #endif
  135: 
  136:   if (boot_time_initialized)
  137:     return boot_time;
  138:   boot_time_initialized = 1;
  139: 
  140: #if defined (CTL_KERN) && defined (KERN_BOOTTIME)
  141:   {
  142:     int mib[2];
  143:     size_t size;
  144:     struct timeval boottime_val;
  145: 
  146:     mib[0] = CTL_KERN;
  147:     mib[1] = KERN_BOOTTIME;
  148:     size = sizeof (boottime_val);
  149: 
  150:     if (sysctl (mib, 2, &boottime_val, &size, NULL, 0) >= 0)
  151:       {
  152:         boot_time = boottime_val.tv_sec;
  153:         return boot_time;
  154:       }
  155:   }
  156: #endif /* defined (CTL_KERN) && defined (KERN_BOOTTIME) */
  157: 
  158:   if (BOOT_TIME_FILE)
  159:     {
  160:       struct stat st;
  161:       if (stat (BOOT_TIME_FILE, &st) == 0)
  162:         {
  163:           boot_time = st.st_mtime;
  164:           return boot_time;
  165:         }
  166:     }
  167: 
  168: #if defined (BOOT_TIME) && ! defined (NO_WTMP_FILE)
  169: #ifndef CANNOT_DUMP
  170:   /* The utmp routines maintain static state.
  171:      Don't touch that state unless we are initialized,
  172:      since it might not survive dumping.  */
  173:   if (! initialized)
  174:     return boot_time;
  175: #endif /* not CANNOT_DUMP */
  176: 
  177:   /* Try to get boot time from utmp before wtmp,
  178:      since utmp is typically much smaller than wtmp.
  179:      Passing a null pointer causes get_boot_time_1
  180:      to inspect the default file, namely utmp.  */
  181:   get_boot_time_1 ((char *) 0, 0);
  182:   if (boot_time)
  183:     return boot_time;
  184: 
  185:   /* Try to get boot time from the current wtmp file.  */
  186:   get_boot_time_1 (WTMP_FILE, 1);
  187: 
  188:   /* If we did not find a boot time in wtmp, look at wtmp, and so on.  */
  189:   for (counter = 0; counter < 20 && ! boot_time; counter++)
  190:     {
  191:       char cmd_string[100];
  192:       Lisp_Object tempname, filename;
  193:       int delete_flag = 0;
  194: 
  195:       filename = Qnil;
  196: 
  197:       sprintf (cmd_string, "%s.%d", WTMP_FILE, counter);
  198:       tempname = build_string (cmd_string);
  199:       if (! NILP (Ffile_exists_p (tempname)))
  200:         filename = tempname;
  201:       else
  202:         {
  203:           sprintf (cmd_string, "%s.%d.gz", WTMP_FILE, counter);
  204:           tempname = build_string (cmd_string);
  205:           if (! NILP (Ffile_exists_p (tempname)))
  206:             {
  207:               Lisp_Object args[6];
  208: 
  209:               /* The utmp functions on mescaline.gnu.org accept only
  210:                  file names up to 8 characters long.  Choose a 2
  211:                  character long prefix, and call make_temp_file with
  212:                  second arg non-zero, so that it will add not more
  213:                  than 6 characters to the prefix.  */
  214:               tempname = Fexpand_file_name (build_string ("wt"),
  215:                                             Vtemporary_file_directory);
  216:               tempname = make_temp_name (tempname, 1);
  217:               args[0] = Vshell_file_name;
  218:               args[1] = Qnil;
  219:               args[2] = Qnil;
  220:               args[3] = Qnil;
  221:               args[4] = build_string ("-c");
  222:               sprintf (cmd_string, "gunzip < %s.%d.gz > %s",
  223:                        WTMP_FILE, counter, SDATA (tempname));
  224:               args[5] = build_string (cmd_string);
  225:               Fcall_process (6, args);
  226:               filename = tempname;
  227:               delete_flag = 1;
  228:             }
  229:         }
  230: 
  231:       if (! NILP (filename))
  232:         {
  233:           get_boot_time_1 (SDATA (filename), 1);
  234:           if (delete_flag)
  235:             unlink (SDATA (filename));
  236:         }
  237:     }
  238: 
  239:   return boot_time;
  240: #else
  241:   return 0;
  242: #endif
  243: }
  244: 
  245: #ifdef BOOT_TIME
  246: /* Try to get the boot time from wtmp file FILENAME.
  247:    This succeeds if that file contains a reboot record.
  248: 
  249:    If FILENAME is zero, use the same file as before;
  250:    if no FILENAME has ever been specified, this is the utmp file.
  251:    Use the newest reboot record if NEWEST is nonzero,
  252:    the first reboot record otherwise.
  253:    Ignore all reboot records on or before BOOT_TIME.
  254:    Success is indicated by setting BOOT_TIME to a larger value.  */
  255: 
  256: void
  257: get_boot_time_1 (filename, newest)
  258:      char *filename;
  259:      int newest;
  260: {
  261:   struct utmp ut, *utp;
  262:   int desc;
  263: 
  264:   if (filename)
  265:     {
  266:       /* On some versions of IRIX, opening a nonexistent file name
  267:          is likely to crash in the utmp routines.  */
  268:       desc = emacs_open (filename, O_RDONLY, 0);
  269:       if (desc < 0)
  270:         return;
  271: 
  272:       emacs_close (desc);
  273: 
  274:       utmpname (filename);
  275:     }
  276: 
  277:   setutent ();
  278: 
  279:   while (1)
  280:     {
  281:       /* Find the next reboot record.  */
  282:       ut.ut_type = BOOT_TIME;
  283:       utp = getutid (&ut);
  284:       if (! utp)
  285:         break;
  286:       /* Compare reboot times and use the newest one.  */
  287:       if (utp->ut_time > boot_time)
  288:         {
  289:           boot_time = utp->ut_time;
  290:           if (! newest)
  291:             break;
  292:         }
  293:       /* Advance on element in the file
  294:          so that getutid won't repeat the same one.  */
  295:       utp = getutent ();
  296:       if (! utp)
  297:         break;
  298:     }
  299:   endutent ();
  300: }
  301: #endif /* BOOT_TIME */
  302: ^L
  303: /* Here is the structure that stores information about a lock.  */
  304: 
  305: typedef struct
  306: {
  307:   char *user;
  308:   char *host;
  309:   unsigned long pid;
  310:   time_t boot_time;
  311: } lock_info_type;
  312: 
  313: /* When we read the info back, we might need this much more,
  314:    enough for decimal representation plus null.  */
  315: #define LOCK_PID_MAX (4 * sizeof (unsigned long))
  316: 
  317: /* Free the two dynamically-allocated pieces in PTR.  */
  318: #define FREE_LOCK_INFO(i) do { xfree ((i).user); xfree ((i).host); } while (0)
  319: 
  320: 
  321: /* Write the name of the lock file for FN into LFNAME.  Length will be
  322:    that of FN plus two more for the leading `.#' plus 1 for the
  323:    trailing period plus one for the digit after it plus one for the
  324:    null.  */
  325: #define MAKE_LOCK_NAME(lock, file) \
  326:   (lock = (char *) alloca (SBYTES (file) + 2 + 1 + 1 + 1), \
  327:    fill_in_lock_file_name (lock, (file)))
  328: 
  329: static void
  330: fill_in_lock_file_name (lockfile, fn)
  331:      register char *lockfile;
  332:      register Lisp_Object fn;
  333: {
  334:   register char *p;
  335:   struct stat st;
  336:   int count = 0;
  337: 
  338:   strcpy (lockfile, SDATA (fn));
  339: 
  340:   /* Shift the nondirectory part of the file name (including the null)
  341:      right two characters.  Here is one of the places where we'd have to
  342:      do something to support 14-character-max file names.  */
  343:   for (p = lockfile + strlen (lockfile); p != lockfile && *p != '/'; p--)
  344:     p[2] = *p;
  345: 
  346:   /* Insert the `.#'.  */
  347:   p[1] = '.';
  348:   p[2] = '#';
  349: 
  350:   p = p + strlen (p);
  351: 
  352:   while (lstat (lockfile, &st) == 0 && !S_ISLNK (st.st_mode))
  353:     {
  354:       if (count > 9)
  355:         {
  356:           *p = '\0';
  357:           return;
  358:         }
  359:       sprintf (p, ".%d", count++);
  360:     }
  361: }
  362: 
  363: /* Lock the lock file named LFNAME.
  364:    If FORCE is nonzero, we do so even if it is already locked.
  365:    Return 1 if successful, 0 if not.  */
  366: 
  367: static int
  368: lock_file_1 (lfname, force)
  369:      char *lfname;
  370:      int force;
  371: {
  372:   register int err;
  373:   time_t boot_time;
  374:   char *user_name;
  375:   char *host_name;
  376:   char *lock_info_str;
  377: 
  378:   /* Call this first because it can GC.  */
  379:   boot_time = get_boot_time ();
  380: 
  381:   if (STRINGP (Fuser_login_name (Qnil)))
  382:     user_name = (char *)SDATA (Fuser_login_name (Qnil));
  383:   else
  384:     user_name = "";
  385:   if (STRINGP (Fsystem_name ()))
  386:     host_name = (char *)SDATA (Fsystem_name ());
  387:   else
  388:     host_name = "";
  389:   lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
  390:                                   + LOCK_PID_MAX + 30);
  391: 
  392:   if (boot_time)
  393:     sprintf (lock_info_str, "%s@%s.%lu:%lu", user_name, host_name,
  394:              (unsigned long) getpid (), (unsigned long) boot_time);
  395:   else
  396:     sprintf (lock_info_str, "%s@%s.%lu", user_name, host_name,
  397:              (unsigned long) getpid ());
  398: 
  399:   err = symlink (lock_info_str, lfname);
  400:   if (errno == EEXIST && force)
  401:     {
  402:       unlink (lfname);
  403:       err = symlink (lock_info_str, lfname);
  404:     }
  405: 
  406:   return err == 0;
  407: }
  408: 
  409: /* Return 1 if times A and B are no more than one second apart.  */
  410: 
  411: int
  412: within_one_second (a, b)
  413:      time_t a, b;
  414: {
  415:   return (a - b >= -1 && a - b <= 1);
  416: }
  417: ^L
  418: /* Return 0 if nobody owns the lock file LFNAME or the lock is obsolete,
  419:    1 if another process owns it (and set OWNER (if non-null) to info),
  420:    2 if the current process owns it,
  421:    or -1 if something is wrong with the locking mechanism.  */
  422: 
  423: static int
  424: current_lock_owner (owner, lfname)
  425:      lock_info_type *owner;
  426:      char *lfname;
  427: {
  428: #ifndef index
  429:   extern char *rindex (), *index ();
  430: #endif
  431:   int len, ret;
  432:   int local_owner = 0;
  433:   char *at, *dot, *colon;
  434:   char *lfinfo = 0;
  435:   int bufsize = 50;
  436:   /* Read arbitrarily-long contents of symlink.  Similar code in
  437:      file-symlink-p in fileio.c.  */
  438:   do
  439:     {
  440:       bufsize *= 2;
  441:       lfinfo = (char *) xrealloc (lfinfo, bufsize);
  442:       errno = 0;
  443:       len = readlink (lfname, lfinfo, bufsize);
  444: #ifdef ERANGE
  445:       /* HP-UX reports ERANGE if the buffer is too small.  */
  446:       if (len == -1 && errno == ERANGE)
  447:         len = bufsize;
  448: #endif
  449:     }
  450:   while (len >= bufsize);
  451: 
  452:   /* If nonexistent lock file, all is well; otherwise, got strange error. */
  453:   if (len == -1)
  454:     {
  455:       xfree (lfinfo);
  456:       return errno == ENOENT ? 0 : -1;
  457:     }
  458: 
  459:   /* Link info exists, so `len' is its length.  Null terminate.  */
  460:   lfinfo[len] = 0;
  461: 
  462:   /* Even if the caller doesn't want the owner info, we still have to
  463:      read it to determine return value, so allocate it.  */
  464:   if (!owner)
  465:     {
  466:       owner = (lock_info_type *) alloca (sizeof (lock_info_type));
  467:       local_owner = 1;
  468:     }
  469: 
  470:   /* Parse USER@HOST.PID:BOOT_TIME.  If can't parse, return -1.  */
  471:   /* The USER is everything before the first @.  */
  472:   at = index (lfinfo, '@');
  473:   dot = rindex (lfinfo, '.');
  474:   if (!at || !dot)
  475:     {
  476:       xfree (lfinfo);
  477:       return -1;
  478:     }
  479:   len = at - lfinfo;
  480:   owner->user = (char *) xmalloc (len + 1);
  481:   strncpy (owner->user, lfinfo, len);
  482:   owner->user[len] = 0;
  483: 
  484:   /* The PID is everything from the last `.' to the `:'.  */
  485:   owner->pid = atoi (dot + 1);
  486:   colon = dot;
  487:   while (*colon && *colon != ':')
  488:     colon++;
  489:   /* After the `:', if there is one, comes the boot time.  */
  490:   if (*colon == ':')
  491:     owner->boot_time = atoi (colon + 1);
  492:   else
  493:     owner->boot_time = 0;
  494: 
  495:   /* The host is everything in between.  */
  496:   len = dot - at - 1;
  497:   owner->host = (char *) xmalloc (len + 1);
  498:   strncpy (owner->host, at + 1, len);
  499:   owner->host[len] = 0;
  500: 
  501:   /* We're done looking at the link info.  */
  502:   xfree (lfinfo);
  503: 
  504:   /* On current host?  */
  505:   if (STRINGP (Fsystem_name ())
  506:       && strcmp (owner->host, SDATA (Fsystem_name ())) == 0)
  507:     {
  508:       if (owner->pid == getpid ())
  509:         ret = 2; /* We own it.  */
  510:       else if (owner->pid > 0
  511:                && (kill (owner->pid, 0) >= 0 || errno == EPERM)
  512:                && (owner->boot_time == 0
  513:                    || within_one_second (owner->boot_time, get_boot_time ())))
  514:         ret = 1; /* An existing process on this machine owns it.  */
  515:       /* The owner process is dead or has a strange pid (<=0), so try to
  516:          zap the lockfile.  */
  517:       else if (unlink (lfname) < 0)
  518:         ret = -1;
  519:       else
  520:         ret = 0;
  521:     }
  522:   else
  523:     { /* If we wanted to support the check for stale locks on remote machines,
  524:          here's where we'd do it.  */
  525:       ret = 1;
  526:     }
  527: 
  528:   /* Avoid garbage.  */
  529:   if (local_owner || ret <= 0)
  530:     {
  531:       FREE_LOCK_INFO (*owner);
  532:     }
  533:   return ret;
  534: }
  535: 
  536: ^L
  537: /* Lock the lock named LFNAME if possible.
  538:    Return 0 in that case.
  539:    Return positive if some other process owns the lock, and info about
  540:      that process in CLASHER.
  541:    Return -1 if cannot lock for any other reason.  */
  542: 
  543: static int
  544: lock_if_free (clasher, lfname)
  545:      lock_info_type *clasher;
  546:      register char *lfname;
  547: {
  548:   while (lock_file_1 (lfname, 0) == 0)
  549:     {
  550:       int locker;
  551: 
  552:       if (errno != EEXIST)
  553:         return -1;
  554: 
  555:       locker = current_lock_owner (clasher, lfname);
  556:       if (locker == 2)
  557:         {
  558:           FREE_LOCK_INFO (*clasher);
  559:           return 0;   /* We ourselves locked it.  */
  560:         }
  561:       else if (locker == 1)
  562:         return 1;  /* Someone else has it.  */
  563:       else if (locker == -1)
  564:         return -1;   /* current_lock_owner returned strange error.  */
  565: 
  566:       /* We deleted a stale lock; try again to lock the file.  */
  567:     }
  568:   return 0;
  569: }
  570: 
  571: /* lock_file locks file FN,
  572:    meaning it serves notice on the world that you intend to edit that file.
  573:    This should be done only when about to modify a file-visiting
  574:    buffer previously unmodified.
  575:    Do not (normally) call this for a buffer already modified,
  576:    as either the file is already locked, or the user has already
  577:    decided to go ahead without locking.
  578: 
  579:    When this returns, either the lock is locked for us,
  580:    or the user has said to go ahead without locking.
  581: 
  582:    If the file is locked by someone else, this calls
  583:    ask-user-about-lock (a Lisp function) with two arguments,
  584:    the file name and info about the user who did the locking.
  585:    This function can signal an error, or return t meaning
  586:    take away the lock, or return nil meaning ignore the lock.  */
  587: 
  588: void
  589: lock_file (fn)
  590:      Lisp_Object fn;
  591: {
  592:   register Lisp_Object attack, orig_fn, encoded_fn;
  593:   register char *lfname, *locker;
  594:   lock_info_type lock_info;
  595:   struct gcpro gcpro1;
  596: 
  597:   /* Don't do locking while dumping Emacs.
  598:      Uncompressing wtmp files uses call-process, which does not work
  599:      in an uninitialized Emacs.  */
  600:   if (! NILP (Vpurify_flag))
  601:     return;
  602: 
  603:   orig_fn = fn;
  604:   GCPRO1 (fn);
  605:   fn =