tempfile: remove deactivated list entries
[git/git.git] / lockfile.c
CommitLineData
021b6e45
JH
1/*
2 * Copyright (c) 2005, Junio C Hamano
3 */
2db69de8 4
021b6e45 5#include "cache.h"
697cc8ef 6#include "lockfile.h"
021b6e45 7
5d5a7a67 8/*
0c0d6e86 9 * path = absolute or relative path name
5d5a7a67 10 *
0c0d6e86
MH
11 * Remove the last path name element from path (leaving the preceding
12 * "/", if any). If path is empty or the root directory ("/"), set
13 * path to the empty string.
5d5a7a67 14 */
0c0d6e86 15static void trim_last_path_component(struct strbuf *path)
5d5a7a67 16{
0c0d6e86 17 int i = path->len;
5d5a7a67
BS
18
19 /* back up past trailing slashes, if any */
0c0d6e86
MH
20 while (i && path->buf[i - 1] == '/')
21 i--;
5d5a7a67
BS
22
23 /*
0c0d6e86
MH
24 * then go backwards until a slash, or the beginning of the
25 * string
5d5a7a67 26 */
0c0d6e86
MH
27 while (i && path->buf[i - 1] != '/')
28 i--;
29
30 strbuf_setlen(path, i);
5d5a7a67
BS
31}
32
33
34/* We allow "recursive" symbolic links. Only within reason, though */
35#define MAXDEPTH 5
36
37/*
6cad8053 38 * path contains a path that might be a symlink.
5d5a7a67 39 *
6cad8053
MH
40 * If path is a symlink, attempt to overwrite it with a path to the
41 * real file or directory (which may or may not exist), following a
42 * chain of symlinks if necessary. Otherwise, leave path unmodified.
5d5a7a67 43 *
6cad8053
MH
44 * This is a best-effort routine. If an error occurs, path will
45 * either be left unmodified or will name a different symlink in a
46 * symlink chain that started with the original path.
5d5a7a67 47 */
6cad8053 48static void resolve_symlink(struct strbuf *path)
5d5a7a67
BS
49{
50 int depth = MAXDEPTH;
5025d845 51 static struct strbuf link = STRBUF_INIT;
5d5a7a67
BS
52
53 while (depth--) {
6cad8053 54 if (strbuf_readlink(&link, path->buf, path->len) < 0)
5025d845 55 break;
5d5a7a67 56
6cad8053 57 if (is_absolute_path(link.buf))
5d5a7a67 58 /* absolute path simply replaces p */
6cad8053 59 strbuf_reset(path);
0c0d6e86 60 else
5d5a7a67 61 /*
5025d845 62 * link is a relative path, so replace the
5d5a7a67
BS
63 * last element of p with it.
64 */
0c0d6e86 65 trim_last_path_component(path);
6cad8053
MH
66
67 strbuf_addbuf(path, &link);
5d5a7a67 68 }
5025d845 69 strbuf_reset(&link);
5d5a7a67
BS
70}
71
447ff1bf 72/* Make sure errno contains a meaningful value on error */
acd3b9ec 73static int lock_file(struct lock_file *lk, const char *path, int flags)
021b6e45 74{
1a9d15db
MH
75 int fd;
76 struct strbuf filename = STRBUF_INIT;
04e57d4d 77
1a9d15db
MH
78 strbuf_addstr(&filename, path);
79 if (!(flags & LOCK_NO_DEREF))
80 resolve_symlink(&filename);
fa137f67 81
1a9d15db
MH
82 strbuf_addstr(&filename, LOCK_SUFFIX);
83 fd = create_tempfile(&lk->tempfile, filename.buf);
84 strbuf_release(&filename);
85 return fd;
021b6e45
JH
86}
87
044b6a9e
MH
88/*
89 * Constants defining the gaps between attempts to lock a file. The
90 * first backoff period is approximately INITIAL_BACKOFF_MS
91 * milliseconds. The longest backoff period is approximately
92 * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds.
93 */
94#define INITIAL_BACKOFF_MS 1L
95#define BACKOFF_MAX_MULTIPLIER 1000
96
97/*
98 * Try locking path, retrying with quadratic backoff for at least
99 * timeout_ms milliseconds. If timeout_ms is 0, try locking the file
100 * exactly once. If timeout_ms is -1, try indefinitely.
101 */
102static int lock_file_timeout(struct lock_file *lk, const char *path,
103 int flags, long timeout_ms)
104{
105 int n = 1;
106 int multiplier = 1;
a8a17756 107 long remaining_ms = 0;
044b6a9e
MH
108 static int random_initialized = 0;
109
110 if (timeout_ms == 0)
111 return lock_file(lk, path, flags);
112
113 if (!random_initialized) {
1e9676ec 114 srand((unsigned int)getpid());
044b6a9e
MH
115 random_initialized = 1;
116 }
117
a8a17756
JS
118 if (timeout_ms > 0)
119 remaining_ms = timeout_ms;
044b6a9e
MH
120
121 while (1) {
a8a17756 122 long backoff_ms, wait_ms;
044b6a9e
MH
123 int fd;
124
125 fd = lock_file(lk, path, flags);
126
127 if (fd >= 0)
128 return fd; /* success */
129 else if (errno != EEXIST)
130 return -1; /* failure other than lock held */
a8a17756 131 else if (timeout_ms > 0 && remaining_ms <= 0)
044b6a9e
MH
132 return -1; /* failure due to timeout */
133
134 backoff_ms = multiplier * INITIAL_BACKOFF_MS;
135 /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
a8a17756 136 wait_ms = (750 + rand() % 500) * backoff_ms / 1000;
30f8160d 137 sleep_millisec(wait_ms);
a8a17756 138 remaining_ms -= wait_ms;
044b6a9e
MH
139
140 /* Recursion: (n+1)^2 = n^2 + 2n + 1 */
141 multiplier += 2*n + 1;
142 if (multiplier > BACKOFF_MAX_MULTIPLIER)
143 multiplier = BACKOFF_MAX_MULTIPLIER;
144 else
145 n++;
146 }
147}
148
6af926e8 149void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
e43a6fd3 150{
bdfd739d 151 if (err == EEXIST) {
3030c295 152 strbuf_addf(buf, _("Unable to create '%s.lock': %s.\n\n"
aed7480c
MM
153 "Another git process seems to be running in this repository, e.g.\n"
154 "an editor opened by 'git commit'. Please make sure all processes\n"
155 "are terminated then try again. If it still fails, a git process\n"
156 "may have crashed in this repository earlier:\n"
157 "remove the file manually to continue."),
e2a57aac 158 absolute_path(path), strerror(err));
1b018fd9 159 } else
3030c295 160 strbuf_addf(buf, _("Unable to create '%s.lock': %s"),
e2a57aac 161 absolute_path(path), strerror(err));
1b018fd9
MV
162}
163
e197c218 164NORETURN void unable_to_lock_die(const char *path, int err)
1b018fd9 165{
6af926e8
RS
166 struct strbuf buf = STRBUF_INIT;
167
168 unable_to_lock_message(path, err, &buf);
169 die("%s", buf.buf);
e43a6fd3
MM
170}
171
447ff1bf 172/* This should return a meaningful errno on failure */
044b6a9e
MH
173int hold_lock_file_for_update_timeout(struct lock_file *lk, const char *path,
174 int flags, long timeout_ms)
40aaae88 175{
044b6a9e 176 int fd = lock_file_timeout(lk, path, flags, timeout_ms);
3f061bf5
JH
177 if (fd < 0) {
178 if (flags & LOCK_DIE_ON_ERROR)
179 unable_to_lock_die(path, errno);
180 if (flags & LOCK_REPORT_ON_ERROR) {
181 struct strbuf buf = STRBUF_INIT;
182 unable_to_lock_message(path, errno, &buf);
183 error("%s", buf.buf);
184 strbuf_release(&buf);
185 }
186 }
40aaae88
JH
187 return fd;
188}
189
ec38b4e4
MH
190char *get_locked_file_path(struct lock_file *lk)
191{
1a9d15db 192 struct strbuf ret = STRBUF_INIT;
013870cd 193
1a9d15db
MH
194 strbuf_addstr(&ret, get_tempfile_path(&lk->tempfile));
195 if (ret.len <= LOCK_SUFFIX_LEN ||
196 strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
ec38b4e4 197 die("BUG: get_locked_file_path() called for malformed lock object");
9c77381d 198 /* remove ".lock": */
1a9d15db
MH
199 strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN);
200 return strbuf_detach(&ret, NULL);
93dcaea2
JH
201}
202
751baced 203int commit_lock_file(struct lock_file *lk)
021b6e45 204{
9c77381d 205 char *result_path = get_locked_file_path(lk);
8a1c7533 206
9c77381d 207 if (commit_lock_file_to(lk, result_path)) {
1b1648f4 208 int save_errno = errno;
9c77381d 209 free(result_path);
1b1648f4 210 errno = save_errno;
d6cf61bf 211 return -1;
1b1648f4 212 }
9c77381d 213 free(result_path);
d6cf61bf 214 return 0;
021b6e45 215}