]>
git.ipfire.org Git - thirdparty/git.git/blob - lockfile.c
2 * Copyright (c) 2005, Junio C Hamano
10 * path = absolute or relative path name
12 * Remove the last path name element from path (leaving the preceding
13 * "/", if any). If path is empty or the root directory ("/"), set
14 * path to the empty string.
16 static void trim_last_path_component(struct strbuf
*path
)
20 /* back up past trailing slashes, if any */
21 while (i
&& path
->buf
[i
- 1] == '/')
25 * then go backwards until a slash, or the beginning of the
28 while (i
&& path
->buf
[i
- 1] != '/')
31 strbuf_setlen(path
, i
);
35 /* We allow "recursive" symbolic links. Only within reason, though */
39 * path contains a path that might be a symlink.
41 * If path is a symlink, attempt to overwrite it with a path to the
42 * real file or directory (which may or may not exist), following a
43 * chain of symlinks if necessary. Otherwise, leave path unmodified.
45 * This is a best-effort routine. If an error occurs, path will
46 * either be left unmodified or will name a different symlink in a
47 * symlink chain that started with the original path.
49 static void resolve_symlink(struct strbuf
*path
)
52 static struct strbuf link
= STRBUF_INIT
;
55 if (strbuf_readlink(&link
, path
->buf
, path
->len
) < 0)
58 if (is_absolute_path(link
.buf
))
59 /* absolute path simply replaces p */
63 * link is a relative path, so replace the
64 * last element of p with it.
66 trim_last_path_component(path
);
68 strbuf_addbuf(path
, &link
);
73 /* Make sure errno contains a meaningful value on error */
74 static int lock_file(struct lock_file
*lk
, const char *path
, int flags
,
77 struct strbuf filename
= STRBUF_INIT
;
79 strbuf_addstr(&filename
, path
);
80 if (!(flags
& LOCK_NO_DEREF
))
81 resolve_symlink(&filename
);
83 strbuf_addstr(&filename
, LOCK_SUFFIX
);
84 lk
->tempfile
= create_tempfile_mode(filename
.buf
, mode
);
85 strbuf_release(&filename
);
86 return lk
->tempfile
? lk
->tempfile
->fd
: -1;
90 * Constants defining the gaps between attempts to lock a file. The
91 * first backoff period is approximately INITIAL_BACKOFF_MS
92 * milliseconds. The longest backoff period is approximately
93 * (BACKOFF_MAX_MULTIPLIER * INITIAL_BACKOFF_MS) milliseconds.
95 #define INITIAL_BACKOFF_MS 1L
96 #define BACKOFF_MAX_MULTIPLIER 1000
99 * Try locking path, retrying with quadratic backoff for at least
100 * timeout_ms milliseconds. If timeout_ms is 0, try locking the file
101 * exactly once. If timeout_ms is -1, try indefinitely.
103 static int lock_file_timeout(struct lock_file
*lk
, const char *path
,
104 int flags
, long timeout_ms
, int mode
)
108 long remaining_ms
= 0;
109 static int random_initialized
= 0;
112 return lock_file(lk
, path
, flags
, mode
);
114 if (!random_initialized
) {
115 srand((unsigned int)getpid());
116 random_initialized
= 1;
120 remaining_ms
= timeout_ms
;
123 long backoff_ms
, wait_ms
;
126 fd
= lock_file(lk
, path
, flags
, mode
);
129 return fd
; /* success */
130 else if (errno
!= EEXIST
)
131 return -1; /* failure other than lock held */
132 else if (timeout_ms
> 0 && remaining_ms
<= 0)
133 return -1; /* failure due to timeout */
135 backoff_ms
= multiplier
* INITIAL_BACKOFF_MS
;
136 /* back off for between 0.75*backoff_ms and 1.25*backoff_ms */
137 wait_ms
= (750 + rand() % 500) * backoff_ms
/ 1000;
138 sleep_millisec(wait_ms
);
139 remaining_ms
-= wait_ms
;
141 /* Recursion: (n+1)^2 = n^2 + 2n + 1 */
142 multiplier
+= 2*n
+ 1;
143 if (multiplier
> BACKOFF_MAX_MULTIPLIER
)
144 multiplier
= BACKOFF_MAX_MULTIPLIER
;
150 void unable_to_lock_message(const char *path
, int err
, struct strbuf
*buf
)
153 strbuf_addf(buf
, _("Unable to create '%s.lock': %s.\n\n"
154 "Another git process seems to be running in this repository, e.g.\n"
155 "an editor opened by 'git commit'. Please make sure all processes\n"
156 "are terminated then try again. If it still fails, a git process\n"
157 "may have crashed in this repository earlier:\n"
158 "remove the file manually to continue."),
159 absolute_path(path
), strerror(err
));
161 strbuf_addf(buf
, _("Unable to create '%s.lock': %s"),
162 absolute_path(path
), strerror(err
));
165 NORETURN
void unable_to_lock_die(const char *path
, int err
)
167 struct strbuf buf
= STRBUF_INIT
;
169 unable_to_lock_message(path
, err
, &buf
);
173 /* This should return a meaningful errno on failure */
174 int hold_lock_file_for_update_timeout_mode(struct lock_file
*lk
,
175 const char *path
, int flags
,
176 long timeout_ms
, int mode
)
178 int fd
= lock_file_timeout(lk
, path
, flags
, timeout_ms
, mode
);
180 if (flags
& LOCK_DIE_ON_ERROR
)
181 unable_to_lock_die(path
, errno
);
182 if (flags
& LOCK_REPORT_ON_ERROR
) {
183 struct strbuf buf
= STRBUF_INIT
;
184 unable_to_lock_message(path
, errno
, &buf
);
185 error("%s", buf
.buf
);
186 strbuf_release(&buf
);
192 char *get_locked_file_path(struct lock_file
*lk
)
194 struct strbuf ret
= STRBUF_INIT
;
196 strbuf_addstr(&ret
, get_tempfile_path(lk
->tempfile
));
197 if (ret
.len
<= LOCK_SUFFIX_LEN
||
198 strcmp(ret
.buf
+ ret
.len
- LOCK_SUFFIX_LEN
, LOCK_SUFFIX
))
199 BUG("get_locked_file_path() called for malformed lock object");
200 /* remove ".lock": */
201 strbuf_setlen(&ret
, ret
.len
- LOCK_SUFFIX_LEN
);
202 return strbuf_detach(&ret
, NULL
);
205 int commit_lock_file(struct lock_file
*lk
)
207 char *result_path
= get_locked_file_path(lk
);
209 if (commit_lock_file_to(lk
, result_path
)) {
210 int save_errno
= errno
;