lockfile.c 7.7 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
	strbuf_add(&lk->filename, path, pathlen);
132
	if (!(flags & LOCK_NO_DEREF))
133
		resolve_symlink(&lk->filename);
134 135
	strbuf_addstr(&lk->filename, LOCK_SUFFIX);
	lk->fd = open(lk->filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666);
136
	if (lk->fd < 0) {
137
		strbuf_reset(&lk->filename);
138
		return -1;
139
	}
140
	lk->owner = getpid();
141
	lk->active = 1;
142
	if (adjust_shared_perm(lk->filename.buf)) {
143
		int save_errno = errno;
144
		error("cannot fix permission bits on %s", lk->filename.buf);
145 146 147
		rollback_lock_file(lk);
		errno = save_errno;
		return -1;
148
	}
149
	return lk->fd;
150 151
}

152
void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
153
{
154
	if (err == EEXIST) {
155
		strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
156 157 158
		    "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.",
159
			    absolute_path(path), strerror(err));
160
	} else
161
		strbuf_addf(buf, "Unable to create '%s.lock': %s",
162
			    absolute_path(path), strerror(err));
163 164
}

165
NORETURN void unable_to_lock_die(const char *path, int err)
166
{
167 168 169 170
	struct strbuf buf = STRBUF_INIT;

	unable_to_lock_message(path, err, &buf);
	die("%s", buf.buf);
171 172
}

173
/* This should return a meaningful errno on failure */
174
int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
175
{
176 177
	int fd = lock_file(lk, path, flags);
	if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
178
		unable_to_lock_die(path, errno);
179 180 181
	return fd;
}

182
int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
183 184 185
{
	int fd, orig_fd;

186
	fd = lock_file(lk, path, flags);
187
	if (fd < 0) {
188
		if (flags & LOCK_DIE_ON_ERROR)
189
			unable_to_lock_die(path, errno);
190 191 192 193 194 195
		return fd;
	}

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

198
			if (flags & LOCK_DIE_ON_ERROR)
199
				die("cannot open '%s' for copying", path);
200
			rollback_lock_file(lk);
201 202 203
			error("cannot open '%s' for copying", path);
			errno = save_errno;
			return -1;
204 205
		}
	} else if (copy_fd(orig_fd, fd)) {
206 207
		int save_errno = errno;

208
		if (flags & LOCK_DIE_ON_ERROR)
209
			exit(128);
210
		close(orig_fd);
211
		rollback_lock_file(lk);
212
		errno = save_errno;
213
		return -1;
214 215
	} else {
		close(orig_fd);
216 217 218 219
	}
	return fd;
}

220 221 222 223 224 225 226 227 228 229 230
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;
}

231 232 233 234 235 236 237 238 239
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);
}

240 241 242
int close_lock_file(struct lock_file *lk)
{
	int fd = lk->fd;
243 244
	FILE *fp = lk->fp;
	int err;
245 246 247 248

	if (fd < 0)
		return 0;

249
	lk->fd = -1;
250 251 252 253 254 255 256 257 258 259 260 261 262
	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) {
263 264 265 266 267
		int save_errno = errno;
		rollback_lock_file(lk);
		errno = save_errno;
		return -1;
	}
268

269
	return 0;
270 271
}

272 273 274 275
int reopen_lock_file(struct lock_file *lk)
{
	if (0 <= lk->fd)
		die(_("BUG: reopen a lockfile that is still open"));
276
	if (!lk->active)
277
		die(_("BUG: reopen a lockfile that has been committed"));
278
	lk->fd = open(lk->filename.buf, O_WRONLY);
279 280 281
	return lk->fd;
}

282
int commit_lock_file_to(struct lock_file *lk, const char *path)
283
{
284
	if (!lk->active)
285
		die("BUG: attempt to commit unlocked object to \"%s\"", path);
286

287
	if (close_lock_file(lk))
288
		return -1;
289

290
	if (rename(lk->filename.buf, path)) {
291 292 293
		int save_errno = errno;
		rollback_lock_file(lk);
		errno = save_errno;
294
		return -1;
295 296
	}

297
	lk->active = 0;
298
	strbuf_reset(&lk->filename);
299
	return 0;
300 301
}

302
int commit_lock_file(struct lock_file *lk)
303
{
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
	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;
320 321
}

322 323
void rollback_lock_file(struct lock_file *lk)
{
324
	if (!lk->active)
325 326
		return;

327
	if (!close_lock_file(lk)) {
328
		unlink_or_warn(lk->filename.buf);
329
		lk->active = 0;
330
		strbuf_reset(&lk->filename);
331
	}
332
}