lockfile.c 7.9 KB
Newer Older
1 2 3 4
/*
 * Copyright (c) 2005, Junio C Hamano
 */
#include "cache.h"
5
#include "lockfile.h"
6
#include "sigchain.h"
7

8
static struct lock_file *volatile lock_file_list;
9

10
static void remove_lock_files(int skip_fclose)
11
{
12 13
	pid_t me = getpid();

14
	while (lock_file_list) {
15 16 17 18
		if (lock_file_list->owner == me) {
			/* fclose() is not safe to call in a signal handler */
			if (skip_fclose)
				lock_file_list->fp = NULL;
19
			rollback_lock_file(lock_file_list);
20
		}
21 22 23 24
		lock_file_list = lock_file_list->next;
	}
}

25 26 27 28 29
static void remove_lock_files_on_exit(void)
{
	remove_lock_files(0);
}

30
static void remove_lock_files_on_signal(int signo)
31
{
32
	remove_lock_files(1);
33
	sigchain_pop(signo);
34 35 36
	raise(signo);
}

37
/*
38
 * path = absolute or relative path name
39
 *
40 41 42
 * Remove the last path name element from path (leaving the preceding
 * "/", if any).  If path is empty or the root directory ("/"), set
 * path to the empty string.
43
 */
44
static void trim_last_path_component(struct strbuf *path)
45
{
46
	int i = path->len;
47 48

	/* back up past trailing slashes, if any */
49 50
	while (i && path->buf[i - 1] == '/')
		i--;
51 52

	/*
53 54
	 * then go backwards until a slash, or the beginning of the
	 * string
55
	 */
56 57 58 59
	while (i && path->buf[i - 1] != '/')
		i--;

	strbuf_setlen(path, i);
60 61 62 63 64 65 66
}


/* We allow "recursive" symbolic links. Only within reason, though */
#define MAXDEPTH 5

/*
67
 * path contains a path that might be a symlink.
68
 *
69 70 71
 * If path is a symlink, attempt to overwrite it with a path to the
 * real file or directory (which may or may not exist), following a
 * chain of symlinks if necessary.  Otherwise, leave path unmodified.
72
 *
73 74 75
 * This is a best-effort routine.  If an error occurs, path will
 * either be left unmodified or will name a different symlink in a
 * symlink chain that started with the original path.
76
 */
77
static void resolve_symlink(struct strbuf *path)
78 79
{
	int depth = MAXDEPTH;
80
	static struct strbuf link = STRBUF_INIT;
81 82

	while (depth--) {
83
		if (strbuf_readlink(&link, path->buf, path->len) < 0)
84
			break;
85

86
		if (is_absolute_path(link.buf))
87
			/* absolute path simply replaces p */
88
			strbuf_reset(path);
89
		else
90
			/*
91
			 * link is a relative path, so replace the
92 93
			 * last element of p with it.
			 */
94
			trim_last_path_component(path);
95 96

		strbuf_addbuf(path, &link);
97
	}
98
	strbuf_reset(&link);
99 100
}

101
/* Make sure errno contains a meaningful value on error */
102
static int lock_file(struct lock_file *lk, const char *path, int flags)
103
{
104
	size_t pathlen = strlen(path);
105

106 107
	if (!lock_file_list) {
		/* One-time initialization */
108
		sigchain_push_common(remove_lock_files_on_signal);
109
		atexit(remove_lock_files_on_exit);
110 111
	}

112 113 114
	if (lk->active)
		die("BUG: cannot lock_file(\"%s\") using active struct lock_file",
		    path);
115 116 117
	if (!lk->on_list) {
		/* Initialize *lk and add it to lock_file_list: */
		lk->fd = -1;
118
		lk->fp = NULL;
119
		lk->active = 0;
120
		lk->owner = 0;
121
		strbuf_init(&lk->filename, pathlen + LOCK_SUFFIX_LEN);
122 123 124
		lk->next = lock_file_list;
		lock_file_list = lk;
		lk->on_list = 1;
125 126 127 128
	} else if (lk->filename.len) {
		/* This shouldn't happen, but better safe than sorry. */
		die("BUG: lock_file(\"%s\") called with improperly-reset lock_file object",
		    path);
129 130
	}

131 132 133 134 135 136 137 138 139 140 141
	if (flags & LOCK_NO_DEREF) {
		strbuf_add_absolute_path(&lk->filename, path);
	} else {
		struct strbuf resolved_path = STRBUF_INIT;

		strbuf_add(&resolved_path, path, pathlen);
		resolve_symlink(&resolved_path);
		strbuf_add_absolute_path(&lk->filename, resolved_path.buf);
		strbuf_release(&resolved_path);
	}

142 143
	strbuf_addstr(&lk->filename, LOCK_SUFFIX);
	lk->fd = open(lk->filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666);
144
	if (lk->fd < 0) {
145
		strbuf_reset(&lk->filename);
146
		return -1;
147
	}
148
	lk->owner = getpid();
149
	lk->active = 1;
150
	if (adjust_shared_perm(lk->filename.buf)) {
151
		int save_errno = errno;
152
		error("cannot fix permission bits on %s", lk->filename.buf);
153 154 155
		rollback_lock_file(lk);
		errno = save_errno;
		return -1;
156
	}
157
	return lk->fd;
158 159
}

160
void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
161
{
162
	if (err == EEXIST) {
163
		strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
164 165 166
		    "If no other git process is currently running, this probably means a\n"
		    "git process crashed in this repository earlier. Make sure no other git\n"
		    "process is running and remove the file manually to continue.",
167
			    absolute_path(path), strerror(err));
168
	} else
169
		strbuf_addf(buf, "Unable to create '%s.lock': %s",
170
			    absolute_path(path), strerror(err));
171 172
}

173
NORETURN void unable_to_lock_die(const char *path, int err)
174
{
175 176 177 178
	struct strbuf buf = STRBUF_INIT;

	unable_to_lock_message(path, err, &buf);
	die("%s", buf.buf);
179 180
}

181
/* This should return a meaningful errno on failure */
182
int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
183
{
184 185
	int fd = lock_file(lk, path, flags);
	if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
186
		unable_to_lock_die(path, errno);
187 188 189
	return fd;
}

190
int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
191 192 193
{
	int fd, orig_fd;

194
	fd = lock_file(lk, path, flags);
195
	if (fd < 0) {
196
		if (flags & LOCK_DIE_ON_ERROR)
197
			unable_to_lock_die(path, errno);
198 199 200 201 202 203
		return fd;
	}

	orig_fd = open(path, O_RDONLY);
	if (orig_fd < 0) {
		if (errno != ENOENT) {
204 205
			int save_errno = errno;

206
			if (flags & LOCK_DIE_ON_ERROR)
207
				die("cannot open '%s' for copying", path);
208
			rollback_lock_file(lk);
209 210 211
			error("cannot open '%s' for copying", path);
			errno = save_errno;
			return -1;
212 213
		}
	} else if (copy_fd(orig_fd, fd)) {
214 215
		int save_errno = errno;

216
		if (flags & LOCK_DIE_ON_ERROR)
217
			exit(128);
218
		close(orig_fd);
219
		rollback_lock_file(lk);
220
		errno = save_errno;
221
		return -1;
222 223
	} else {
		close(orig_fd);
224 225 226 227
	}
	return fd;
}

228 229 230 231 232 233 234 235 236 237 238
FILE *fdopen_lock_file(struct lock_file *lk, const char *mode)
{
	if (!lk->active)
		die("BUG: fdopen_lock_file() called for unlocked object");
	if (lk->fp)
		die("BUG: fdopen_lock_file() called twice for file '%s'", lk->filename.buf);

	lk->fp = fdopen(lk->fd, mode);
	return lk->fp;
}

239 240 241 242 243 244 245 246 247
char *get_locked_file_path(struct lock_file *lk)
{
	if (!lk->active)
		die("BUG: get_locked_file_path() called for unlocked object");
	if (lk->filename.len <= LOCK_SUFFIX_LEN)
		die("BUG: get_locked_file_path() called for malformed lock object");
	return xmemdupz(lk->filename.buf, lk->filename.len - LOCK_SUFFIX_LEN);
}

248 249 250
int close_lock_file(struct lock_file *lk)
{
	int fd = lk->fd;
251 252
	FILE *fp = lk->fp;
	int err;
253 254 255 256

	if (fd < 0)
		return 0;

257
	lk->fd = -1;
258 259 260 261 262 263 264 265 266 267 268 269 270
	if (fp) {
		lk->fp = NULL;

		/*
		 * Note: no short-circuiting here; we want to fclose()
		 * in any case!
		 */
		err = ferror(fp) | fclose(fp);
	} else {
		err = close(fd);
	}

	if (err) {
271 272 273 274 275
		int save_errno = errno;
		rollback_lock_file(lk);
		errno = save_errno;
		return -1;
	}
276

277
	return 0;
278 279
}

280 281 282 283
int reopen_lock_file(struct lock_file *lk)
{
	if (0 <= lk->fd)
		die(_("BUG: reopen a lockfile that is still open"));
284
	if (!lk->active)
285
		die(_("BUG: reopen a lockfile that has been committed"));
286
	lk->fd = open(lk->filename.buf, O_WRONLY);
287 288 289
	return lk->fd;
}

290
int commit_lock_file_to(struct lock_file *lk, const char *path)
291
{
292
	if (!lk->active)
293
		die("BUG: attempt to commit unlocked object to \"%s\"", path);
294

295
	if (close_lock_file(lk))
296
		return -1;
297

298
	if (rename(lk->filename.buf, path)) {
299 300 301
		int save_errno = errno;
		rollback_lock_file(lk);
		errno = save_errno;
302
		return -1;
303 304
	}

305
	lk->active = 0;
306
	strbuf_reset(&lk->filename);
307
	return 0;
308 309
}

310
int commit_lock_file(struct lock_file *lk)
311
{
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
	static struct strbuf result_file = STRBUF_INIT;
	int err;

	if (!lk->active)
		die("BUG: attempt to commit unlocked object");

	if (lk->filename.len <= LOCK_SUFFIX_LEN ||
	    strcmp(lk->filename.buf + lk->filename.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
		die("BUG: lockfile filename corrupt");

	/* remove ".lock": */
	strbuf_add(&result_file, lk->filename.buf,
		   lk->filename.len - LOCK_SUFFIX_LEN);
	err = commit_lock_file_to(lk, result_file.buf);
	strbuf_reset(&result_file);
	return err;
328 329
}

330 331
void rollback_lock_file(struct lock_file *lk)
{
332
	if (!lk->active)
333 334
		return;

335
	if (!close_lock_file(lk)) {
336
		unlink_or_warn(lk->filename.buf);
337
		lk->active = 0;
338
		strbuf_reset(&lk->filename);
339
	}
340
}