Code

Merge branch 'maint-1.6.0' into maint-1.6.1
[git.git] / lockfile.c
1 /*
2  * Copyright (c) 2005, Junio C Hamano
3  */
4 #include "cache.h"
6 static struct lock_file *lock_file_list;
7 static const char *alternate_index_output;
9 static void remove_lock_file(void)
10 {
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(lock_file_list->filename);
19                 }
20                 lock_file_list = lock_file_list->next;
21         }
22 }
24 static void remove_lock_file_on_signal(int signo)
25 {
26         remove_lock_file();
27         signal(signo, SIG_DFL);
28         raise(signo);
29 }
31 /*
32  * p = absolute or relative path name
33  *
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.
36  */
37 static char *last_path_elm(char *p)
38 {
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--;
51         /*
52          * then go backwards until I hit a slash, or the beginning of
53          * the string
54          */
55         while (r > p && *(r-1) != '/')
56                 r--;
57         return r;
58 }
61 /* We allow "recursive" symbolic links. Only within reason, though */
62 #define MAXDEPTH 5
64 /*
65  * p = path that may be a symlink
66  * s = full size of p
67  *
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.
71  *
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.
75  *
76  * Always returns p.
77  */
79 static char *resolve_symlink(char *p, size_t s)
80 {
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;
89                 }
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;
96                 }
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;
105                         }
106                 } else {
107                         /*
108                          * link is a relative path, so I must replace the
109                          * last element of p with it.
110                          */
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;
117                         }
118                 }
119         }
120         return p;
124 static int lock_file(struct lock_file *lk, const char *path, int flags)
126         if (strlen(path) >= sizeof(lk->filename))
127                 return -1;
128         strcpy(lk->filename, path);
129         /*
130          * subtract 5 from size to make sure there's room for adding
131          * ".lock" for the lock file name
132          */
133         if (!(flags & LOCK_NODEREF))
134                 resolve_symlink(lk->filename, sizeof(lk->filename)-5);
135         strcat(lk->filename, ".lock");
136         lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
137         if (0 <= lk->fd) {
138                 if (!lock_file_list) {
139                         signal(SIGINT, remove_lock_file_on_signal);
140                         signal(SIGHUP, remove_lock_file_on_signal);
141                         signal(SIGTERM, remove_lock_file_on_signal);
142                         signal(SIGQUIT, remove_lock_file_on_signal);
143                         signal(SIGPIPE, remove_lock_file_on_signal);
144                         atexit(remove_lock_file);
145                 }
146                 lk->owner = getpid();
147                 if (!lk->on_list) {
148                         lk->next = lock_file_list;
149                         lock_file_list = lk;
150                         lk->on_list = 1;
151                 }
152                 if (adjust_shared_perm(lk->filename))
153                         return error("cannot fix permission bits on %s",
154                                      lk->filename);
155         }
156         else
157                 lk->filename[0] = 0;
158         return lk->fd;
162 NORETURN void unable_to_lock_index_die(const char *path, int err)
164         if (errno == EEXIST) {
165                 die("Unable to create '%s.lock': %s.\n\n"
166                     "If no other git process is currently running, this probably means a\n"
167                     "git process crashed in this repository earlier. Make sure no other git\n"
168                     "process is running and remove the file manually to continue.",
169                     path, strerror(err));
170         } else {
171                 die("Unable to create '%s.lock': %s", path, strerror(err));
172         }
175 int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
177         int fd = lock_file(lk, path, flags);
178         if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
179                 unable_to_lock_index_die(path, errno);
180         return fd;
183 int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
185         int fd, orig_fd;
187         fd = lock_file(lk, path, flags);
188         if (fd < 0) {
189                 if (flags & LOCK_DIE_ON_ERROR)
190                         die("unable to create '%s.lock': %s", path, strerror(errno));
191                 return fd;
192         }
194         orig_fd = open(path, O_RDONLY);
195         if (orig_fd < 0) {
196                 if (errno != ENOENT) {
197                         if (flags & LOCK_DIE_ON_ERROR)
198                                 die("cannot open '%s' for copying", path);
199                         close(fd);
200                         return error("cannot open '%s' for copying", path);
201                 }
202         } else if (copy_fd(orig_fd, fd)) {
203                 if (flags & LOCK_DIE_ON_ERROR)
204                         exit(128);
205                 close(fd);
206                 return -1;
207         }
208         return fd;
211 int close_lock_file(struct lock_file *lk)
213         int fd = lk->fd;
214         lk->fd = -1;
215         return close(fd);
218 int commit_lock_file(struct lock_file *lk)
220         char result_file[PATH_MAX];
221         size_t i;
222         if (lk->fd >= 0 && close_lock_file(lk))
223                 return -1;
224         strcpy(result_file, lk->filename);
225         i = strlen(result_file) - 5; /* .lock */
226         result_file[i] = 0;
227         if (rename(lk->filename, result_file))
228                 return -1;
229         lk->filename[0] = 0;
230         return 0;
233 int hold_locked_index(struct lock_file *lk, int die_on_error)
235         return hold_lock_file_for_update(lk, get_index_file(),
236                                          die_on_error
237                                          ? LOCK_DIE_ON_ERROR
238                                          : 0);
241 void set_alternate_index_output(const char *name)
243         alternate_index_output = name;
246 int commit_locked_index(struct lock_file *lk)
248         if (alternate_index_output) {
249                 if (lk->fd >= 0 && close_lock_file(lk))
250                         return -1;
251                 if (rename(lk->filename, alternate_index_output))
252                         return -1;
253                 lk->filename[0] = 0;
254                 return 0;
255         }
256         else
257                 return commit_lock_file(lk);
260 void rollback_lock_file(struct lock_file *lk)
262         if (lk->filename[0]) {
263                 if (lk->fd >= 0)
264                         close(lk->fd);
265                 unlink(lk->filename);
266         }
267         lk->filename[0] = 0;