blob: 1d5ed0168287464e24d60e30b0cfbce181676535 [file] [log] [blame]
Junio C Hamano021b6e42006-06-06 12:51:49 -07001/*
2 * Copyright (c) 2005, Junio C Hamano
3 */
Michael Haggerty2db69de2015-08-10 11:47:36 +02004
Elijah Newrena64acf72023-03-21 06:26:02 +00005#include "git-compat-util.h"
Elijah Newren0b027f62023-03-21 06:25:58 +00006#include "abspath.h"
Elijah Newrenf394e092023-03-21 06:25:54 +00007#include "gettext.h"
Michael Haggerty697cc8e2014-10-01 12:28:42 +02008#include "lockfile.h"
Junio C Hamano021b6e42006-06-06 12:51:49 -07009
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040010/*
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020011 * path = absolute or relative path name
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040012 *
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020013 * Remove the last path name element from path (leaving the preceding
14 * "/", if any). If path is empty or the root directory ("/"), set
15 * path to the empty string.
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040016 */
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020017static void trim_last_path_component(struct strbuf *path)
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040018{
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020019 int i = path->len;
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040020
21 /* back up past trailing slashes, if any */
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020022 while (i && path->buf[i - 1] == '/')
23 i--;
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040024
25 /*
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020026 * then go backwards until a slash, or the beginning of the
27 * string
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040028 */
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020029 while (i && path->buf[i - 1] != '/')
30 i--;
31
32 strbuf_setlen(path, i);
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040033}
34
35
36/* We allow "recursive" symbolic links. Only within reason, though */
37#define MAXDEPTH 5
38
39/*
Michael Haggerty6cad8052014-10-01 12:28:34 +020040 * path contains a path that might be a symlink.
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040041 *
Michael Haggerty6cad8052014-10-01 12:28:34 +020042 * If path is a symlink, attempt to overwrite it with a path to the
43 * real file or directory (which may or may not exist), following a
44 * chain of symlinks if necessary. Otherwise, leave path unmodified.
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040045 *
Michael Haggerty6cad8052014-10-01 12:28:34 +020046 * This is a best-effort routine. If an error occurs, path will
47 * either be left unmodified or will name a different symlink in a
48 * symlink chain that started with the original path.
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040049 */
Michael Haggerty6cad8052014-10-01 12:28:34 +020050static void resolve_symlink(struct strbuf *path)
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040051{
52 int depth = MAXDEPTH;
Michael Haggerty5025d842014-10-01 12:28:33 +020053 static struct strbuf link = STRBUF_INIT;
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040054
55 while (depth--) {
Michael Haggerty6cad8052014-10-01 12:28:34 +020056 if (strbuf_readlink(&link, path->buf, path->len) < 0)
Michael Haggerty5025d842014-10-01 12:28:33 +020057 break;
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040058
Michael Haggerty6cad8052014-10-01 12:28:34 +020059 if (is_absolute_path(link.buf))
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040060 /* absolute path simply replaces p */
Michael Haggerty6cad8052014-10-01 12:28:34 +020061 strbuf_reset(path);
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020062 else
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040063 /*
Michael Haggerty5025d842014-10-01 12:28:33 +020064 * link is a relative path, so replace the
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040065 * last element of p with it.
66 */
Michael Haggerty0c0d6e82014-10-01 12:28:35 +020067 trim_last_path_component(path);
Michael Haggerty6cad8052014-10-01 12:28:34 +020068
69 strbuf_addbuf(path, &link);
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040070 }
Michael Haggerty5025d842014-10-01 12:28:33 +020071 strbuf_reset(&link);
Bradford C. Smith5d5a7a62007-07-26 13:34:14 -040072}
73
Ronnie Sahlberg447ff1b2014-06-20 07:42:48 -070074/* Make sure errno contains a meaningful value on error */
Taylor Blaufa3bff22020-04-27 10:27:58 -060075static int lock_file(struct lock_file *lk, const char *path, int flags,
76 int mode)
Junio C Hamano021b6e42006-06-06 12:51:49 -070077{
Michael Haggerty1a9d15d2015-08-10 11:47:41 +020078 struct strbuf filename = STRBUF_INIT;
Michael Haggerty2fbd4f92013-07-06 21:48:52 +020079
Michael Haggerty1a9d15d2015-08-10 11:47:41 +020080 strbuf_addstr(&filename, path);
81 if (!(flags & LOCK_NO_DEREF))
82 resolve_symlink(&filename);
Michael Haggerty04e57d42014-10-01 12:28:13 +020083
Michael Haggerty1a9d15d2015-08-10 11:47:41 +020084 strbuf_addstr(&filename, LOCK_SUFFIX);
Taylor Blaufa3bff22020-04-27 10:27:58 -060085 lk->tempfile = create_tempfile_mode(filename.buf, mode);
Michael Haggerty1a9d15d2015-08-10 11:47:41 +020086 strbuf_release(&filename);
Jeff King076aa2c2017-09-05 08:15:08 -040087 return lk->tempfile ? lk->tempfile->fd : -1;
Junio C Hamano021b6e42006-06-06 12:51:49 -070088}
89
Michael Haggerty044b6a92015-05-11 12:35:25 +020090/*
91 * Constants defining the gaps between attempts to lock a file. The
92 * first backoff period is approximately INITIAL_BACKOFF_MS
93 * milliseconds. The longest backoff period is approximately
94 * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds.
95 */
96#define INITIAL_BACKOFF_MS 1L
97#define BACKOFF_MAX_MULTIPLIER 1000
98
99/*
100 * Try locking path, retrying with quadratic backoff for at least
101 * timeout_ms milliseconds. If timeout_ms is 0, try locking the file
102 * exactly once. If timeout_ms is -1, try indefinitely.
103 */
104static int lock_file_timeout(struct lock_file *lk, const char *path,
Taylor Blaufa3bff22020-04-27 10:27:58 -0600105 int flags, long timeout_ms, int mode)
Michael Haggerty044b6a92015-05-11 12:35:25 +0200106{
107 int n = 1;
108 int multiplier = 1;
Johannes Sixta8a17752015-06-05 21:45:06 +0200109 long remaining_ms = 0;
Michael Haggerty044b6a92015-05-11 12:35:25 +0200110 static int random_initialized = 0;
111
112 if (timeout_ms == 0)
Taylor Blaufa3bff22020-04-27 10:27:58 -0600113 return lock_file(lk, path, flags, mode);
Michael Haggerty044b6a92015-05-11 12:35:25 +0200114
115 if (!random_initialized) {
Johannes Sixt1e9676e2015-06-05 21:45:04 +0200116 srand((unsigned int)getpid());
Michael Haggerty044b6a92015-05-11 12:35:25 +0200117 random_initialized = 1;
118 }
119
Johannes Sixta8a17752015-06-05 21:45:06 +0200120 if (timeout_ms > 0)
121 remaining_ms = timeout_ms;
Michael Haggerty044b6a92015-05-11 12:35:25 +0200122
123 while (1) {
Johannes Sixta8a17752015-06-05 21:45:06 +0200124 long backoff_ms, wait_ms;
Michael Haggerty044b6a92015-05-11 12:35:25 +0200125 int fd;
126
Taylor Blaufa3bff22020-04-27 10:27:58 -0600127 fd = lock_file(lk, path, flags, mode);
Michael Haggerty044b6a92015-05-11 12:35:25 +0200128
129 if (fd >= 0)
130 return fd; /* success */
131 else if (errno != EEXIST)
132 return -1; /* failure other than lock held */
Johannes Sixta8a17752015-06-05 21:45:06 +0200133 else if (timeout_ms > 0 && remaining_ms <= 0)
Michael Haggerty044b6a92015-05-11 12:35:25 +0200134 return -1; /* failure due to timeout */
135
136 backoff_ms = multiplier * INITIAL_BACKOFF_MS;
137 /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
Johannes Sixta8a17752015-06-05 21:45:06 +0200138 wait_ms = (750 + rand() % 500) * backoff_ms / 1000;
Johannes Sixt30f81602015-06-05 21:45:07 +0200139 sleep_millisec(wait_ms);
Johannes Sixta8a17752015-06-05 21:45:06 +0200140 remaining_ms -= wait_ms;
Michael Haggerty044b6a92015-05-11 12:35:25 +0200141
142 /* Recursion: (n+1)^2 = n^2 + 2n + 1 */
143 multiplier += 2*n + 1;
144 if (multiplier > BACKOFF_MAX_MULTIPLIER)
145 multiplier = BACKOFF_MAX_MULTIPLIER;
146 else
147 n++;
148 }
149}
150
Ronnie Sahlberg6af926e2014-06-20 07:42:47 -0700151void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
Matthieu Moye43a6fd2009-02-19 13:54:18 +0100152{
John Tapsellbdfd7392009-03-04 15:00:44 +0000153 if (err == EEXIST) {
Matthieu Moy3030c292016-03-01 18:04:09 +0100154 strbuf_addf(buf, _("Unable to create '%s.lock': %s.\n\n"
Matthieu Moyaed74802016-03-01 18:04:10 +0100155 "Another git process seems to be running in this repository, e.g.\n"
156 "an editor opened by 'git commit'. Please make sure all processes\n"
157 "are terminated then try again. If it still fails, a git process\n"
158 "may have crashed in this repository earlier:\n"
159 "remove the file manually to continue."),
Carlos Martín Nietoe2a57aa2011-03-17 12:26:46 +0100160 absolute_path(path), strerror(err));
Miklos Vajna1b018fd2009-09-27 01:15:09 +0200161 } else
Matthieu Moy3030c292016-03-01 18:04:09 +0100162 strbuf_addf(buf, _("Unable to create '%s.lock': %s"),
Carlos Martín Nietoe2a57aa2011-03-17 12:26:46 +0100163 absolute_path(path), strerror(err));
Miklos Vajna1b018fd2009-09-27 01:15:09 +0200164}
165
Michael Haggertye197c212014-10-01 12:28:05 +0200166NORETURN void unable_to_lock_die(const char *path, int err)
Miklos Vajna1b018fd2009-09-27 01:15:09 +0200167{
Ronnie Sahlberg6af926e2014-06-20 07:42:47 -0700168 struct strbuf buf = STRBUF_INIT;
169
170 unable_to_lock_message(path, err, &buf);
171 die("%s", buf.buf);
Matthieu Moye43a6fd2009-02-19 13:54:18 +0100172}
173
Ronnie Sahlberg447ff1b2014-06-20 07:42:48 -0700174/* This should return a meaningful errno on failure */
Taylor Blaufa3bff22020-04-27 10:27:58 -0600175int hold_lock_file_for_update_timeout_mode(struct lock_file *lk,
176 const char *path, int flags,
177 long timeout_ms, int mode)
Junio C Hamano40aaae82006-08-12 01:03:47 -0700178{
Taylor Blaufa3bff22020-04-27 10:27:58 -0600179 int fd = lock_file_timeout(lk, path, flags, timeout_ms, mode);
Junio C Hamano3f061bf2016-12-07 10:56:26 -0800180 if (fd < 0) {
181 if (flags & LOCK_DIE_ON_ERROR)
182 unable_to_lock_die(path, errno);
183 if (flags & LOCK_REPORT_ON_ERROR) {
184 struct strbuf buf = STRBUF_INIT;
185 unable_to_lock_message(path, errno, &buf);
186 error("%s", buf.buf);
187 strbuf_release(&buf);
188 }
189 }
Junio C Hamano40aaae82006-08-12 01:03:47 -0700190 return fd;
191}
192
Michael Haggertyec38b4e2014-10-01 12:28:39 +0200193char *get_locked_file_path(struct lock_file *lk)
194{
Michael Haggerty1a9d15d2015-08-10 11:47:41 +0200195 struct strbuf ret = STRBUF_INIT;
196
Jeff King076aa2c2017-09-05 08:15:08 -0400197 strbuf_addstr(&ret, get_tempfile_path(lk->tempfile));
Michael Haggerty1a9d15d2015-08-10 11:47:41 +0200198 if (ret.len <= LOCK_SUFFIX_LEN ||
199 strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
Johannes Schindelin033abf92018-05-02 11:38:39 +0200200 BUG("get_locked_file_path() called for malformed lock object");
Michael Haggerty9c773812015-08-10 11:47:40 +0200201 /* remove ".lock": */
Michael Haggerty1a9d15d2015-08-10 11:47:41 +0200202 strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN);
203 return strbuf_detach(&ret, NULL);
Junio C Hamano021b6e42006-06-06 12:51:49 -0700204}
205
Junio C Hamano021b6e42006-06-06 12:51:49 -0700206int commit_lock_file(struct lock_file *lk)
207{
Michael Haggerty9c773812015-08-10 11:47:40 +0200208 char *result_path = get_locked_file_path(lk);
Junio C Hamano021b6e42006-06-06 12:51:49 -0700209
Michael Haggerty9c773812015-08-10 11:47:40 +0200210 if (commit_lock_file_to(lk, result_path)) {
211 int save_errno = errno;
212 free(result_path);
213 errno = save_errno;
214 return -1;
Johannes Schindelin4723ee92007-11-13 21:05:03 +0100215 }
Michael Haggerty9c773812015-08-10 11:47:40 +0200216 free(result_path);
217 return 0;
Junio C Hamano021b6e42006-06-06 12:51:49 -0700218}