1/*
2 * Copyright (c) 2005, Junio C Hamano
3 */
4
5#include "cache.h"
6#include "lockfile.h"
7
8/*
9 * path = absolute or relative path name
10 *
11 * Remove the last path name element from path (leaving the preceding
12 * "/", if any). If path is empty or the root directory ("/"), set
13 * path to the empty string.
14 */
15static void trim_last_path_component(struct strbuf *path)
16{
17 int i = path->len;
18
19 /* back up past trailing slashes, if any */
20 while (i && path->buf[i - 1] == '/')
21 i--;
22
23 /*
24 * then go backwards until a slash, or the beginning of the
25 * string
26 */
27 while (i && path->buf[i - 1] != '/')
28 i--;
29
30 strbuf_setlen(path, i);
31}
32
33
34/* We allow "recursive" symbolic links. Only within reason, though */
35#define MAXDEPTH 5
36
37/*
38 * path contains a path that might be a symlink.
39 *
40 * If path is a symlink, attempt to overwrite it with a path to the
41 * real file or directory (which may or may not exist), following a
42 * chain of symlinks if necessary. Otherwise, leave path unmodified.
43 *
44 * This is a best-effort routine. If an error occurs, path will
45 * either be left unmodified or will name a different symlink in a
46 * symlink chain that started with the original path.
47 */
48static void resolve_symlink(struct strbuf *path)
49{
50 int depth = MAXDEPTH;
51 static struct strbuf link = STRBUF_INIT;
52
53 while (depth--) {
54 if (strbuf_readlink(&link, path->buf, path->len) < 0)
55 break;
56
57 if (is_absolute_path(link.buf))
58 /* absolute path simply replaces p */
59 strbuf_reset(path);
60 else
61 /*
62 * link is a relative path, so replace the
63 * last element of p with it.
64 */
65 trim_last_path_component(path);
66
67 strbuf_addbuf(path, &link);
68 }
69 strbuf_reset(&link);
70}
71
72/* Make sure errno contains a meaningful value on error */
73static int lock_file(struct lock_file *lk, const char *path, int flags)
74{
75 int fd;
76 struct strbuf filename = STRBUF_INIT;
77
78 strbuf_addstr(&filename, path);
79 if (!(flags & LOCK_NO_DEREF))
80 resolve_symlink(&filename);
81
82 strbuf_addstr(&filename, LOCK_SUFFIX);
83 fd = create_tempfile(&lk->tempfile, filename.buf);
84 strbuf_release(&filename);
85 return fd;
86}
87
88static int sleep_microseconds(long us)
89{
90 struct timeval tv;
91 tv.tv_sec = 0;
92 tv.tv_usec = us;
93 return select(0, NULL, NULL, NULL, &tv);
94}
95
96/*
97 * Constants defining the gaps between attempts to lock a file. The
98 * first backoff period is approximately INITIAL_BACKOFF_MS
99 * milliseconds. The longest backoff period is approximately
100 * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds.
101 */
102#define INITIAL_BACKOFF_MS 1L
103#define BACKOFF_MAX_MULTIPLIER 1000
104
105/*
106 * Try locking path, retrying with quadratic backoff for at least
107 * timeout_ms milliseconds. If timeout_ms is 0, try locking the file
108 * exactly once. If timeout_ms is -1, try indefinitely.
109 */
110static int lock_file_timeout(struct lock_file *lk, const char *path,
111 int flags, long timeout_ms)
112{
113 int n = 1;
114 int multiplier = 1;
115 long remaining_us = 0;
116 static int random_initialized = 0;
117
118 if (timeout_ms == 0)
119 return lock_file(lk, path, flags);
120
121 if (!random_initialized) {
122 srandom((unsigned int)getpid());
123 random_initialized = 1;
124 }
125
126 if (timeout_ms > 0) {
127 /* avoid overflow */
128 if (timeout_ms <= LONG_MAX / 1000)
129 remaining_us = timeout_ms * 1000;
130 else
131 remaining_us = LONG_MAX;
132 }
133
134 while (1) {
135 long backoff_ms, wait_us;
136 int fd;
137
138 fd = lock_file(lk, path, flags);
139
140 if (fd >= 0)
141 return fd; /* success */
142 else if (errno != EEXIST)
143 return -1; /* failure other than lock held */
144 else if (timeout_ms > 0 && remaining_us <= 0)
145 return -1; /* failure due to timeout */
146
147 backoff_ms = multiplier * INITIAL_BACKOFF_MS;
148 /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
149 wait_us = (750 + random() % 500) * backoff_ms;
150 sleep_microseconds(wait_us);
151 remaining_us -= wait_us;
152
153 /* Recursion: (n+1)^2 = n^2 + 2n + 1 */
154 multiplier += 2*n + 1;
155 if (multiplier > BACKOFF_MAX_MULTIPLIER)
156 multiplier = BACKOFF_MAX_MULTIPLIER;
157 else
158 n++;
159 }
160}
161
162void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
163{
164 if (err == EEXIST) {
165 strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
166 "If no other git process is currently running, this probably means a\n"
167 "git process crashed in this repository earlier. Make sure no other git\n"
168 "process is running and remove the file manually to continue.",
169 absolute_path(path), strerror(err));
170 } else
171 strbuf_addf(buf, "Unable to create '%s.lock': %s",
172 absolute_path(path), strerror(err));
173}
174
175NORETURN void unable_to_lock_die(const char *path, int err)
176{
177 struct strbuf buf = STRBUF_INIT;
178
179 unable_to_lock_message(path, err, &buf);
180 die("%s", buf.buf);
181}
182
183/* This should return a meaningful errno on failure */
184int hold_lock_file_for_update_timeout(struct lock_file *lk, const char *path,
185 int flags, long timeout_ms)
186{
187 int fd = lock_file_timeout(lk, path, flags, timeout_ms);
188 if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
189 unable_to_lock_die(path, errno);
190 return fd;
191}
192
193int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
194{
195 int fd, orig_fd;
196
197 fd = lock_file(lk, path, flags);
198 if (fd < 0) {
199 if (flags & LOCK_DIE_ON_ERROR)
200 unable_to_lock_die(path, errno);
201 return fd;
202 }
203
204 orig_fd = open(path, O_RDONLY);
205 if (orig_fd < 0) {
206 if (errno != ENOENT) {
207 int save_errno = errno;
208
209 if (flags & LOCK_DIE_ON_ERROR)
210 die("cannot open '%s' for copying", path);
211 rollback_lock_file(lk);
212 error("cannot open '%s' for copying", path);
213 errno = save_errno;
214 return -1;
215 }
216 } else if (copy_fd(orig_fd, fd)) {
217 int save_errno = errno;
218
219 if (flags & LOCK_DIE_ON_ERROR)
220 die("failed to prepare '%s' for appending", path);
221 close(orig_fd);
222 rollback_lock_file(lk);
223 errno = save_errno;
224 return -1;
225 } else {
226 close(orig_fd);
227 }
228 return fd;
229}
230
231char *get_locked_file_path(struct lock_file *lk)
232{
233 struct strbuf ret = STRBUF_INIT;
234
235 strbuf_addstr(&ret, get_tempfile_path(&lk->tempfile));
236 if (ret.len <= LOCK_SUFFIX_LEN ||
237 strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
238 die("BUG: get_locked_file_path() called for malformed lock object");
239 /* remove ".lock": */
240 strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN);
241 return strbuf_detach(&ret, NULL);
242}
243
244int commit_lock_file(struct lock_file *lk)
245{
246 char *result_path = get_locked_file_path(lk);
247
248 if (commit_lock_file_to(lk, result_path)) {
249 int save_errno = errno;
250 free(result_path);
251 errno = save_errno;
252 return -1;
253 }
254 free(result_path);
255 return 0;
256}