]> git.ipfire.org Git - thirdparty/git.git/blame - lockfile.c
wt-status: exit early using goto in wt_shortstatus_print_tracking()
[thirdparty/git.git] / lockfile.c
CommitLineData
021b6e45
JH
1/*
2 * Copyright (c) 2005, Junio C Hamano
3 */
021b6e45 4#include "cache.h"
697cc8ef 5#include "lockfile.h"
4a16d072 6#include "sigchain.h"
021b6e45 7
2091c506 8static struct lock_file *volatile lock_file_list;
021b6e45 9
013870cd 10static void remove_lock_files(int skip_fclose)
021b6e45 11{
5e635e39
JH
12 pid_t me = getpid();
13
021b6e45 14 while (lock_file_list) {
013870cd
MH
15 if (lock_file_list->owner == me) {
16 /* fclose() is not safe to call in a signal handler */
17 if (skip_fclose)
18 lock_file_list->fp = NULL;
a1754bcc 19 rollback_lock_file(lock_file_list);
013870cd 20 }
021b6e45
JH
21 lock_file_list = lock_file_list->next;
22 }
23}
24
013870cd
MH
25static void remove_lock_files_on_exit(void)
26{
27 remove_lock_files(0);
28}
29
316683bd 30static void remove_lock_files_on_signal(int signo)
021b6e45 31{
013870cd 32 remove_lock_files(1);
4a16d072 33 sigchain_pop(signo);
021b6e45
JH
34 raise(signo);
35}
36
5d5a7a67 37/*
0c0d6e86 38 * path = absolute or relative path name
5d5a7a67 39 *
0c0d6e86
MH
40 * Remove the last path name element from path (leaving the preceding
41 * "/", if any). If path is empty or the root directory ("/"), set
42 * path to the empty string.
5d5a7a67 43 */
0c0d6e86 44static void trim_last_path_component(struct strbuf *path)
5d5a7a67 45{
0c0d6e86 46 int i = path->len;
5d5a7a67
BS
47
48 /* back up past trailing slashes, if any */
0c0d6e86
MH
49 while (i && path->buf[i - 1] == '/')
50 i--;
5d5a7a67
BS
51
52 /*
0c0d6e86
MH
53 * then go backwards until a slash, or the beginning of the
54 * string
5d5a7a67 55 */
0c0d6e86
MH
56 while (i && path->buf[i - 1] != '/')
57 i--;
58
59 strbuf_setlen(path, i);
5d5a7a67
BS
60}
61
62
63/* We allow "recursive" symbolic links. Only within reason, though */
64#define MAXDEPTH 5
65
66/*
6cad8053 67 * path contains a path that might be a symlink.
5d5a7a67 68 *
6cad8053
MH
69 * If path is a symlink, attempt to overwrite it with a path to the
70 * real file or directory (which may or may not exist), following a
71 * chain of symlinks if necessary. Otherwise, leave path unmodified.
5d5a7a67 72 *
6cad8053
MH
73 * This is a best-effort routine. If an error occurs, path will
74 * either be left unmodified or will name a different symlink in a
75 * symlink chain that started with the original path.
5d5a7a67 76 */
6cad8053 77static void resolve_symlink(struct strbuf *path)
5d5a7a67
BS
78{
79 int depth = MAXDEPTH;
5025d845 80 static struct strbuf link = STRBUF_INIT;
5d5a7a67
BS
81
82 while (depth--) {
6cad8053 83 if (strbuf_readlink(&link, path->buf, path->len) < 0)
5025d845 84 break;
5d5a7a67 85
6cad8053 86 if (is_absolute_path(link.buf))
5d5a7a67 87 /* absolute path simply replaces p */
6cad8053 88 strbuf_reset(path);
0c0d6e86 89 else
5d5a7a67 90 /*
5025d845 91 * link is a relative path, so replace the
5d5a7a67
BS
92 * last element of p with it.
93 */
0c0d6e86 94 trim_last_path_component(path);
6cad8053
MH
95
96 strbuf_addbuf(path, &link);
5d5a7a67 97 }
5025d845 98 strbuf_reset(&link);
5d5a7a67
BS
99}
100
447ff1bf 101/* Make sure errno contains a meaningful value on error */
acd3b9ec 102static int lock_file(struct lock_file *lk, const char *path, int flags)
021b6e45 103{
6cad8053 104 size_t pathlen = strlen(path);
2fbd4f92 105
04e57d4d
MH
106 if (!lock_file_list) {
107 /* One-time initialization */
316683bd 108 sigchain_push_common(remove_lock_files_on_signal);
013870cd 109 atexit(remove_lock_files_on_exit);
04e57d4d
MH
110 }
111
707103fd
MH
112 if (lk->active)
113 die("BUG: cannot lock_file(\"%s\") using active struct lock_file",
114 path);
04e57d4d
MH
115 if (!lk->on_list) {
116 /* Initialize *lk and add it to lock_file_list: */
117 lk->fd = -1;
013870cd 118 lk->fp = NULL;
707103fd 119 lk->active = 0;
04e57d4d 120 lk->owner = 0;
6cad8053 121 strbuf_init(&lk->filename, pathlen + LOCK_SUFFIX_LEN);
04e57d4d
MH
122 lk->next = lock_file_list;
123 lock_file_list = lk;
124 lk->on_list = 1;
cf6950d3
MH
125 } else if (lk->filename.len) {
126 /* This shouldn't happen, but better safe than sorry. */
127 die("BUG: lock_file(\"%s\") called with improperly-reset lock_file object",
128 path);
04e57d4d
MH
129 }
130
fa137f67
NTND
131 if (flags & LOCK_NO_DEREF) {
132 strbuf_add_absolute_path(&lk->filename, path);
133 } else {
134 struct strbuf resolved_path = STRBUF_INIT;
135
136 strbuf_add(&resolved_path, path, pathlen);
137 resolve_symlink(&resolved_path);
138 strbuf_add_absolute_path(&lk->filename, resolved_path.buf);
139 strbuf_release(&resolved_path);
140 }
141
cf6950d3
MH
142 strbuf_addstr(&lk->filename, LOCK_SUFFIX);
143 lk->fd = open(lk->filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666);
e31e949b 144 if (lk->fd < 0) {
cf6950d3 145 strbuf_reset(&lk->filename);
2fbd4f92 146 return -1;
447ff1bf 147 }
e31e949b 148 lk->owner = getpid();
707103fd 149 lk->active = 1;
cf6950d3 150 if (adjust_shared_perm(lk->filename.buf)) {
e31e949b 151 int save_errno = errno;
cf6950d3 152 error("cannot fix permission bits on %s", lk->filename.buf);
e31e949b
MH
153 rollback_lock_file(lk);
154 errno = save_errno;
155 return -1;
021b6e45 156 }
4723ee99 157 return lk->fd;
021b6e45
JH
158}
159
044b6a9e
MH
160/*
161 * Constants defining the gaps between attempts to lock a file. The
162 * first backoff period is approximately INITIAL_BACKOFF_MS
163 * milliseconds. The longest backoff period is approximately
164 * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds.
165 */
166#define INITIAL_BACKOFF_MS 1L
167#define BACKOFF_MAX_MULTIPLIER 1000
168
169/*
170 * Try locking path, retrying with quadratic backoff for at least
171 * timeout_ms milliseconds. If timeout_ms is 0, try locking the file
172 * exactly once. If timeout_ms is -1, try indefinitely.
173 */
174static int lock_file_timeout(struct lock_file *lk, const char *path,
175 int flags, long timeout_ms)
176{
177 int n = 1;
178 int multiplier = 1;
a8a17756 179 long remaining_ms = 0;
044b6a9e
MH
180 static int random_initialized = 0;
181
182 if (timeout_ms == 0)
183 return lock_file(lk, path, flags);
184
185 if (!random_initialized) {
1e9676ec 186 srand((unsigned int)getpid());
044b6a9e
MH
187 random_initialized = 1;
188 }
189
a8a17756
JS
190 if (timeout_ms > 0)
191 remaining_ms = timeout_ms;
044b6a9e
MH
192
193 while (1) {
a8a17756 194 long backoff_ms, wait_ms;
044b6a9e
MH
195 int fd;
196
197 fd = lock_file(lk, path, flags);
198
199 if (fd >= 0)
200 return fd; /* success */
201 else if (errno != EEXIST)
202 return -1; /* failure other than lock held */
a8a17756 203 else if (timeout_ms > 0 && remaining_ms <= 0)
044b6a9e
MH
204 return -1; /* failure due to timeout */
205
206 backoff_ms = multiplier * INITIAL_BACKOFF_MS;
207 /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
a8a17756 208 wait_ms = (750 + rand() % 500) * backoff_ms / 1000;
30f8160d 209 sleep_millisec(wait_ms);
a8a17756 210 remaining_ms -= wait_ms;
044b6a9e
MH
211
212 /* Recursion: (n+1)^2 = n^2 + 2n + 1 */
213 multiplier += 2*n + 1;
214 if (multiplier > BACKOFF_MAX_MULTIPLIER)
215 multiplier = BACKOFF_MAX_MULTIPLIER;
216 else
217 n++;
218 }
219}
220
6af926e8 221void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
e43a6fd3 222{
bdfd739d 223 if (err == EEXIST) {
6af926e8 224 strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
e43a6fd3
MM
225 "If no other git process is currently running, this probably means a\n"
226 "git process crashed in this repository earlier. Make sure no other git\n"
227 "process is running and remove the file manually to continue.",
e2a57aac 228 absolute_path(path), strerror(err));
1b018fd9 229 } else
6af926e8 230 strbuf_addf(buf, "Unable to create '%s.lock': %s",
e2a57aac 231 absolute_path(path), strerror(err));
1b018fd9
MV
232}
233
e197c218 234NORETURN void unable_to_lock_die(const char *path, int err)
1b018fd9 235{
6af926e8
RS
236 struct strbuf buf = STRBUF_INIT;
237
238 unable_to_lock_message(path, err, &buf);
239 die("%s", buf.buf);
e43a6fd3
MM
240}
241
447ff1bf 242/* This should return a meaningful errno on failure */
044b6a9e
MH
243int hold_lock_file_for_update_timeout(struct lock_file *lk, const char *path,
244 int flags, long timeout_ms)
40aaae88 245{
044b6a9e 246 int fd = lock_file_timeout(lk, path, flags, timeout_ms);
acd3b9ec 247 if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
e197c218 248 unable_to_lock_die(path, errno);
40aaae88
JH
249 return fd;
250}
251
acd3b9ec 252int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
ea3cd5c7
DB
253{
254 int fd, orig_fd;
255
acd3b9ec 256 fd = lock_file(lk, path, flags);
ea3cd5c7 257 if (fd < 0) {
acd3b9ec 258 if (flags & LOCK_DIE_ON_ERROR)
e197c218 259 unable_to_lock_die(path, errno);
ea3cd5c7
DB
260 return fd;
261 }
262
263 orig_fd = open(path, O_RDONLY);
264 if (orig_fd < 0) {
265 if (errno != ENOENT) {
4d423a3e
MH
266 int save_errno = errno;
267
acd3b9ec 268 if (flags & LOCK_DIE_ON_ERROR)
ea3cd5c7 269 die("cannot open '%s' for copying", path);
ebb8e380 270 rollback_lock_file(lk);
4d423a3e
MH
271 error("cannot open '%s' for copying", path);
272 errno = save_errno;
273 return -1;
ea3cd5c7
DB
274 }
275 } else if (copy_fd(orig_fd, fd)) {
4d423a3e
MH
276 int save_errno = errno;
277
acd3b9ec 278 if (flags & LOCK_DIE_ON_ERROR)
00b7cbfc 279 die("failed to prepare '%s' for appending", path);
b29763aa 280 close(orig_fd);
ebb8e380 281 rollback_lock_file(lk);
4d423a3e 282 errno = save_errno;
ea3cd5c7 283 return -1;
b29763aa
SP
284 } else {
285 close(orig_fd);
ea3cd5c7
DB
286 }
287 return fd;
288}
289
013870cd
MH
290FILE *fdopen_lock_file(struct lock_file *lk, const char *mode)
291{
292 if (!lk->active)
293 die("BUG: fdopen_lock_file() called for unlocked object");
294 if (lk->fp)
295 die("BUG: fdopen_lock_file() called twice for file '%s'", lk->filename.buf);
296
297 lk->fp = fdopen(lk->fd, mode);
298 return lk->fp;
299}
300
ec38b4e4
MH
301char *get_locked_file_path(struct lock_file *lk)
302{
303 if (!lk->active)
304 die("BUG: get_locked_file_path() called for unlocked object");
305 if (lk->filename.len <= LOCK_SUFFIX_LEN)
306 die("BUG: get_locked_file_path() called for malformed lock object");
307 return xmemdupz(lk->filename.buf, lk->filename.len - LOCK_SUFFIX_LEN);
308}
309
d6cf61bf
BC
310int close_lock_file(struct lock_file *lk)
311{
312 int fd = lk->fd;
013870cd
MH
313 FILE *fp = lk->fp;
314 int err;
419f0c0f
MH
315
316 if (fd < 0)
317 return 0;
318
d6cf61bf 319 lk->fd = -1;
013870cd
MH
320 if (fp) {
321 lk->fp = NULL;
322
323 /*
324 * Note: no short-circuiting here; we want to fclose()
325 * in any case!
326 */
327 err = ferror(fp) | fclose(fp);
328 } else {
329 err = close(fd);
330 }
331
332 if (err) {
8e86c155
MH
333 int save_errno = errno;
334 rollback_lock_file(lk);
335 errno = save_errno;
336 return -1;
337 }
013870cd 338
8e86c155 339 return 0;
d6cf61bf
BC
340}
341
93dcaea2
JH
342int reopen_lock_file(struct lock_file *lk)
343{
344 if (0 <= lk->fd)
345 die(_("BUG: reopen a lockfile that is still open"));
707103fd 346 if (!lk->active)
93dcaea2 347 die(_("BUG: reopen a lockfile that has been committed"));
cf6950d3 348 lk->fd = open(lk->filename.buf, O_WRONLY);
93dcaea2
JH
349 return lk->fd;
350}
351
751baced 352int commit_lock_file_to(struct lock_file *lk, const char *path)
021b6e45 353{
707103fd 354 if (!lk->active)
751baced 355 die("BUG: attempt to commit unlocked object to \"%s\"", path);
8a1c7533 356
419f0c0f 357 if (close_lock_file(lk))
d6cf61bf 358 return -1;
4f4713df 359
751baced 360 if (rename(lk->filename.buf, path)) {
1b1648f4
MH
361 int save_errno = errno;
362 rollback_lock_file(lk);
363 errno = save_errno;
d6cf61bf 364 return -1;
1b1648f4
MH
365 }
366
707103fd 367 lk->active = 0;
cf6950d3 368 strbuf_reset(&lk->filename);
d6cf61bf 369 return 0;
021b6e45
JH
370}
371
751baced 372int commit_lock_file(struct lock_file *lk)
30ca07a2 373{
751baced
MH
374 static struct strbuf result_file = STRBUF_INIT;
375 int err;
376
377 if (!lk->active)
378 die("BUG: attempt to commit unlocked object");
379
380 if (lk->filename.len <= LOCK_SUFFIX_LEN ||
381 strcmp(lk->filename.buf + lk->filename.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
382 die("BUG: lockfile filename corrupt");
383
384 /* remove ".lock": */
385 strbuf_add(&result_file, lk->filename.buf,
386 lk->filename.len - LOCK_SUFFIX_LEN);
387 err = commit_lock_file_to(lk, result_file.buf);
388 strbuf_reset(&result_file);
389 return err;
30ca07a2
JH
390}
391
021b6e45
JH
392void rollback_lock_file(struct lock_file *lk)
393{
707103fd 394 if (!lk->active)
9085f8e2
MH
395 return;
396
8e86c155 397 if (!close_lock_file(lk)) {
cf6950d3 398 unlink_or_warn(lk->filename.buf);
707103fd 399 lk->active = 0;
cf6950d3 400 strbuf_reset(&lk->filename);
4723ee99 401 }
021b6e45 402}