f4ce79bc2733b44d85ddb60c65bb710536747330
1/*
2 * Copyright (c) 2005, Junio C Hamano
3 */
4#include "cache.h"
5#include "sigchain.h"
6
7static struct lock_file *lock_file_list;
8
9static void remove_lock_file(void)
10{
11 pid_t me = getpid();
12
13 while (lock_file_list) {
14 if (lock_file_list->owner == me &&
15 lock_file_list->filename[0]) {
16 if (lock_file_list->fd >= 0)
17 close(lock_file_list->fd);
18 unlink_or_warn(lock_file_list->filename);
19 }
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();
27 sigchain_pop(signo);
28 raise(signo);
29}
30
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
98 if (is_absolute_path(link)) {
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 */
111 char *r = (char *)last_path_elm(p);
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
123/* Make sure errno contains a meaningful value on error */
124static int lock_file(struct lock_file *lk, const char *path, int flags)
125{
126 /*
127 * subtract 5 from size to make sure there's room for adding
128 * ".lock" for the lock file name
129 */
130 static const size_t max_path_len = sizeof(lk->filename) - 5;
131
132 if (strlen(path) >= max_path_len) {
133 errno = ENAMETOOLONG;
134 return -1;
135 }
136 strcpy(lk->filename, path);
137 if (!(flags & LOCK_NODEREF))
138 resolve_symlink(lk->filename, max_path_len);
139 strcat(lk->filename, ".lock");
140 lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
141 if (0 <= lk->fd) {
142 if (!lock_file_list) {
143 sigchain_push_common(remove_lock_file_on_signal);
144 atexit(remove_lock_file);
145 }
146 lk->owner = getpid();
147 if (!lk->on_list) {
148 lk->next = lock_file_list;
149 lock_file_list = lk;
150 lk->on_list = 1;
151 }
152 if (adjust_shared_perm(lk->filename)) {
153 int save_errno = errno;
154 error("cannot fix permission bits on %s",
155 lk->filename);
156 rollback_lock_file(lk);
157 errno = save_errno;
158 return -1;
159 }
160 }
161 else
162 lk->filename[0] = 0;
163 return lk->fd;
164}
165
166void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
167{
168 if (err == EEXIST) {
169 strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
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.",
173 absolute_path(path), strerror(err));
174 } else
175 strbuf_addf(buf, "Unable to create '%s.lock': %s",
176 absolute_path(path), strerror(err));
177}
178
179int unable_to_lock_error(const char *path, int err)
180{
181 struct strbuf buf = STRBUF_INIT;
182
183 unable_to_lock_message(path, err, &buf);
184 error("%s", buf.buf);
185 strbuf_release(&buf);
186 return -1;
187}
188
189NORETURN void unable_to_lock_die(const char *path, int err)
190{
191 struct strbuf buf = STRBUF_INIT;
192
193 unable_to_lock_message(path, err, &buf);
194 die("%s", buf.buf);
195}
196
197/* This should return a meaningful errno on failure */
198int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
199{
200 int fd = lock_file(lk, path, flags);
201 if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
202 unable_to_lock_die(path, errno);
203 return fd;
204}
205
206int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
207{
208 int fd, orig_fd;
209
210 fd = lock_file(lk, path, flags);
211 if (fd < 0) {
212 if (flags & LOCK_DIE_ON_ERROR)
213 unable_to_lock_die(path, errno);
214 return fd;
215 }
216
217 orig_fd = open(path, O_RDONLY);
218 if (orig_fd < 0) {
219 if (errno != ENOENT) {
220 if (flags & LOCK_DIE_ON_ERROR)
221 die("cannot open '%s' for copying", path);
222 rollback_lock_file(lk);
223 return error("cannot open '%s' for copying", path);
224 }
225 } else if (copy_fd(orig_fd, fd)) {
226 if (flags & LOCK_DIE_ON_ERROR)
227 exit(128);
228 rollback_lock_file(lk);
229 return -1;
230 }
231 return fd;
232}
233
234int close_lock_file(struct lock_file *lk)
235{
236 int fd = lk->fd;
237
238 if (fd < 0)
239 return 0;
240
241 lk->fd = -1;
242 return close(fd);
243}
244
245int reopen_lock_file(struct lock_file *lk)
246{
247 if (0 <= lk->fd)
248 die(_("BUG: reopen a lockfile that is still open"));
249 if (!lk->filename[0])
250 die(_("BUG: reopen a lockfile that has been committed"));
251 lk->fd = open(lk->filename, O_WRONLY);
252 return lk->fd;
253}
254
255int commit_lock_file(struct lock_file *lk)
256{
257 char result_file[PATH_MAX];
258 size_t i;
259 if (close_lock_file(lk))
260 return -1;
261 strcpy(result_file, lk->filename);
262 i = strlen(result_file) - 5; /* .lock */
263 result_file[i] = 0;
264 if (rename(lk->filename, result_file))
265 return -1;
266 lk->filename[0] = 0;
267 return 0;
268}
269
270int hold_locked_index(struct lock_file *lk, int die_on_error)
271{
272 return hold_lock_file_for_update(lk, get_index_file(),
273 die_on_error
274 ? LOCK_DIE_ON_ERROR
275 : 0);
276}
277
278void rollback_lock_file(struct lock_file *lk)
279{
280 if (!lk->filename[0])
281 return;
282
283 close_lock_file(lk);
284 unlink_or_warn(lk->filename);
285 lk->filename[0] = 0;
286}