change hard-coded perl path to variable
[platform/upstream/git.git] / lockfile.c
1 /*
2  * Copyright (c) 2005, Junio C Hamano
3  */
4 #include "cache.h"
5 #include "sigchain.h"
6
7 static struct lock_file *lock_file_list;
8 static const char *alternate_index_output;
9
10 static void remove_lock_file(void)
11 {
12         pid_t me = getpid();
13
14         while (lock_file_list) {
15                 if (lock_file_list->owner == me &&
16                     lock_file_list->filename[0]) {
17                         if (lock_file_list->fd >= 0)
18                                 close(lock_file_list->fd);
19                         unlink_or_warn(lock_file_list->filename);
20                 }
21                 lock_file_list = lock_file_list->next;
22         }
23 }
24
25 static void remove_lock_file_on_signal(int signo)
26 {
27         remove_lock_file();
28         sigchain_pop(signo);
29         raise(signo);
30 }
31
32 /*
33  * p = absolute or relative path name
34  *
35  * Return a pointer into p showing the beginning of the last path name
36  * element.  If p is empty or the root directory ("/"), just return p.
37  */
38 static char *last_path_elm(char *p)
39 {
40         /* r starts pointing to null at the end of the string */
41         char *r = strchr(p, '\0');
42
43         if (r == p)
44                 return p; /* just return empty string */
45
46         r--; /* back up to last non-null character */
47
48         /* back up past trailing slashes, if any */
49         while (r > p && *r == '/')
50                 r--;
51
52         /*
53          * then go backwards until I hit a slash, or the beginning of
54          * the string
55          */
56         while (r > p && *(r-1) != '/')
57                 r--;
58         return r;
59 }
60
61
62 /* We allow "recursive" symbolic links. Only within reason, though */
63 #define MAXDEPTH 5
64
65 /*
66  * p = path that may be a symlink
67  * s = full size of p
68  *
69  * If p is a symlink, attempt to overwrite p with a path to the real
70  * file or directory (which may or may not exist), following a chain of
71  * symlinks if necessary.  Otherwise, leave p unmodified.
72  *
73  * This is a best-effort routine.  If an error occurs, p will either be
74  * left unmodified or will name a different symlink in a symlink chain
75  * that started with p's initial contents.
76  *
77  * Always returns p.
78  */
79
80 static char *resolve_symlink(char *p, size_t s)
81 {
82         int depth = MAXDEPTH;
83
84         while (depth--) {
85                 char link[PATH_MAX];
86                 int link_len = readlink(p, link, sizeof(link));
87                 if (link_len < 0) {
88                         /* not a symlink anymore */
89                         return p;
90                 }
91                 else if (link_len < sizeof(link))
92                         /* readlink() never null-terminates */
93                         link[link_len] = '\0';
94                 else {
95                         warning("%s: symlink too long", p);
96                         return p;
97                 }
98
99                 if (is_absolute_path(link)) {
100                         /* absolute path simply replaces p */
101                         if (link_len < s)
102                                 strcpy(p, link);
103                         else {
104                                 warning("%s: symlink too long", p);
105                                 return p;
106                         }
107                 } else {
108                         /*
109                          * link is a relative path, so I must replace the
110                          * last element of p with it.
111                          */
112                         char *r = (char *)last_path_elm(p);
113                         if (r - p + link_len < s)
114                                 strcpy(r, link);
115                         else {
116                                 warning("%s: symlink too long", p);
117                                 return p;
118                         }
119                 }
120         }
121         return p;
122 }
123
124
125 static int lock_file(struct lock_file *lk, const char *path, int flags)
126 {
127         /*
128          * subtract 5 from size to make sure there's room for adding
129          * ".lock" for the lock file name
130          */
131         static const size_t max_path_len = sizeof(lk->filename) - 5;
132
133         if (strlen(path) >= max_path_len)
134                 return -1;
135         strcpy(lk->filename, path);
136         if (!(flags & LOCK_NODEREF))
137                 resolve_symlink(lk->filename, max_path_len);
138         strcat(lk->filename, ".lock");
139         lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
140         if (0 <= lk->fd) {
141                 if (!lock_file_list) {
142                         sigchain_push_common(remove_lock_file_on_signal);
143                         atexit(remove_lock_file);
144                 }
145                 lk->owner = getpid();
146                 if (!lk->on_list) {
147                         lk->next = lock_file_list;
148                         lock_file_list = lk;
149                         lk->on_list = 1;
150                 }
151                 if (adjust_shared_perm(lk->filename))
152                         return error("cannot fix permission bits on %s",
153                                      lk->filename);
154         }
155         else
156                 lk->filename[0] = 0;
157         return lk->fd;
158 }
159
160 static char *unable_to_lock_message(const char *path, int err)
161 {
162         struct strbuf buf = STRBUF_INIT;
163
164         if (err == EEXIST) {
165                 strbuf_addf(&buf, "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                             absolute_path(path), strerror(err));
170         } else
171                 strbuf_addf(&buf, "Unable to create '%s.lock': %s",
172                             absolute_path(path), strerror(err));
173         return strbuf_detach(&buf, NULL);
174 }
175
176 int unable_to_lock_error(const char *path, int err)
177 {
178         char *msg = unable_to_lock_message(path, err);
179         error("%s", msg);
180         free(msg);
181         return -1;
182 }
183
184 NORETURN void unable_to_lock_index_die(const char *path, int err)
185 {
186         die("%s", unable_to_lock_message(path, err));
187 }
188
189 int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
190 {
191         int fd = lock_file(lk, path, flags);
192         if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
193                 unable_to_lock_index_die(path, errno);
194         return fd;
195 }
196
197 int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
198 {
199         int fd, orig_fd;
200
201         fd = lock_file(lk, path, flags);
202         if (fd < 0) {
203                 if (flags & LOCK_DIE_ON_ERROR)
204                         unable_to_lock_index_die(path, errno);
205                 return fd;
206         }
207
208         orig_fd = open(path, O_RDONLY);
209         if (orig_fd < 0) {
210                 if (errno != ENOENT) {
211                         if (flags & LOCK_DIE_ON_ERROR)
212                                 die("cannot open '%s' for copying", path);
213                         close(fd);
214                         return error("cannot open '%s' for copying", path);
215                 }
216         } else if (copy_fd(orig_fd, fd)) {
217                 if (flags & LOCK_DIE_ON_ERROR)
218                         exit(128);
219                 close(fd);
220                 return -1;
221         }
222         return fd;
223 }
224
225 int close_lock_file(struct lock_file *lk)
226 {
227         int fd = lk->fd;
228         lk->fd = -1;
229         return close(fd);
230 }
231
232 int commit_lock_file(struct lock_file *lk)
233 {
234         char result_file[PATH_MAX];
235         size_t i;
236         if (lk->fd >= 0 && close_lock_file(lk))
237                 return -1;
238         strcpy(result_file, lk->filename);
239         i = strlen(result_file) - 5; /* .lock */
240         result_file[i] = 0;
241         if (rename(lk->filename, result_file))
242                 return -1;
243         lk->filename[0] = 0;
244         return 0;
245 }
246
247 int hold_locked_index(struct lock_file *lk, int die_on_error)
248 {
249         return hold_lock_file_for_update(lk, get_index_file(),
250                                          die_on_error
251                                          ? LOCK_DIE_ON_ERROR
252                                          : 0);
253 }
254
255 void set_alternate_index_output(const char *name)
256 {
257         alternate_index_output = name;
258 }
259
260 int commit_locked_index(struct lock_file *lk)
261 {
262         if (alternate_index_output) {
263                 if (lk->fd >= 0 && close_lock_file(lk))
264                         return -1;
265                 if (rename(lk->filename, alternate_index_output))
266                         return -1;
267                 lk->filename[0] = 0;
268                 return 0;
269         }
270         else
271                 return commit_lock_file(lk);
272 }
273
274 void rollback_lock_file(struct lock_file *lk)
275 {
276         if (lk->filename[0]) {
277                 if (lk->fd >= 0)
278                         close(lk->fd);
279                 unlink_or_warn(lk->filename);
280         }
281         lk->filename[0] = 0;
282 }