Mercurial > emacs
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); |