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