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