2
2
* Copyright (c) 2005, Junio C Hamano
3
3
*/
4
4
5
- /*
6
- * State diagram and cleanup
7
- * -------------------------
8
- *
9
- * This module keeps track of all locked files in `lock_file_list` for
10
- * use at cleanup. This list and the `lock_file` objects that comprise
11
- * it must be kept in self-consistent states at all time, because the
12
- * program can be interrupted any time by a signal, in which case the
13
- * signal handler will walk through the list attempting to clean up
14
- * any open lock files.
15
- *
16
- * The possible states of a `lock_file` object are as follows:
17
- *
18
- * - Uninitialized. In this state the object's `on_list` field must be
19
- * zero but the rest of its contents need not be initialized. As
20
- * soon as the object is used in any way, it is irrevocably
21
- * registered in `lock_file_list`, and `on_list` is set.
22
- *
23
- * - Locked, lockfile open (after `hold_lock_file_for_update()`,
24
- * `hold_lock_file_for_append()`, or `reopen_lock_file()`). In this
25
- * state:
26
- *
27
- * - the lockfile exists
28
- * - `active` is set
29
- * - `filename` holds the filename of the lockfile
30
- * - `fd` holds a file descriptor open for writing to the lockfile
31
- * - `fp` holds a pointer to an open `FILE` object if and only if
32
- * `fdopen_lock_file()` has been called on the object
33
- * - `owner` holds the PID of the process that locked the file
34
- *
35
- * - Locked, lockfile closed (after successful `close_lock_file()`).
36
- * Same as the previous state, except that the lockfile is closed
37
- * and `fd` is -1.
38
- *
39
- * - Unlocked (after `commit_lock_file()`, `commit_lock_file_to()`,
40
- * `rollback_lock_file()`, a failed attempt to lock, or a failed
41
- * `close_lock_file()`). In this state:
42
- *
43
- * - `active` is unset
44
- * - `filename` is empty (usually, though there are transitory
45
- * states in which this condition doesn't hold). Client code should
46
- * *not* rely on the filename being empty in this state.
47
- * - `fd` is -1
48
- * - the object is left registered in the `lock_file_list`, and
49
- * `on_list` is set.
50
- *
51
- * A lockfile is owned by the process that created it. The `lock_file`
52
- * has an `owner` field that records the owner's PID. This field is
53
- * used to prevent a forked process from closing a lockfile created by
54
- * its parent.
55
- */
56
-
57
5
#include "cache.h"
58
6
#include "lockfile.h"
59
- #include "sigchain.h"
60
-
61
- static struct lock_file * volatile lock_file_list ;
62
-
63
- static void remove_lock_files (int skip_fclose )
64
- {
65
- pid_t me = getpid ();
66
-
67
- while (lock_file_list ) {
68
- if (lock_file_list -> owner == me ) {
69
- /* fclose() is not safe to call in a signal handler */
70
- if (skip_fclose )
71
- lock_file_list -> fp = NULL ;
72
- rollback_lock_file (lock_file_list );
73
- }
74
- lock_file_list = lock_file_list -> next ;
75
- }
76
- }
77
-
78
- static void remove_lock_files_on_exit (void )
79
- {
80
- remove_lock_files (0 );
81
- }
82
-
83
- static void remove_lock_files_on_signal (int signo )
84
- {
85
- remove_lock_files (1 );
86
- sigchain_pop (signo );
87
- raise (signo );
88
- }
89
7
90
8
/*
91
9
* path = absolute or relative path name
@@ -154,60 +72,17 @@ static void resolve_symlink(struct strbuf *path)
154
72
/* Make sure errno contains a meaningful value on error */
155
73
static int lock_file (struct lock_file * lk , const char * path , int flags )
156
74
{
157
- size_t pathlen = strlen (path );
158
-
159
- if (!lock_file_list ) {
160
- /* One-time initialization */
161
- sigchain_push_common (remove_lock_files_on_signal );
162
- atexit (remove_lock_files_on_exit );
163
- }
75
+ int fd ;
76
+ struct strbuf filename = STRBUF_INIT ;
164
77
165
- if (lk -> active )
166
- die ("BUG: cannot lock_file(\"%s\") using active struct lock_file" ,
167
- path );
168
- if (!lk -> on_list ) {
169
- /* Initialize *lk and add it to lock_file_list: */
170
- lk -> fd = -1 ;
171
- lk -> fp = NULL ;
172
- lk -> active = 0 ;
173
- lk -> owner = 0 ;
174
- strbuf_init (& lk -> filename , pathlen + LOCK_SUFFIX_LEN );
175
- lk -> next = lock_file_list ;
176
- lock_file_list = lk ;
177
- lk -> on_list = 1 ;
178
- } else if (lk -> filename .len ) {
179
- /* This shouldn't happen, but better safe than sorry. */
180
- die ("BUG: lock_file(\"%s\") called with improperly-reset lock_file object" ,
181
- path );
182
- }
78
+ strbuf_addstr (& filename , path );
79
+ if (!(flags & LOCK_NO_DEREF ))
80
+ resolve_symlink (& filename );
183
81
184
- if (flags & LOCK_NO_DEREF ) {
185
- strbuf_add_absolute_path (& lk -> filename , path );
186
- } else {
187
- struct strbuf resolved_path = STRBUF_INIT ;
188
-
189
- strbuf_add (& resolved_path , path , pathlen );
190
- resolve_symlink (& resolved_path );
191
- strbuf_add_absolute_path (& lk -> filename , resolved_path .buf );
192
- strbuf_release (& resolved_path );
193
- }
194
-
195
- strbuf_addstr (& lk -> filename , LOCK_SUFFIX );
196
- lk -> fd = open (lk -> filename .buf , O_RDWR | O_CREAT | O_EXCL , 0666 );
197
- if (lk -> fd < 0 ) {
198
- strbuf_reset (& lk -> filename );
199
- return -1 ;
200
- }
201
- lk -> owner = getpid ();
202
- lk -> active = 1 ;
203
- if (adjust_shared_perm (lk -> filename .buf )) {
204
- int save_errno = errno ;
205
- error ("cannot fix permission bits on %s" , lk -> filename .buf );
206
- rollback_lock_file (lk );
207
- errno = save_errno ;
208
- return -1 ;
209
- }
210
- return lk -> fd ;
82
+ strbuf_addstr (& filename , LOCK_SUFFIX );
83
+ fd = create_tempfile (& lk -> tempfile , filename .buf );
84
+ strbuf_release (& filename );
85
+ return fd ;
211
86
}
212
87
213
88
static int sleep_microseconds (long us )
@@ -353,109 +228,17 @@ int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
353
228
return fd ;
354
229
}
355
230
356
- FILE * fdopen_lock_file (struct lock_file * lk , const char * mode )
357
- {
358
- if (!lk -> active )
359
- die ("BUG: fdopen_lock_file() called for unlocked object" );
360
- if (lk -> fp )
361
- die ("BUG: fdopen_lock_file() called twice for file '%s'" , lk -> filename .buf );
362
-
363
- lk -> fp = fdopen (lk -> fd , mode );
364
- return lk -> fp ;
365
- }
366
-
367
- const char * get_lock_file_path (struct lock_file * lk )
368
- {
369
- if (!lk -> active )
370
- die ("BUG: get_lock_file_path() called for unlocked object" );
371
- return lk -> filename .buf ;
372
- }
373
-
374
- int get_lock_file_fd (struct lock_file * lk )
375
- {
376
- if (!lk -> active )
377
- die ("BUG: get_lock_file_fd() called for unlocked object" );
378
- return lk -> fd ;
379
- }
380
-
381
- FILE * get_lock_file_fp (struct lock_file * lk )
382
- {
383
- if (!lk -> active )
384
- die ("BUG: get_lock_file_fp() called for unlocked object" );
385
- return lk -> fp ;
386
- }
387
-
388
231
char * get_locked_file_path (struct lock_file * lk )
389
232
{
390
- if (!lk -> active )
391
- die ("BUG: get_locked_file_path() called for unlocked object" );
392
- if (lk -> filename .len <= LOCK_SUFFIX_LEN ||
393
- strcmp (lk -> filename .buf + lk -> filename .len - LOCK_SUFFIX_LEN , LOCK_SUFFIX ))
233
+ struct strbuf ret = STRBUF_INIT ;
234
+
235
+ strbuf_addstr (& ret , get_tempfile_path (& lk -> tempfile ));
236
+ if (ret .len <= LOCK_SUFFIX_LEN ||
237
+ strcmp (ret .buf + ret .len - LOCK_SUFFIX_LEN , LOCK_SUFFIX ))
394
238
die ("BUG: get_locked_file_path() called for malformed lock object" );
395
239
/* remove ".lock": */
396
- return xmemdupz (lk -> filename .buf , lk -> filename .len - LOCK_SUFFIX_LEN );
397
- }
398
-
399
- int close_lock_file (struct lock_file * lk )
400
- {
401
- int fd = lk -> fd ;
402
- FILE * fp = lk -> fp ;
403
- int err ;
404
-
405
- if (fd < 0 )
406
- return 0 ;
407
-
408
- lk -> fd = -1 ;
409
- if (fp ) {
410
- lk -> fp = NULL ;
411
-
412
- /*
413
- * Note: no short-circuiting here; we want to fclose()
414
- * in any case!
415
- */
416
- err = ferror (fp ) | fclose (fp );
417
- } else {
418
- err = close (fd );
419
- }
420
-
421
- if (err ) {
422
- int save_errno = errno ;
423
- rollback_lock_file (lk );
424
- errno = save_errno ;
425
- return -1 ;
426
- }
427
-
428
- return 0 ;
429
- }
430
-
431
- int reopen_lock_file (struct lock_file * lk )
432
- {
433
- if (0 <= lk -> fd )
434
- die (_ ("BUG: reopen a lockfile that is still open" ));
435
- if (!lk -> active )
436
- die (_ ("BUG: reopen a lockfile that has been committed" ));
437
- lk -> fd = open (lk -> filename .buf , O_WRONLY );
438
- return lk -> fd ;
439
- }
440
-
441
- int commit_lock_file_to (struct lock_file * lk , const char * path )
442
- {
443
- if (!lk -> active )
444
- die ("BUG: attempt to commit unlocked object to \"%s\"" , path );
445
-
446
- if (close_lock_file (lk ))
447
- return -1 ;
448
-
449
- if (rename (lk -> filename .buf , path )) {
450
- int save_errno = errno ;
451
- rollback_lock_file (lk );
452
- errno = save_errno ;
453
- return -1 ;
454
- }
455
-
456
- lk -> active = 0 ;
457
- strbuf_reset (& lk -> filename );
458
- return 0 ;
240
+ strbuf_setlen (& ret , ret .len - LOCK_SUFFIX_LEN );
241
+ return strbuf_detach (& ret , NULL );
459
242
}
460
243
461
244
int commit_lock_file (struct lock_file * lk )
@@ -471,15 +254,3 @@ int commit_lock_file(struct lock_file *lk)
471
254
free (result_path );
472
255
return 0 ;
473
256
}
474
-
475
- void rollback_lock_file (struct lock_file * lk )
476
- {
477
- if (!lk -> active )
478
- return ;
479
-
480
- if (!close_lock_file (lk )) {
481
- unlink_or_warn (lk -> filename .buf );
482
- lk -> active = 0 ;
483
- strbuf_reset (& lk -> filename );
484
- }
485
- }
0 commit comments