Implement first draft of DNS-SD support in git-daemon
[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
9 static void remove_lock_file(void)
10 {
11         pid_t me = getpid();
12
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);
19                 }
20                 lock_file_list = lock_file_list->next;
21         }
22 }
23
24 static void remove_lock_file_on_signal(int signo)
25 {
26         remove_lock_file();
27         sigchain_pop(signo);
28         raise(signo);
29 }
30
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');
41
42         if (r == p)
43                 return p; /* just return empty string */
44
45         r--; /* back up to last non-null character */
46
47         /* back up past trailing slashes, if any */
48         while (r > p && *r == '/')
49                 r--;
50
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 }
59
60
61 /* We allow "recursive" symbolic links. Only within reason, though */
62 #define MAXDEPTH 5
63
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  */
78
79 static char *resolve_symlink(char *p, size_t s)
80 {
81         int depth = MAXDEPTH;
82
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                 }
97
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;
121 }
122
123
124 static int lock_file(struct lock_file *lk, const char *path, int flags)
125 {
126         /*
127          * subtract 5 from size to make sure there's room for adding
128          * ".lock" for the lock file name
129          */
130         static const size_t max_path_len = sizeof(lk->filename) - 5;
131
132         if (strlen(path) >= max_path_len)
133                 return -1;
134         strcpy(lk->filename, path);
135         if (!(flags & LOCK_NODEREF))
136                 resolve_symlink(lk->filename, max_path_len);
137         strcat(lk->filename, ".lock");
138         lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
139         if (0 <= lk->fd) {
140                 if (!lock_file_list) {
141                         sigchain_push_common(remove_lock_file_on_signal);
142                         atexit(remove_lock_file);
143                 }
144                 lk->owner = getpid();
145                 if (!lk->on_list) {
146                         lk->next = lock_file_list;
147                         lock_file_list = lk;
148                         lk->on_list = 1;
149                 }
150                 if (adjust_shared_perm(lk->filename))
151                         return error("cannot fix permission bits on %s",
152                                      lk->filename);
153         }
154         else
155                 lk->filename[0] = 0;
156         return lk->fd;
157 }
158
159 static char *unable_to_lock_message(const char *path, int err)
160 {
161         struct strbuf buf = STRBUF_INIT;
162
163         if (err == EEXIST) {
164                 strbuf_addf(&buf, "Unable to create '%s.lock': %s.\n\n"
165                     "If no other git process is currently running, this probably means a\n"
166                     "git process crashed in this repository earlier. Make sure no other git\n"
167                     "process is running and remove the file manually to continue.",
168                             absolute_path(path), strerror(err));
169         } else
170                 strbuf_addf(&buf, "Unable to create '%s.lock': %s",
171                             absolute_path(path), strerror(err));
172         return strbuf_detach(&buf, NULL);
173 }
174
175 int unable_to_lock_error(const char *path, int err)
176 {
177         char *msg = unable_to_lock_message(path, err);
178         error("%s", msg);
179         free(msg);
180         return -1;
181 }
182
183 NORETURN void unable_to_lock_index_die(const char *path, int err)
184 {
185         die("%s", unable_to_lock_message(path, err));
186 }
187
188 int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
189 {
190         int fd = lock_file(lk, path, flags);
191         if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
192                 unable_to_lock_index_die(path, errno);
193         return fd;
194 }
195
196 int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
197 {
198         int fd, orig_fd;
199
200         fd = lock_file(lk, path, flags);
201         if (fd < 0) {
202                 if (flags & LOCK_DIE_ON_ERROR)
203                         unable_to_lock_index_die(path, errno);
204                 return fd;
205         }
206
207         orig_fd = open(path, O_RDONLY);
208         if (orig_fd < 0) {
209                 if (errno != ENOENT) {
210                         if (flags & LOCK_DIE_ON_ERROR)
211                                 die("cannot open '%s' for copying", path);
212                         close(fd);
213                         return error("cannot open '%s' for copying", path);
214                 }
215         } else if (copy_fd(orig_fd, fd)) {
216                 if (flags & LOCK_DIE_ON_ERROR)
217                         exit(128);
218                 close(fd);
219                 return -1;
220         }
221         return fd;
222 }
223
224 int close_lock_file(struct lock_file *lk)
225 {
226         int fd = lk->fd;
227         lk->fd = -1;
228         return close(fd);
229 }
230
231 int commit_lock_file(struct lock_file *lk)
232 {
233         char result_file[PATH_MAX];
234         size_t i;
235         if (lk->fd >= 0 && close_lock_file(lk))
236                 return -1;
237         strcpy(result_file, lk->filename);
238         i = strlen(result_file) - 5; /* .lock */
239         result_file[i] = 0;
240         if (rename(lk->filename, result_file))
241                 return -1;
242         lk->filename[0] = 0;
243         return 0;
244 }
245
246 int hold_locked_index(struct lock_file *lk, int die_on_error)
247 {
248         return hold_lock_file_for_update(lk, get_index_file(),
249                                          die_on_error
250                                          ? LOCK_DIE_ON_ERROR
251                                          : 0);
252 }
253
254 void rollback_lock_file(struct lock_file *lk)
255 {
256         if (lk->filename[0]) {
257                 if (lk->fd >= 0)
258                         close(lk->fd);
259                 unlink_or_warn(lk->filename);
260         }
261         lk->filename[0] = 0;
262 }