lock_file(): always initialize and register lock_file object
[git/debian.git] / lockfile.c
blob81143e55ad9fde888de1875d039439b611124375
1 /*
2 * Copyright (c) 2005, Junio C Hamano
3 */
4 #include "cache.h"
5 #include "sigchain.h"
7 static struct lock_file *lock_file_list;
9 static void remove_lock_file(void)
11 pid_t me = getpid();
13 while (lock_file_list) {
14 if (lock_file_list->owner == me &&
15 lock_file_list->filename[0]) {
16 if (lock_file_list->fd >= 0)
17 close(lock_file_list->fd);
18 unlink_or_warn(lock_file_list->filename);
20 lock_file_list = lock_file_list->next;
24 static void remove_lock_file_on_signal(int signo)
26 remove_lock_file();
27 sigchain_pop(signo);
28 raise(signo);
32 * p = absolute or relative path name
34 * Return a pointer into p showing the beginning of the last path name
35 * element. If p is empty or the root directory ("/"), just return p.
37 static char *last_path_elm(char *p)
39 /* r starts pointing to null at the end of the string */
40 char *r = strchr(p, '\0');
42 if (r == p)
43 return p; /* just return empty string */
45 r--; /* back up to last non-null character */
47 /* back up past trailing slashes, if any */
48 while (r > p && *r == '/')
49 r--;
52 * then go backwards until I hit a slash, or the beginning of
53 * the string
55 while (r > p && *(r-1) != '/')
56 r--;
57 return r;
61 /* We allow "recursive" symbolic links. Only within reason, though */
62 #define MAXDEPTH 5
65 * p = path that may be a symlink
66 * s = full size of p
68 * If p is a symlink, attempt to overwrite p with a path to the real
69 * file or directory (which may or may not exist), following a chain of
70 * symlinks if necessary. Otherwise, leave p unmodified.
72 * This is a best-effort routine. If an error occurs, p will either be
73 * left unmodified or will name a different symlink in a symlink chain
74 * that started with p's initial contents.
76 * Always returns p.
79 static char *resolve_symlink(char *p, size_t s)
81 int depth = MAXDEPTH;
83 while (depth--) {
84 char link[PATH_MAX];
85 int link_len = readlink(p, link, sizeof(link));
86 if (link_len < 0) {
87 /* not a symlink anymore */
88 return p;
90 else if (link_len < sizeof(link))
91 /* readlink() never null-terminates */
92 link[link_len] = '\0';
93 else {
94 warning("%s: symlink too long", p);
95 return p;
98 if (is_absolute_path(link)) {
99 /* absolute path simply replaces p */
100 if (link_len < s)
101 strcpy(p, link);
102 else {
103 warning("%s: symlink too long", p);
104 return p;
106 } else {
108 * link is a relative path, so I must replace the
109 * last element of p with it.
111 char *r = (char *)last_path_elm(p);
112 if (r - p + link_len < s)
113 strcpy(r, link);
114 else {
115 warning("%s: symlink too long", p);
116 return p;
120 return p;
123 /* Make sure errno contains a meaningful value on error */
124 static int lock_file(struct lock_file *lk, const char *path, int flags)
127 * subtract 5 from size to make sure there's room for adding
128 * ".lock" for the lock file name
130 static const size_t max_path_len = sizeof(lk->filename) - 5;
132 if (!lock_file_list) {
133 /* One-time initialization */
134 sigchain_push_common(remove_lock_file_on_signal);
135 atexit(remove_lock_file);
138 if (!lk->on_list) {
139 /* Initialize *lk and add it to lock_file_list: */
140 lk->fd = -1;
141 lk->owner = 0;
142 lk->filename[0] = 0;
143 lk->next = lock_file_list;
144 lock_file_list = lk;
145 lk->on_list = 1;
148 if (strlen(path) >= max_path_len) {
149 errno = ENAMETOOLONG;
150 return -1;
152 strcpy(lk->filename, path);
153 if (!(flags & LOCK_NODEREF))
154 resolve_symlink(lk->filename, max_path_len);
155 strcat(lk->filename, ".lock");
156 lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
157 if (0 <= lk->fd) {
158 lk->owner = getpid();
159 if (adjust_shared_perm(lk->filename)) {
160 int save_errno = errno;
161 error("cannot fix permission bits on %s",
162 lk->filename);
163 rollback_lock_file(lk);
164 errno = save_errno;
165 return -1;
168 else
169 lk->filename[0] = 0;
170 return lk->fd;
173 void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
175 if (err == EEXIST) {
176 strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
177 "If no other git process is currently running, this probably means a\n"
178 "git process crashed in this repository earlier. Make sure no other git\n"
179 "process is running and remove the file manually to continue.",
180 absolute_path(path), strerror(err));
181 } else
182 strbuf_addf(buf, "Unable to create '%s.lock': %s",
183 absolute_path(path), strerror(err));
186 int unable_to_lock_error(const char *path, int err)
188 struct strbuf buf = STRBUF_INIT;
190 unable_to_lock_message(path, err, &buf);
191 error("%s", buf.buf);
192 strbuf_release(&buf);
193 return -1;
196 NORETURN void unable_to_lock_die(const char *path, int err)
198 struct strbuf buf = STRBUF_INIT;
200 unable_to_lock_message(path, err, &buf);
201 die("%s", buf.buf);
204 /* This should return a meaningful errno on failure */
205 int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
207 int fd = lock_file(lk, path, flags);
208 if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
209 unable_to_lock_die(path, errno);
210 return fd;
213 int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
215 int fd, orig_fd;
217 fd = lock_file(lk, path, flags);
218 if (fd < 0) {
219 if (flags & LOCK_DIE_ON_ERROR)
220 unable_to_lock_die(path, errno);
221 return fd;
224 orig_fd = open(path, O_RDONLY);
225 if (orig_fd < 0) {
226 if (errno != ENOENT) {
227 if (flags & LOCK_DIE_ON_ERROR)
228 die("cannot open '%s' for copying", path);
229 rollback_lock_file(lk);
230 return error("cannot open '%s' for copying", path);
232 } else if (copy_fd(orig_fd, fd)) {
233 if (flags & LOCK_DIE_ON_ERROR)
234 exit(128);
235 rollback_lock_file(lk);
236 return -1;
238 return fd;
241 int close_lock_file(struct lock_file *lk)
243 int fd = lk->fd;
245 if (fd < 0)
246 return 0;
248 lk->fd = -1;
249 return close(fd);
252 int reopen_lock_file(struct lock_file *lk)
254 if (0 <= lk->fd)
255 die(_("BUG: reopen a lockfile that is still open"));
256 if (!lk->filename[0])
257 die(_("BUG: reopen a lockfile that has been committed"));
258 lk->fd = open(lk->filename, O_WRONLY);
259 return lk->fd;
262 int commit_lock_file(struct lock_file *lk)
264 char result_file[PATH_MAX];
265 size_t i;
266 if (close_lock_file(lk))
267 return -1;
268 strcpy(result_file, lk->filename);
269 i = strlen(result_file) - 5; /* .lock */
270 result_file[i] = 0;
271 if (rename(lk->filename, result_file))
272 return -1;
273 lk->filename[0] = 0;
274 return 0;
277 int hold_locked_index(struct lock_file *lk, int die_on_error)
279 return hold_lock_file_for_update(lk, get_index_file(),
280 die_on_error
281 ? LOCK_DIE_ON_ERROR
282 : 0);
285 void rollback_lock_file(struct lock_file *lk)
287 if (!lk->filename[0])
288 return;
290 close_lock_file(lk);
291 unlink_or_warn(lk->filename);
292 lk->filename[0] = 0;