🌐 AI搜索 & 代理 主页
blob: 1d5ed0168287464e24d60e30b0cfbce181676535 [file] [log] [blame]
Junio C Hamano021b6e42006-06-06 19:51:491/*
2 * Copyright (c) 2005, Junio C Hamano
3 */
Michael Haggerty2db69de2015-08-10 09:47:364
Elijah Newrena64acf72023-03-21 06:26:025#include "git-compat-util.h"
Elijah Newren0b027f62023-03-21 06:25:586#include "abspath.h"
Elijah Newrenf394e092023-03-21 06:25:547#include "gettext.h"
Michael Haggerty697cc8e2014-10-01 10:28:428#include "lockfile.h"
Junio C Hamano021b6e42006-06-06 19:51:499
Bradford C. Smith5d5a7a62007-07-26 17:34:1410/*
Michael Haggerty0c0d6e82014-10-01 10:28:3511 * path = absolute or relative path name
Bradford C. Smith5d5a7a62007-07-26 17:34:1412 *
Michael Haggerty0c0d6e82014-10-01 10:28:3513 * 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 17:34:1416 */
Michael Haggerty0c0d6e82014-10-01 10:28:3517static void trim_last_path_component(struct strbuf *path)
Bradford C. Smith5d5a7a62007-07-26 17:34:1418{
Michael Haggerty0c0d6e82014-10-01 10:28:3519 int i = path->len;
Bradford C. Smith5d5a7a62007-07-26 17:34:1420
21 /* back up past trailing slashes, if any */
Michael Haggerty0c0d6e82014-10-01 10:28:3522 while (i && path->buf[i - 1] == '/')
23 i--;
Bradford C. Smith5d5a7a62007-07-26 17:34:1424
25 /*
Michael Haggerty0c0d6e82014-10-01 10:28:3526 * then go backwards until a slash, or the beginning of the
27 * string
Bradford C. Smith5d5a7a62007-07-26 17:34:1428 */
Michael Haggerty0c0d6e82014-10-01 10:28:3529 while (i && path->buf[i - 1] != '/')
30 i--;
31
32 strbuf_setlen(path, i);
Bradford C. Smith5d5a7a62007-07-26 17:34:1433}
34
35
36/* We allow "recursive" symbolic links. Only within reason, though */
37#define MAXDEPTH 5
38
39/*
Michael Haggerty6cad8052014-10-01 10:28:3440 * path contains a path that might be a symlink.
Bradford C. Smith5d5a7a62007-07-26 17:34:1441 *
Michael Haggerty6cad8052014-10-01 10:28:3442 * 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 17:34:1445 *
Michael Haggerty6cad8052014-10-01 10:28:3446 * 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 17:34:1449 */
Michael Haggerty6cad8052014-10-01 10:28:3450static void resolve_symlink(struct strbuf *path)
Bradford C. Smith5d5a7a62007-07-26 17:34:1451{
52 int depth = MAXDEPTH;
Michael Haggerty5025d842014-10-01 10:28:3353 static struct strbuf link = STRBUF_INIT;
Bradford C. Smith5d5a7a62007-07-26 17:34:1454
55 while (depth--) {
Michael Haggerty6cad8052014-10-01 10:28:3456 if (strbuf_readlink(&link, path->buf, path->len) < 0)
Michael Haggerty5025d842014-10-01 10:28:3357 break;
Bradford C. Smith5d5a7a62007-07-26 17:34:1458
Michael Haggerty6cad8052014-10-01 10:28:3459 if (is_absolute_path(link.buf))
Bradford C. Smith5d5a7a62007-07-26 17:34:1460 /* absolute path simply replaces p */
Michael Haggerty6cad8052014-10-01 10:28:3461 strbuf_reset(path);
Michael Haggerty0c0d6e82014-10-01 10:28:3562 else
Bradford C. Smith5d5a7a62007-07-26 17:34:1463 /*
Michael Haggerty5025d842014-10-01 10:28:3364 * link is a relative path, so replace the
Bradford C. Smith5d5a7a62007-07-26 17:34:1465 * last element of p with it.
66 */
Michael Haggerty0c0d6e82014-10-01 10:28:3567 trim_last_path_component(path);
Michael Haggerty6cad8052014-10-01 10:28:3468
69 strbuf_addbuf(path, &link);
Bradford C. Smith5d5a7a62007-07-26 17:34:1470 }
Michael Haggerty5025d842014-10-01 10:28:3371 strbuf_reset(&link);
Bradford C. Smith5d5a7a62007-07-26 17:34:1472}
73
Ronnie Sahlberg447ff1b2014-06-20 14:42:4874/* Make sure errno contains a meaningful value on error */
Taylor Blaufa3bff22020-04-27 16:27:5875static int lock_file(struct lock_file *lk, const char *path, int flags,
76 int mode)
Junio C Hamano021b6e42006-06-06 19:51:4977{
Michael Haggerty1a9d15d2015-08-10 09:47:4178 struct strbuf filename = STRBUF_INIT;
Michael Haggerty2fbd4f92013-07-06 19:48:5279
Michael Haggerty1a9d15d2015-08-10 09:47:4180 strbuf_addstr(&filename, path);
81 if (!(flags & LOCK_NO_DEREF))
82 resolve_symlink(&filename);
Michael Haggerty04e57d42014-10-01 10:28:1383
Michael Haggerty1a9d15d2015-08-10 09:47:4184 strbuf_addstr(&filename, LOCK_SUFFIX);
Taylor Blaufa3bff22020-04-27 16:27:5885 lk->tempfile = create_tempfile_mode(filename.buf, mode);
Michael Haggerty1a9d15d2015-08-10 09:47:4186 strbuf_release(&filename);
Jeff King076aa2c2017-09-05 12:15:0887 return lk->tempfile ? lk->tempfile->fd : -1;
Junio C Hamano021b6e42006-06-06 19:51:4988}
89
Michael Haggerty044b6a92015-05-11 10:35:2590/*
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 16:27:58105 int flags, long timeout_ms, int mode)
Michael Haggerty044b6a92015-05-11 10:35:25106{
107 int n = 1;
108 int multiplier = 1;
Johannes Sixta8a17752015-06-05 19:45:06109 long remaining_ms = 0;
Michael Haggerty044b6a92015-05-11 10:35:25110 static int random_initialized = 0;
111
112 if (timeout_ms == 0)
Taylor Blaufa3bff22020-04-27 16:27:58113 return lock_file(lk, path, flags, mode);
Michael Haggerty044b6a92015-05-11 10:35:25114
115 if (!random_initialized) {
Johannes Sixt1e9676e2015-06-05 19:45:04116 srand((unsigned int)getpid());
Michael Haggerty044b6a92015-05-11 10:35:25117 random_initialized = 1;
118 }
119
Johannes Sixta8a17752015-06-05 19:45:06120 if (timeout_ms > 0)
121 remaining_ms = timeout_ms;
Michael Haggerty044b6a92015-05-11 10:35:25122
123 while (1) {
Johannes Sixta8a17752015-06-05 19:45:06124 long backoff_ms, wait_ms;
Michael Haggerty044b6a92015-05-11 10:35:25125 int fd;
126
Taylor Blaufa3bff22020-04-27 16:27:58127 fd = lock_file(lk, path, flags, mode);
Michael Haggerty044b6a92015-05-11 10:35:25128
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 19:45:06133 else if (timeout_ms > 0 && remaining_ms <= 0)
Michael Haggerty044b6a92015-05-11 10:35:25134 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 19:45:06138 wait_ms = (750 + rand() % 500) * backoff_ms / 1000;
Johannes Sixt30f81602015-06-05 19:45:07139 sleep_millisec(wait_ms);
Johannes Sixta8a17752015-06-05 19:45:06140 remaining_ms -= wait_ms;
Michael Haggerty044b6a92015-05-11 10:35:25141
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 14:42:47151void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
Matthieu Moye43a6fd2009-02-19 12:54:18152{
John Tapsellbdfd7392009-03-04 15:00:44153 if (err == EEXIST) {
Matthieu Moy3030c292016-03-01 17:04:09154 strbuf_addf(buf, _("Unable to create '%s.lock': %s.\n\n"
Matthieu Moyaed74802016-03-01 17:04:10155 "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 11:26:46160 absolute_path(path), strerror(err));
Miklos Vajna1b018fd2009-09-26 23:15:09161 } else
Matthieu Moy3030c292016-03-01 17:04:09162 strbuf_addf(buf, _("Unable to create '%s.lock': %s"),
Carlos Martín Nietoe2a57aa2011-03-17 11:26:46163 absolute_path(path), strerror(err));
Miklos Vajna1b018fd2009-09-26 23:15:09164}
165
Michael Haggertye197c212014-10-01 10:28:05166NORETURN void unable_to_lock_die(const char *path, int err)
Miklos Vajna1b018fd2009-09-26 23:15:09167{
Ronnie Sahlberg6af926e2014-06-20 14:42:47168 struct strbuf buf = STRBUF_INIT;
169
170 unable_to_lock_message(path, err, &buf);
171 die("%s", buf.buf);
Matthieu Moye43a6fd2009-02-19 12:54:18172}
173
Ronnie Sahlberg447ff1b2014-06-20 14:42:48174/* This should return a meaningful errno on failure */
Taylor Blaufa3bff22020-04-27 16:27:58175int 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 08:03:47178{
Taylor Blaufa3bff22020-04-27 16:27:58179 int fd = lock_file_timeout(lk, path, flags, timeout_ms, mode);
Junio C Hamano3f061bf2016-12-07 18:56:26180 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 08:03:47190 return fd;
191}
192
Michael Haggertyec38b4e2014-10-01 10:28:39193char *get_locked_file_path(struct lock_file *lk)
194{
Michael Haggerty1a9d15d2015-08-10 09:47:41195 struct strbuf ret = STRBUF_INIT;
196
Jeff King076aa2c2017-09-05 12:15:08197 strbuf_addstr(&ret, get_tempfile_path(lk->tempfile));
Michael Haggerty1a9d15d2015-08-10 09:47:41198 if (ret.len <= LOCK_SUFFIX_LEN ||
199 strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
Johannes Schindelin033abf92018-05-02 09:38:39200 BUG("get_locked_file_path() called for malformed lock object");
Michael Haggerty9c773812015-08-10 09:47:40201 /* remove ".lock": */
Michael Haggerty1a9d15d2015-08-10 09:47:41202 strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN);
203 return strbuf_detach(&ret, NULL);
Junio C Hamano021b6e42006-06-06 19:51:49204}
205
Junio C Hamano021b6e42006-06-06 19:51:49206int commit_lock_file(struct lock_file *lk)
207{
Michael Haggerty9c773812015-08-10 09:47:40208 char *result_path = get_locked_file_path(lk);
Junio C Hamano021b6e42006-06-06 19:51:49209
Michael Haggerty9c773812015-08-10 09:47:40210 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 20:05:03215 }
Michael Haggerty9c773812015-08-10 09:47:40216 free(result_path);
217 return 0;
Junio C Hamano021b6e42006-06-06 19:51:49218}