lock_file(): always initialize and register lock_file object
[git/git.git] / lockfile.c
CommitLineData
021b6e45
JH
1/*
2 * Copyright (c) 2005, Junio C Hamano
3 */
021b6e45 4#include "cache.h"
4a16d072 5#include "sigchain.h"
021b6e45
JH
6
7static struct lock_file *lock_file_list;
8
9static void remove_lock_file(void)
10{
5e635e39
JH
11 pid_t me = getpid();
12
021b6e45 13 while (lock_file_list) {
5e635e39 14 if (lock_file_list->owner == me &&
4723ee99 15 lock_file_list->filename[0]) {
d6cf61bf
BC
16 if (lock_file_list->fd >= 0)
17 close(lock_file_list->fd);
691f1a28 18 unlink_or_warn(lock_file_list->filename);
4723ee99 19 }
021b6e45
JH
20 lock_file_list = lock_file_list->next;
21 }
22}
23
24static void remove_lock_file_on_signal(int signo)
25{
26 remove_lock_file();
4a16d072 27 sigchain_pop(signo);
021b6e45
JH
28 raise(signo);
29}
30
5d5a7a67
BS
31/*
32 * p = absolute or relative path name
33 *
34 * Return a pointer into p showing the beginning of the last path name
35 * element. If p is empty or the root directory ("/"), just return p.
36 */
37static char *last_path_elm(char *p)
38{
39 /* r starts pointing to null at the end of the string */
40 char *r = strchr(p, '\0');
41
42 if (r == p)
43 return p; /* just return empty string */
44
45 r--; /* back up to last non-null character */
46
47 /* back up past trailing slashes, if any */
48 while (r > p && *r == '/')
49 r--;
50
51 /*
52 * then go backwards until I hit a slash, or the beginning of
53 * the string
54 */
55 while (r > p && *(r-1) != '/')
56 r--;
57 return r;
58}
59
60
61/* We allow "recursive" symbolic links. Only within reason, though */
62#define MAXDEPTH 5
63
64/*
65 * p = path that may be a symlink
66 * s = full size of p
67 *
68 * If p is a symlink, attempt to overwrite p with a path to the real
69 * file or directory (which may or may not exist), following a chain of
70 * symlinks if necessary. Otherwise, leave p unmodified.
71 *
72 * This is a best-effort routine. If an error occurs, p will either be
73 * left unmodified or will name a different symlink in a symlink chain
74 * that started with p's initial contents.
75 *
76 * Always returns p.
77 */
78
79static char *resolve_symlink(char *p, size_t s)
80{
81 int depth = MAXDEPTH;
82
83 while (depth--) {
84 char link[PATH_MAX];
85 int link_len = readlink(p, link, sizeof(link));
86 if (link_len < 0) {
87 /* not a symlink anymore */
88 return p;
89 }
90 else if (link_len < sizeof(link))
91 /* readlink() never null-terminates */
92 link[link_len] = '\0';
93 else {
94 warning("%s: symlink too long", p);
95 return p;
96 }
97
ecf4831d 98 if (is_absolute_path(link)) {
5d5a7a67
BS
99 /* absolute path simply replaces p */
100 if (link_len < s)
101 strcpy(p, link);
102 else {
103 warning("%s: symlink too long", p);
104 return p;
105 }
106 } else {
107 /*
108 * link is a relative path, so I must replace the
109 * last element of p with it.
110 */
4b25d091 111 char *r = (char *)last_path_elm(p);
5d5a7a67
BS
112 if (r - p + link_len < s)
113 strcpy(r, link);
114 else {
115 warning("%s: symlink too long", p);
116 return p;
117 }
118 }
119 }
120 return p;
121}
122
447ff1bf 123/* Make sure errno contains a meaningful value on error */
acd3b9ec 124static int lock_file(struct lock_file *lk, const char *path, int flags)
021b6e45 125{
5d5a7a67
BS
126 /*
127 * subtract 5 from size to make sure there's room for adding
128 * ".lock" for the lock file name
129 */
2fbd4f92
MH
130 static const size_t max_path_len = sizeof(lk->filename) - 5;
131
04e57d4d
MH
132 if (!lock_file_list) {
133 /* One-time initialization */
134 sigchain_push_common(remove_lock_file_on_signal);
135 atexit(remove_lock_file);
136 }
137
138 if (!lk->on_list) {
139 /* Initialize *lk and add it to lock_file_list: */
140 lk->fd = -1;
141 lk->owner = 0;
142 lk->filename[0] = 0;
143 lk->next = lock_file_list;
144 lock_file_list = lk;
145 lk->on_list = 1;
146 }
147
447ff1bf
RS
148 if (strlen(path) >= max_path_len) {
149 errno = ENAMETOOLONG;
2fbd4f92 150 return -1;
447ff1bf 151 }
2fbd4f92 152 strcpy(lk->filename, path);
acd3b9ec 153 if (!(flags & LOCK_NODEREF))
2fbd4f92 154 resolve_symlink(lk->filename, max_path_len);
5d5a7a67 155 strcat(lk->filename, ".lock");
4723ee99
JS
156 lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
157 if (0 <= lk->fd) {
5e635e39 158 lk->owner = getpid();
447ff1bf
RS
159 if (adjust_shared_perm(lk->filename)) {
160 int save_errno = errno;
161 error("cannot fix permission bits on %s",
162 lk->filename);
41dd4ffa 163 rollback_lock_file(lk);
447ff1bf
RS
164 errno = save_errno;
165 return -1;
166 }
021b6e45 167 }
1084b845
JH
168 else
169 lk->filename[0] = 0;
4723ee99 170 return lk->fd;
021b6e45
JH
171}
172
6af926e8 173void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
e43a6fd3 174{
bdfd739d 175 if (err == EEXIST) {
6af926e8 176 strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
e43a6fd3
MM
177 "If no other git process is currently running, this probably means a\n"
178 "git process crashed in this repository earlier. Make sure no other git\n"
179 "process is running and remove the file manually to continue.",
e2a57aac 180 absolute_path(path), strerror(err));
1b018fd9 181 } else
6af926e8 182 strbuf_addf(buf, "Unable to create '%s.lock': %s",
e2a57aac 183 absolute_path(path), strerror(err));
1b018fd9
MV
184}
185
186int unable_to_lock_error(const char *path, int err)
187{
6af926e8
RS
188 struct strbuf buf = STRBUF_INIT;
189
190 unable_to_lock_message(path, err, &buf);
191 error("%s", buf.buf);
192 strbuf_release(&buf);
1b018fd9
MV
193 return -1;
194}
195
e197c218 196NORETURN void unable_to_lock_die(const char *path, int err)
1b018fd9 197{
6af926e8
RS
198 struct strbuf buf = STRBUF_INIT;
199
200 unable_to_lock_message(path, err, &buf);
201 die("%s", buf.buf);
e43a6fd3
MM
202}
203
447ff1bf 204/* This should return a meaningful errno on failure */
acd3b9ec 205int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
40aaae88 206{
acd3b9ec
JH
207 int fd = lock_file(lk, path, flags);
208 if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
e197c218 209 unable_to_lock_die(path, errno);
40aaae88
JH
210 return fd;
211}
212
acd3b9ec 213int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
ea3cd5c7
DB
214{
215 int fd, orig_fd;
216
acd3b9ec 217 fd = lock_file(lk, path, flags);
ea3cd5c7 218 if (fd < 0) {
acd3b9ec 219 if (flags & LOCK_DIE_ON_ERROR)
e197c218 220 unable_to_lock_die(path, errno);
ea3cd5c7
DB
221 return fd;
222 }
223
224 orig_fd = open(path, O_RDONLY);
225 if (orig_fd < 0) {
226 if (errno != ENOENT) {
acd3b9ec 227 if (flags & LOCK_DIE_ON_ERROR)
ea3cd5c7 228 die("cannot open '%s' for copying", path);
ebb8e380 229 rollback_lock_file(lk);
ea3cd5c7
DB
230 return error("cannot open '%s' for copying", path);
231 }
232 } else if (copy_fd(orig_fd, fd)) {
acd3b9ec 233 if (flags & LOCK_DIE_ON_ERROR)
ea3cd5c7 234 exit(128);
ebb8e380 235 rollback_lock_file(lk);
ea3cd5c7
DB
236 return -1;
237 }
238 return fd;
239}
240
d6cf61bf
BC
241int close_lock_file(struct lock_file *lk)
242{
243 int fd = lk->fd;
419f0c0f
MH
244
245 if (fd < 0)
246 return 0;
247
d6cf61bf
BC
248 lk->fd = -1;
249 return close(fd);
250}
251
93dcaea2
JH
252int reopen_lock_file(struct lock_file *lk)
253{
254 if (0 <= lk->fd)
255 die(_("BUG: reopen a lockfile that is still open"));
256 if (!lk->filename[0])
257 die(_("BUG: reopen a lockfile that has been committed"));
258 lk->fd = open(lk->filename, O_WRONLY);
259 return lk->fd;
260}
261
021b6e45
JH
262int commit_lock_file(struct lock_file *lk)
263{
264 char result_file[PATH_MAX];
d6cf61bf 265 size_t i;
419f0c0f 266 if (close_lock_file(lk))
d6cf61bf 267 return -1;
021b6e45
JH
268 strcpy(result_file, lk->filename);
269 i = strlen(result_file) - 5; /* .lock */
270 result_file[i] = 0;
d6cf61bf
BC
271 if (rename(lk->filename, result_file))
272 return -1;
021b6e45 273 lk->filename[0] = 0;
d6cf61bf 274 return 0;
021b6e45
JH
275}
276
30ca07a2
JH
277int hold_locked_index(struct lock_file *lk, int die_on_error)
278{
acd3b9ec
JH
279 return hold_lock_file_for_update(lk, get_index_file(),
280 die_on_error
281 ? LOCK_DIE_ON_ERROR
282 : 0);
30ca07a2
JH
283}
284
021b6e45
JH
285void rollback_lock_file(struct lock_file *lk)
286{
9085f8e2
MH
287 if (!lk->filename[0])
288 return;
289
26f5d3b6 290 close_lock_file(lk);
9085f8e2
MH
291 unlink_or_warn(lk->filename);
292 lk->filename[0] = 0;
021b6e45 293}