credential-cache--daemon: use tempfile module
[git] / lockfile.c
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  */
15 static 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  */
48 static 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 */
73 static 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
88 static 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  */
110 static 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
162 void 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
175 NORETURN 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 */
184 int 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
193 int 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
231 char *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
244 int 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 }