1: /* Copyright (C) 1985 Richard M. Stallman and Dick King
   2: 
   3: This file is part of GNU Emacs.
   4: 
   5: GNU Emacs is distributed in the hope that it will be useful,
   6: but WITHOUT ANY WARRANTY.  No author or distributor
   7: accepts responsibility to anyone for the consequences of using it
   8: or for whether it serves any particular purpose or works at all,
   9: unless he says so in writing.  Refer to the GNU Emacs General Public
  10: License for full details.
  11: 
  12: Everyone is granted permission to copy, modify and redistribute
  13: GNU Emacs, but only under the conditions described in the
  14: GNU Emacs General Public License.   A copy of this license is
  15: supposed to have been given to you along with GNU Emacs so you
  16: can know your rights and responsibilities.  It should be in a
  17: file named COPYING.  Among other things, the copyright notice
  18: and this notice must be preserved on all copies.  */
  19: 
  20: 
  21: #include "config.h"
  22: #include "lisp.h"
  23: #include "paths.h"
  24: #include "buffer.h"
  25: #include <sys/types.h>
  26: #include <sys/stat.h>
  27: #include <pwd.h>
  28: #include <errno.h>
  29: #include <sys/file.h>
  30: #ifdef USG
  31: #include <fcntl.h>
  32: #endif /* USG */
  33: 
  34: #ifdef CLASH_DETECTION
  35: 
  36: /* lock_file locks file fn,
  37:    meaning it serves notice on the world that you intend to edit that file.
  38:    This should be done only when about to modify a file-visiting
  39:    buffer previously unmodified.
  40:    Do not (normally) call lock_buffer for a buffer already modified,
  41:    as either the file is already locked, or the user has already
  42:    decided to go ahead without locking.
  43: 
  44:    When lock_buffer returns, either the lock is locked for us,
  45:    or the user has said to go ahead without locking.
  46: 
  47:    If the file is locked by someone else, lock_buffer calls
  48:    ask-user-about-lock (a Lisp function) with two arguments,
  49:    the file name and the name of the user who did the locking.
  50:    This function can signal an error, or return t meaning
  51:    take away the lock, or return nil meaning ignore the lock.  */
  52: 
  53: /* The lock file name is the file name with "/" replaced by "!"
  54:    and put in the Emacs lock directory.  */
  55: /* (ie., /ka/king/junk.tex -> /!/!ka!king!junk.tex). */
  56: 
  57: void
  58: lock_file (fn)
  59:      register Lisp_Object fn;
  60: {
  61:   register int fd;
  62:   register Lisp_Object attack;
  63:   register char *lfname;
  64:   struct stat s;
  65:   struct passwd *the_pw;
  66:   extern struct passwd *getpwuid ();
  67: 
  68:   /* Create the name of the lock-file for file fn */
  69:   lfname = (char *) alloca (XSTRING (fn)->size + strlen (PATH_LOCK) + 1);
  70:   fill_in_lock_file_name (lfname, fn);
  71: 
  72:   /* Try to lock the lock. */
  73:   if (lock_if_free (lfname) <= 0)
  74:     /* Return now if we have locked it, or if lock dir does not exist */
  75:     return;
  76: 
  77:   /* Else consider breaking the lock */
  78:   the_pw = 0;
  79:   if (lstat (lfname, &s) == 0)
  80:     the_pw = getpwuid (s.st_uid);
  81:   attack = call2 (intern ("ask-user-about-lock"), fn,
  82:           the_pw == 0 ? Qnil : build_string (the_pw->pw_name));
  83:   if (!NULL (attack))
  84:     /* User says take the lock */
  85:     {
  86:       lock_superlock (lfname);
  87:       lock_file_1 (lfname, O_WRONLY) ;
  88:       unlink (PATH_SUPERLOCK);
  89:       return;
  90:     }
  91:   /* User says ignore the lock */
  92: }
  93: 
  94: fill_in_lock_file_name (lockfile, fn)
  95:      register char *lockfile;
  96:      register Lisp_Object fn;
  97: {
  98:   register char *p;
  99: 
 100:   strcpy (lockfile, PATH_LOCK);
 101: 
 102:   p = lockfile + strlen (lockfile);
 103: 
 104:   strcpy (p, XSTRING (fn)->data);
 105: 
 106:   for (; *p; p++)
 107:     {
 108:       if (*p == '/')
 109:     *p = '!';
 110:     }
 111: }
 112: 
 113: /* Lock the lock file named LFNAME.
 114:    If MODE is O_WRONLY, we do so even if it is already locked.
 115:    If MODE is O_WRONLY | O_EXCL | O_CREAT, we do so only if it is free.
 116:    Return 1 if successful, 0 if not.  */
 117: 
 118: int
 119: lock_file_1 (lfname, mode)
 120:      int mode; char *lfname;
 121: {
 122:   register int fd;
 123:   char buf[20];
 124: 
 125:   if ((fd = open (lfname, mode, 0666)) >= 0)
 126:     {
 127:       fchmod (fd, 0666);
 128:       sprintf (buf, "%d ", getpid ());
 129:       write (fd, buf, strlen (buf));
 130:       close (fd);
 131:       return 1;
 132:     }
 133:   else
 134:     return 0;
 135: }
 136: 
 137: /* Lock the lock named LFNAME if possible.
 138:    Return 0 in that case.
 139:    Return 1 if lock is really locked by someone else.
 140:    Return -1 if cannot lock for any other reason.  */
 141: 
 142: int
 143: lock_if_free (lfname)
 144:      register char *lfname;
 145: {
 146:   register int clasher;
 147:   extern int errno;
 148: 
 149:   while (lock_file_1 (lfname, O_WRONLY | O_EXCL | O_CREAT) == 0)
 150:     {
 151:       if (errno != EEXIST)
 152:     return -1;
 153:       clasher = current_lock_owner (lfname);
 154:       if (clasher == 0 || (kill (clasher, 0) < 0 && errno == ESRCH))
 155:     {
 156:       if (unlink (lfname) < 0)
 157:         return -1;
 158:       /* If we delete the lock successfully, try again to lock.  */
 159:     }
 160:       else
 161:     return (clasher != getpid ());
 162:      }
 163:   return 0;
 164: }
 165: 
 166: int
 167: current_lock_owner (lfname)
 168:      char *lfname;
 169: {
 170:   register int fd;
 171:   char buf[20];
 172: 
 173:   fd = open (lfname, O_RDONLY, 0666);
 174:   if (fd < 0)
 175:     return 0;
 176: 
 177:   if (read (fd, buf, sizeof buf) <= 0)
 178:     return 0;
 179:   close (fd);
 180:   return atoi (buf);
 181: }
 182: 
 183: void
 184: unlock_file (fn)
 185:      register Lisp_Object fn;
 186: {
 187:   register char *lfname;
 188: 
 189:   lfname = (char *) alloca (XSTRING (fn)->size + strlen (PATH_LOCK) + 1);
 190:   fill_in_lock_file_name (lfname, fn);
 191: 
 192:   lock_superlock (lfname);
 193: 
 194:   if (current_lock_owner (lfname) == getpid ())
 195:     unlink (lfname);
 196: 
 197:   unlink (PATH_SUPERLOCK);
 198: }
 199: 
 200: lock_superlock (lfname)
 201:      char *lfname;
 202: {
 203:   register int i, fd;
 204:   extern int errno;
 205: 
 206:   for (i = -20; i < 0 && (fd = open (PATH_SUPERLOCK,
 207:                      O_WRONLY | O_EXCL | O_CREAT, 0666)) < 0;
 208:        i++)
 209:     {
 210:       if (errno != EEXIST)
 211:     return;
 212:       sleep (1);
 213:     }
 214:   if (fd >= 0)
 215:     {
 216:       fchmod (fd, 0666);
 217:       write (fd, lfname, strlen (lfname));
 218:       close (fd);
 219:     }
 220: }
 221: 
 222: void
 223: unlock_all_files ()
 224: {
 225:   register Lisp_Object tail;
 226:   register struct buffer *b;
 227: 
 228:   for (tail = Vbuffer_alist; XGCTYPE (tail) == Lisp_Cons;
 229:        tail = XCONS (tail)->cdr)
 230:     {
 231:       b = XBUFFER (XCONS (XCONS (tail)->car)->cdr);
 232:       if (!NULL (b->filename)
 233:       && b->save_modified < b->text.modified)
 234:     unlock_file (b->filename);
 235:     }
 236: }
 237: 
 238: DEFUN ("lock-buffer", Flock_buffer, Slock_buffer,
 239:   0, 1, 0,
 240:   "Locks FILE, if current buffer is modified.\n\
 241: FILE defaults to current buffer's visited file,\n\
 242: or else nothing is done if current buffer isn't visiting a file.")
 243:   (fn)
 244:      Lisp_Object fn;
 245: {
 246:   if (NULL (fn))
 247:     fn = bf_cur->filename;
 248:   else
 249:     CHECK_STRING (fn, 0);
 250:   if (bf_cur->save_modified < bf_modified
 251:       && !NULL (fn))
 252:     lock_file (fn);
 253:   return Qnil;
 254: }
 255: 
 256: DEFUN ("unlock-buffer", Funlock_buffer, Sunlock_buffer,
 257:   0, 0, 0,
 258:  "Unlocks the file visited in the current buffer,\n\
 259: if it should normally be locked.")
 260:   ()
 261: {
 262:   if (bf_cur->save_modified < bf_modified
 263:       && !NULL (bf_cur->filename))
 264:     unlock_file (bf_cur->filename);
 265:   return Qnil;
 266: }
 267: 
 268: syms_of_filelock ()
 269: {
 270:   defsubr (&Sunlock_buffer);
 271:   defsubr (&Slock_buffer);
 272: }
 273: 
 274: #endif /* CLASH_DETECTION */

Defined functions

DEFUN defined in line 256; never used
current_lock_owner defined in line 166; used 2 times
fill_in_lock_file_name defined in line 94; used 2 times
lock_file_1 defined in line 118; used 2 times
lock_if_free defined in line 142; used 1 times
  • in line 73
lock_superlock defined in line 200; used 2 times
syms_of_filelock defined in line 268; used 1 times
unlock_all_files defined in line 222; used 2 times
unlock_file defined in line 183; used 8 times
Last modified: 1986-02-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1427
Valid CSS Valid XHTML 1.0 Strict