mmap_limit: introduce GIT_MMAP_LIMIT to allow testing expected mmap size
[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
447ff1bf
RS
132 if (strlen(path) >= max_path_len) {
133 errno = ENAMETOOLONG;
2fbd4f92 134 return -1;
447ff1bf 135 }
2fbd4f92 136 strcpy(lk->filename, path);
acd3b9ec 137 if (!(flags & LOCK_NODEREF))
2fbd4f92 138 resolve_symlink(lk->filename, max_path_len);
5d5a7a67 139 strcat(lk->filename, ".lock");
4723ee99
JS
140 lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
141 if (0 <= lk->fd) {
9a4cbdca 142 if (!lock_file_list) {
57b235a4 143 sigchain_push_common(remove_lock_file_on_signal);
9a4cbdca
SV
144 atexit(remove_lock_file);
145 }
5e635e39 146 lk->owner = getpid();
1084b845 147 if (!lk->on_list) {
138086a7
JH
148 lk->next = lock_file_list;
149 lock_file_list = lk;
1084b845
JH
150 lk->on_list = 1;
151 }
447ff1bf
RS
152 if (adjust_shared_perm(lk->filename)) {
153 int save_errno = errno;
154 error("cannot fix permission bits on %s",
155 lk->filename);
156 errno = save_errno;
157 return -1;
158 }
021b6e45 159 }
1084b845
JH
160 else
161 lk->filename[0] = 0;
4723ee99 162 return lk->fd;
021b6e45
JH
163}
164
6af926e8 165void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
e43a6fd3 166{
bdfd739d 167 if (err == EEXIST) {
6af926e8 168 strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
e43a6fd3
MM
169 "If no other git process is currently running, this probably means a\n"
170 "git process crashed in this repository earlier. Make sure no other git\n"
171 "process is running and remove the file manually to continue.",
e2a57aac 172 absolute_path(path), strerror(err));
1b018fd9 173 } else
6af926e8 174 strbuf_addf(buf, "Unable to create '%s.lock': %s",
e2a57aac 175 absolute_path(path), strerror(err));
1b018fd9
MV
176}
177
178int unable_to_lock_error(const char *path, int err)
179{
6af926e8
RS
180 struct strbuf buf = STRBUF_INIT;
181
182 unable_to_lock_message(path, err, &buf);
183 error("%s", buf.buf);
184 strbuf_release(&buf);
1b018fd9
MV
185 return -1;
186}
187
188NORETURN void unable_to_lock_index_die(const char *path, int err)
189{
6af926e8
RS
190 struct strbuf buf = STRBUF_INIT;
191
192 unable_to_lock_message(path, err, &buf);
193 die("%s", buf.buf);
e43a6fd3
MM
194}
195
447ff1bf 196/* This should return a meaningful errno on failure */
acd3b9ec 197int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
40aaae88 198{
acd3b9ec
JH
199 int fd = lock_file(lk, path, flags);
200 if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
e43a6fd3 201 unable_to_lock_index_die(path, errno);
40aaae88
JH
202 return fd;
203}
204
acd3b9ec 205int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
ea3cd5c7
DB
206{
207 int fd, orig_fd;
208
acd3b9ec 209 fd = lock_file(lk, path, flags);
ea3cd5c7 210 if (fd < 0) {
acd3b9ec 211 if (flags & LOCK_DIE_ON_ERROR)
bdfd739d 212 unable_to_lock_index_die(path, errno);
ea3cd5c7
DB
213 return fd;
214 }
215
216 orig_fd = open(path, O_RDONLY);
217 if (orig_fd < 0) {
218 if (errno != ENOENT) {
acd3b9ec 219 if (flags & LOCK_DIE_ON_ERROR)
ea3cd5c7
DB
220 die("cannot open '%s' for copying", path);
221 close(fd);
222 return error("cannot open '%s' for copying", path);
223 }
224 } else if (copy_fd(orig_fd, fd)) {
acd3b9ec 225 if (flags & LOCK_DIE_ON_ERROR)
ea3cd5c7
DB
226 exit(128);
227 close(fd);
228 return -1;
229 }
230 return fd;
231}
232
d6cf61bf
BC
233int close_lock_file(struct lock_file *lk)
234{
235 int fd = lk->fd;
236 lk->fd = -1;
237 return close(fd);
238}
239
021b6e45
JH
240int commit_lock_file(struct lock_file *lk)
241{
242 char result_file[PATH_MAX];
d6cf61bf
BC
243 size_t i;
244 if (lk->fd >= 0 && close_lock_file(lk))
245 return -1;
021b6e45
JH
246 strcpy(result_file, lk->filename);
247 i = strlen(result_file) - 5; /* .lock */
248 result_file[i] = 0;
d6cf61bf
BC
249 if (rename(lk->filename, result_file))
250 return -1;
021b6e45 251 lk->filename[0] = 0;
d6cf61bf 252 return 0;
021b6e45
JH
253}
254
30ca07a2
JH
255int hold_locked_index(struct lock_file *lk, int die_on_error)
256{
acd3b9ec
JH
257 return hold_lock_file_for_update(lk, get_index_file(),
258 die_on_error
259 ? LOCK_DIE_ON_ERROR
260 : 0);
30ca07a2
JH
261}
262
021b6e45
JH
263void rollback_lock_file(struct lock_file *lk)
264{
4723ee99 265 if (lk->filename[0]) {
d6cf61bf
BC
266 if (lk->fd >= 0)
267 close(lk->fd);
691f1a28 268 unlink_or_warn(lk->filename);
4723ee99 269 }
021b6e45
JH
270 lk->filename[0] = 0;
271}