test-tool: don't force full index
[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                      int mode)
75 {
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         lk->tempfile = create_tempfile_mode(filename.buf, mode);
84         strbuf_release(&filename);
85         return lk->tempfile ? lk->tempfile->fd : -1;
86 }
87
88 /*
89  * Constants defining the gaps between attempts to lock a file. The
90  * first backoff period is approximately INITIAL_BACKOFF_MS
91  * milliseconds. The longest backoff period is approximately
92  * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds.
93  */
94 #define INITIAL_BACKOFF_MS 1L
95 #define BACKOFF_MAX_MULTIPLIER 1000
96
97 /*
98  * Try locking path, retrying with quadratic backoff for at least
99  * timeout_ms milliseconds. If timeout_ms is 0, try locking the file
100  * exactly once. If timeout_ms is -1, try indefinitely.
101  */
102 static int lock_file_timeout(struct lock_file *lk, const char *path,
103                              int flags, long timeout_ms, int mode)
104 {
105         int n = 1;
106         int multiplier = 1;
107         long remaining_ms = 0;
108         static int random_initialized = 0;
109
110         if (timeout_ms == 0)
111                 return lock_file(lk, path, flags, mode);
112
113         if (!random_initialized) {
114                 srand((unsigned int)getpid());
115                 random_initialized = 1;
116         }
117
118         if (timeout_ms > 0)
119                 remaining_ms = timeout_ms;
120
121         while (1) {
122                 long backoff_ms, wait_ms;
123                 int fd;
124
125                 fd = lock_file(lk, path, flags, mode);
126
127                 if (fd >= 0)
128                         return fd; /* success */
129                 else if (errno != EEXIST)
130                         return -1; /* failure other than lock held */
131                 else if (timeout_ms > 0 && remaining_ms <= 0)
132                         return -1; /* failure due to timeout */
133
134                 backoff_ms = multiplier * INITIAL_BACKOFF_MS;
135                 /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
136                 wait_ms = (750 + rand() % 500) * backoff_ms / 1000;
137                 sleep_millisec(wait_ms);
138                 remaining_ms -= wait_ms;
139
140                 /* Recursion: (n+1)^2 = n^2 + 2n + 1 */
141                 multiplier += 2*n + 1;
142                 if (multiplier > BACKOFF_MAX_MULTIPLIER)
143                         multiplier = BACKOFF_MAX_MULTIPLIER;
144                 else
145                         n++;
146         }
147 }
148
149 void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
150 {
151         if (err == EEXIST) {
152                 strbuf_addf(buf, _("Unable to create '%s.lock': %s.\n\n"
153                     "Another git process seems to be running in this repository, e.g.\n"
154                     "an editor opened by 'git commit'. Please make sure all processes\n"
155                     "are terminated then try again. If it still fails, a git process\n"
156                     "may have crashed in this repository earlier:\n"
157                     "remove the file manually to continue."),
158                             absolute_path(path), strerror(err));
159         } else
160                 strbuf_addf(buf, _("Unable to create '%s.lock': %s"),
161                             absolute_path(path), strerror(err));
162 }
163
164 NORETURN void unable_to_lock_die(const char *path, int err)
165 {
166         struct strbuf buf = STRBUF_INIT;
167
168         unable_to_lock_message(path, err, &buf);
169         die("%s", buf.buf);
170 }
171
172 /* This should return a meaningful errno on failure */
173 int hold_lock_file_for_update_timeout_mode(struct lock_file *lk,
174                                            const char *path, int flags,
175                                            long timeout_ms, int mode)
176 {
177         int fd = lock_file_timeout(lk, path, flags, timeout_ms, mode);
178         if (fd < 0) {
179                 if (flags & LOCK_DIE_ON_ERROR)
180                         unable_to_lock_die(path, errno);
181                 if (flags & LOCK_REPORT_ON_ERROR) {
182                         struct strbuf buf = STRBUF_INIT;
183                         unable_to_lock_message(path, errno, &buf);
184                         error("%s", buf.buf);
185                         strbuf_release(&buf);
186                 }
187         }
188         return fd;
189 }
190
191 char *get_locked_file_path(struct lock_file *lk)
192 {
193         struct strbuf ret = STRBUF_INIT;
194
195         strbuf_addstr(&ret, get_tempfile_path(lk->tempfile));
196         if (ret.len <= LOCK_SUFFIX_LEN ||
197             strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
198                 BUG("get_locked_file_path() called for malformed lock object");
199         /* remove ".lock": */
200         strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN);
201         return strbuf_detach(&ret, NULL);
202 }
203
204 int commit_lock_file(struct lock_file *lk)
205 {
206         char *result_path = get_locked_file_path(lk);
207
208         if (commit_lock_file_to(lk, result_path)) {
209                 int save_errno = errno;
210                 free(result_path);
211                 errno = save_errno;
212                 return -1;
213         }
214         free(result_path);
215         return 0;
216 }