Sync with 2.4.1
[git/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
6af926e8 160void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
e43a6fd3 161{
bdfd739d 162 if (err == EEXIST) {
6af926e8 163 strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
e43a6fd3
MM
164 "If no other git process is currently running, this probably means a\n"
165 "git process crashed in this repository earlier. Make sure no other git\n"
166 "process is running and remove the file manually to continue.",
e2a57aac 167 absolute_path(path), strerror(err));
1b018fd9 168 } else
6af926e8 169 strbuf_addf(buf, "Unable to create '%s.lock': %s",
e2a57aac 170 absolute_path(path), strerror(err));
1b018fd9
MV
171}
172
e197c218 173NORETURN void unable_to_lock_die(const char *path, int err)
1b018fd9 174{
6af926e8
RS
175 struct strbuf buf = STRBUF_INIT;
176
177 unable_to_lock_message(path, err, &buf);
178 die("%s", buf.buf);
e43a6fd3
MM
179}
180
447ff1bf 181/* This should return a meaningful errno on failure */
acd3b9ec 182int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
40aaae88 183{
acd3b9ec
JH
184 int fd = lock_file(lk, path, flags);
185 if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
e197c218 186 unable_to_lock_die(path, errno);
40aaae88
JH
187 return fd;
188}
189
acd3b9ec 190int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
ea3cd5c7
DB
191{
192 int fd, orig_fd;
193
acd3b9ec 194 fd = lock_file(lk, path, flags);
ea3cd5c7 195 if (fd < 0) {
acd3b9ec 196 if (flags & LOCK_DIE_ON_ERROR)
e197c218 197 unable_to_lock_die(path, errno);
ea3cd5c7
DB
198 return fd;
199 }
200
201 orig_fd = open(path, O_RDONLY);
202 if (orig_fd < 0) {
203 if (errno != ENOENT) {
4d423a3e
MH
204 int save_errno = errno;
205
acd3b9ec 206 if (flags & LOCK_DIE_ON_ERROR)
ea3cd5c7 207 die("cannot open '%s' for copying", path);
ebb8e380 208 rollback_lock_file(lk);
4d423a3e
MH
209 error("cannot open '%s' for copying", path);
210 errno = save_errno;
211 return -1;
ea3cd5c7
DB
212 }
213 } else if (copy_fd(orig_fd, fd)) {
4d423a3e
MH
214 int save_errno = errno;
215
acd3b9ec 216 if (flags & LOCK_DIE_ON_ERROR)
ea3cd5c7 217 exit(128);
b29763aa 218 close(orig_fd);
ebb8e380 219 rollback_lock_file(lk);
4d423a3e 220 errno = save_errno;
ea3cd5c7 221 return -1;
b29763aa
SP
222 } else {
223 close(orig_fd);
ea3cd5c7
DB
224 }
225 return fd;
226}
227
013870cd
MH
228FILE *fdopen_lock_file(struct lock_file *lk, const char *mode)
229{
230 if (!lk->active)
231 die("BUG: fdopen_lock_file() called for unlocked object");
232 if (lk->fp)
233 die("BUG: fdopen_lock_file() called twice for file '%s'", lk->filename.buf);
234
235 lk->fp = fdopen(lk->fd, mode);
236 return lk->fp;
237}
238
ec38b4e4
MH
239char *get_locked_file_path(struct lock_file *lk)
240{
241 if (!lk->active)
242 die("BUG: get_locked_file_path() called for unlocked object");
243 if (lk->filename.len <= LOCK_SUFFIX_LEN)
244 die("BUG: get_locked_file_path() called for malformed lock object");
245 return xmemdupz(lk->filename.buf, lk->filename.len - LOCK_SUFFIX_LEN);
246}
247
d6cf61bf
BC
248int close_lock_file(struct lock_file *lk)
249{
250 int fd = lk->fd;
013870cd
MH
251 FILE *fp = lk->fp;
252 int err;
419f0c0f
MH
253
254 if (fd < 0)
255 return 0;
256
d6cf61bf 257 lk->fd = -1;
013870cd
MH
258 if (fp) {
259 lk->fp = NULL;
260
261 /*
262 * Note: no short-circuiting here; we want to fclose()
263 * in any case!
264 */
265 err = ferror(fp) | fclose(fp);
266 } else {
267 err = close(fd);
268 }
269
270 if (err) {
8e86c155
MH
271 int save_errno = errno;
272 rollback_lock_file(lk);
273 errno = save_errno;
274 return -1;
275 }
013870cd 276
8e86c155 277 return 0;
d6cf61bf
BC
278}
279
93dcaea2
JH
280int reopen_lock_file(struct lock_file *lk)
281{
282 if (0 <= lk->fd)
283 die(_("BUG: reopen a lockfile that is still open"));
707103fd 284 if (!lk->active)
93dcaea2 285 die(_("BUG: reopen a lockfile that has been committed"));
cf6950d3 286 lk->fd = open(lk->filename.buf, O_WRONLY);
93dcaea2
JH
287 return lk->fd;
288}
289
751baced 290int commit_lock_file_to(struct lock_file *lk, const char *path)
021b6e45 291{
707103fd 292 if (!lk->active)
751baced 293 die("BUG: attempt to commit unlocked object to \"%s\"", path);
8a1c7533 294
419f0c0f 295 if (close_lock_file(lk))
d6cf61bf 296 return -1;
4f4713df 297
751baced 298 if (rename(lk->filename.buf, path)) {
1b1648f4
MH
299 int save_errno = errno;
300 rollback_lock_file(lk);
301 errno = save_errno;
d6cf61bf 302 return -1;
1b1648f4
MH
303 }
304
707103fd 305 lk->active = 0;
cf6950d3 306 strbuf_reset(&lk->filename);
d6cf61bf 307 return 0;
021b6e45
JH
308}
309
751baced 310int commit_lock_file(struct lock_file *lk)
30ca07a2 311{
751baced
MH
312 static struct strbuf result_file = STRBUF_INIT;
313 int err;
314
315 if (!lk->active)
316 die("BUG: attempt to commit unlocked object");
317
318 if (lk->filename.len <= LOCK_SUFFIX_LEN ||
319 strcmp(lk->filename.buf + lk->filename.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
320 die("BUG: lockfile filename corrupt");
321
322 /* remove ".lock": */
323 strbuf_add(&result_file, lk->filename.buf,
324 lk->filename.len - LOCK_SUFFIX_LEN);
325 err = commit_lock_file_to(lk, result_file.buf);
326 strbuf_reset(&result_file);
327 return err;
30ca07a2
JH
328}
329
021b6e45
JH
330void rollback_lock_file(struct lock_file *lk)
331{
707103fd 332 if (!lk->active)
9085f8e2
MH
333 return;
334
8e86c155 335 if (!close_lock_file(lk)) {
cf6950d3 336 unlink_or_warn(lk->filename.buf);
707103fd 337 lk->active = 0;
cf6950d3 338 strbuf_reset(&lk->filename);
4723ee99 339 }
021b6e45 340}