comparison src/filelock.c @ 624:2bb7f23b7ea5

*** empty log message ***
author Jim Blandy <jimb@redhat.com>
date Fri, 01 May 1992 06:20:46 +0000
parents 65e7f842d017
children 40b255f55df3
comparison
equal deleted inserted replaced
623:347a8db13650 624:2bb7f23b7ea5
1 /* Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc. 1 /* Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
2 2
3 This file is part of GNU Emacs. 3 This file is part of GNU Emacs.
4 4
5 GNU Emacs is free software; you can redistribute it and/or modify 5 GNU Emacs is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option) 7 the Free Software Foundation; either version 2, or (at your option)
8 any later version. 8 any later version.
9 9
10 GNU Emacs is distributed in the hope that it will be useful, 10 GNU Emacs is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 #include "paths.h" 37 #include "paths.h"
38 #include "buffer.h" 38 #include "buffer.h"
39 39
40 extern int errno; 40 extern int errno;
41 41
42 extern char *egetenv ();
43
42 #ifdef CLASH_DETECTION 44 #ifdef CLASH_DETECTION
43 45
44 /* If system does not have symbolic links, it does not have lstat. 46 /* If system does not have symbolic links, it does not have lstat.
45 In that case, use ordinary stat instead. */ 47 In that case, use ordinary stat instead. */
46 48
47 #ifndef S_IFLNK 49 #ifndef S_IFLNK
48 #define lstat stat 50 #define lstat stat
49 #endif 51 #endif
52
53
54 /* The name of the directory in which we keep lock files, with a '/'
55 appended. */
56 char *lock_path;
57
58 /* The name of the file in the lock directory which is used to
59 arbitrate access to the entire directory. */
60 #define SUPERLOCK_NAME "!!!SuperLock!!!"
61
62 /* The path to the superlock file. This is SUPERLOCK_NAME appended to
63 lock_path. */
64 char *superlock_path;
65
66 /* Set LOCK to the name of the lock file for the filename FILE.
67 char *LOCK; Lisp_Object FILE; */
68 #define MAKE_LOCK_PATH (lock, file) \
69 (lock = (char *) alloca (XSTRING (file)->size + strlen (lock_path) + 1), \
70 fill_in_lock_file_name (lock, (file)))
71
72 fill_in_lock_file_name (lockfile, fn)
73 register char *lockfile;
74 register Lisp_Object fn;
75 {
76 register char *p;
77
78 strcpy (lockfile, lock_path);
79
80 p = lockfile + strlen (lockfile);
81
82 strcpy (p, XSTRING (fn)->data);
83
84 for (; *p; p++)
85 {
86 if (*p == '/')
87 *p = '!';
88 }
89 }
50 90
51 static Lisp_Object 91 static Lisp_Object
52 lock_file_owner_name (lfname) 92 lock_file_owner_name (lfname)
53 char *lfname; 93 char *lfname;
54 { 94 {
88 register Lisp_Object fn; 128 register Lisp_Object fn;
89 { 129 {
90 register Lisp_Object attack; 130 register Lisp_Object attack;
91 register char *lfname; 131 register char *lfname;
92 132
93 /* Create the name of the lock-file for file fn */ 133 MAKE_LOCK_PATH (lfname, fn);
94 lfname = (char *) alloca (XSTRING (fn)->size + strlen (PATH_LOCK) + 1); 134
95 fill_in_lock_file_name (lfname, fn); 135 /* See if this file is visited and has changed on disk since it was
96 136 visited. */
97 /* See if this file is visited and has changed on disk since it was visited. */
98 { 137 {
99 register Lisp_Object subject_buf = Fget_file_buffer (fn); 138 register Lisp_Object subject_buf = Fget_file_buffer (fn);
100 if (!NILP (subject_buf) 139 if (!NILP (subject_buf)
101 && NILP (Fverify_visited_file_modtime (subject_buf)) 140 && NILP (Fverify_visited_file_modtime (subject_buf))
102 && !NILP (Ffile_exists_p (fn))) 141 && !NILP (Ffile_exists_p (fn)))
114 if (!NILP (attack)) 153 if (!NILP (attack))
115 /* User says take the lock */ 154 /* User says take the lock */
116 { 155 {
117 lock_superlock (lfname); 156 lock_superlock (lfname);
118 lock_file_1 (lfname, O_WRONLY) ; 157 lock_file_1 (lfname, O_WRONLY) ;
119 unlink (PATH_SUPERLOCK); 158 unlink (superlock_path);
120 return; 159 return;
121 } 160 }
122 /* User says ignore the lock */ 161 /* User says ignore the lock */
123 }
124
125 fill_in_lock_file_name (lockfile, fn)
126 register char *lockfile;
127 register Lisp_Object fn;
128 {
129 register char *p;
130
131 strcpy (lockfile, PATH_LOCK);
132
133 p = lockfile + strlen (lockfile);
134
135 strcpy (p, XSTRING (fn)->data);
136
137 for (; *p; p++)
138 {
139 if (*p == '/')
140 *p = '!';
141 }
142 } 162 }
143 163
144 /* Lock the lock file named LFNAME. 164 /* Lock the lock file named LFNAME.
145 If MODE is O_WRONLY, we do so even if it is already locked. 165 If MODE is O_WRONLY, we do so even if it is already locked.
146 If MODE is O_WRONLY | O_EXCL | O_CREAT, we do so only if it is free. 166 If MODE is O_WRONLY | O_EXCL | O_CREAT, we do so only if it is free.
234 unlock_file (fn) 254 unlock_file (fn)
235 register Lisp_Object fn; 255 register Lisp_Object fn;
236 { 256 {
237 register char *lfname; 257 register char *lfname;
238 258
239 lfname = (char *) alloca (XSTRING (fn)->size + strlen (PATH_LOCK) + 1); 259 MAKE_LOCK_PATH (lfname, fn);
240 fill_in_lock_file_name (lfname, fn);
241 260
242 lock_superlock (lfname); 261 lock_superlock (lfname);
243 262
244 if (current_lock_owner_1 (lfname) == getpid ()) 263 if (current_lock_owner_1 (lfname) == getpid ())
245 unlink (lfname); 264 unlink (lfname);
246 265
247 unlink (PATH_SUPERLOCK); 266 unlink (superlock_path);
248 } 267 }
249 268
250 lock_superlock (lfname) 269 lock_superlock (lfname)
251 char *lfname; 270 char *lfname;
252 { 271 {
253 register int i, fd; 272 register int i, fd;
254 273
255 for (i = -20; i < 0 && (fd = open (PATH_SUPERLOCK, 274 for (i = -20; i < 0 && (fd = open (superlock_path,
256 O_WRONLY | O_EXCL | O_CREAT, 0666)) < 0; 275 O_WRONLY | O_EXCL | O_CREAT, 0666)) < 0;
257 i++) 276 i++)
258 { 277 {
259 if (errno != EEXIST) 278 if (errno != EEXIST)
260 return; 279 return;
261 sleep (1); 280 sleep (1);
262 } 281 }
263 if (fd >= 0) 282 if (fd >= 0)
264 { 283 {
265 #ifdef USG 284 #ifdef USG
266 chmod (PATH_SUPERLOCK, 0666); 285 chmod (superlock_path, 0666);
267 #else 286 #else
268 fchmod (fd, 0666); 287 fchmod (fd, 0666);
269 #endif 288 #endif
270 write (fd, lfname, strlen (lfname)); 289 write (fd, lfname, strlen (lfname));
271 close (fd); 290 close (fd);
339 register char *lfname; 358 register char *lfname;
340 int owner; 359 int owner;
341 360
342 fn = Fexpand_file_name (fn, Qnil); 361 fn = Fexpand_file_name (fn, Qnil);
343 362
344 /* Create the name of the lock-file for file filename */ 363 MAKE_LOCK_PATH (lfname, fn);
345 lfname = (char *) alloca (XSTRING (fn)->size + strlen (PATH_LOCK) + 1);
346 fill_in_lock_file_name (lfname, fn);
347 364
348 owner = current_lock_owner (lfname); 365 owner = current_lock_owner (lfname);
349 if (owner <= 0) 366 if (owner <= 0)
350 return (Qnil); 367 return (Qnil);
351 else if (owner == getpid ()) 368 else if (owner == getpid ())
352 return (Qt); 369 return (Qt);
353 370
354 return (lock_file_owner_name (lfname)); 371 return (lock_file_owner_name (lfname));
355 } 372 }
356 373
374
375 /* Initialization functions. */
376
377 init_filelock ()
378 {
379 lock_path = egetenv ("EMACSLOCKDIR");
380 if (! lock_path)
381 lock_path = PATH_LOCK;
382
383 /* Make sure it ends with a slash. */
384 if (lock_path[strlen (lock_path) - 1] != '/')
385 {
386 lock_path = strcpy ((char *) xmalloc (strlen (lock_path) + 2),
387 lock_path);
388 strcat (lock_path, "/");
389 }
390
391 superlock_path = (char *) xmalloc ((strlen (lock_path)
392 + sizeof (SUPERLOCK_NAME)));
393 strcpy (superlock_path, lock_path);
394 strcat (superlock_path, SUPERLOCK_NAME);
395 }
396
357 syms_of_filelock () 397 syms_of_filelock ()
358 { 398 {
359 defsubr (&Sunlock_buffer); 399 defsubr (&Sunlock_buffer);
360 defsubr (&Slock_buffer); 400 defsubr (&Slock_buffer);
361 defsubr (&Sfile_locked_p); 401 defsubr (&Sfile_locked_p);