lockfile.con commit hold_lock_file_for_append(): release lock on errors (ebb8e38)
   1/*
   2 * Copyright (c) 2005, Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "sigchain.h"
   6
   7static struct lock_file *lock_file_list;
   8
   9static 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
  24static 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 */
  37static 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
  79static 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/* Make sure errno contains a meaningful value on error */
 124static 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                errno = ENAMETOOLONG;
 134                return -1;
 135        }
 136        strcpy(lk->filename, path);
 137        if (!(flags & LOCK_NODEREF))
 138                resolve_symlink(lk->filename, max_path_len);
 139        strcat(lk->filename, ".lock");
 140        lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
 141        if (0 <= lk->fd) {
 142                if (!lock_file_list) {
 143                        sigchain_push_common(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                        int save_errno = errno;
 154                        error("cannot fix permission bits on %s",
 155                              lk->filename);
 156                        rollback_lock_file(lk);
 157                        errno = save_errno;
 158                        return -1;
 159                }
 160        }
 161        else
 162                lk->filename[0] = 0;
 163        return lk->fd;
 164}
 165
 166void unable_to_lock_message(const char *path, int err, struct strbuf *buf)
 167{
 168        if (err == EEXIST) {
 169                strbuf_addf(buf, "Unable to create '%s.lock': %s.\n\n"
 170                    "If no other git process is currently running, this probably means a\n"
 171                    "git process crashed in this repository earlier. Make sure no other git\n"
 172                    "process is running and remove the file manually to continue.",
 173                            absolute_path(path), strerror(err));
 174        } else
 175                strbuf_addf(buf, "Unable to create '%s.lock': %s",
 176                            absolute_path(path), strerror(err));
 177}
 178
 179int unable_to_lock_error(const char *path, int err)
 180{
 181        struct strbuf buf = STRBUF_INIT;
 182
 183        unable_to_lock_message(path, err, &buf);
 184        error("%s", buf.buf);
 185        strbuf_release(&buf);
 186        return -1;
 187}
 188
 189NORETURN void unable_to_lock_die(const char *path, int err)
 190{
 191        struct strbuf buf = STRBUF_INIT;
 192
 193        unable_to_lock_message(path, err, &buf);
 194        die("%s", buf.buf);
 195}
 196
 197/* This should return a meaningful errno on failure */
 198int hold_lock_file_for_update(struct lock_file *lk, const char *path, int flags)
 199{
 200        int fd = lock_file(lk, path, flags);
 201        if (fd < 0 && (flags & LOCK_DIE_ON_ERROR))
 202                unable_to_lock_die(path, errno);
 203        return fd;
 204}
 205
 206int hold_lock_file_for_append(struct lock_file *lk, const char *path, int flags)
 207{
 208        int fd, orig_fd;
 209
 210        fd = lock_file(lk, path, flags);
 211        if (fd < 0) {
 212                if (flags & LOCK_DIE_ON_ERROR)
 213                        unable_to_lock_die(path, errno);
 214                return fd;
 215        }
 216
 217        orig_fd = open(path, O_RDONLY);
 218        if (orig_fd < 0) {
 219                if (errno != ENOENT) {
 220                        if (flags & LOCK_DIE_ON_ERROR)
 221                                die("cannot open '%s' for copying", path);
 222                        rollback_lock_file(lk);
 223                        return error("cannot open '%s' for copying", path);
 224                }
 225        } else if (copy_fd(orig_fd, fd)) {
 226                if (flags & LOCK_DIE_ON_ERROR)
 227                        exit(128);
 228                rollback_lock_file(lk);
 229                return -1;
 230        }
 231        return fd;
 232}
 233
 234int close_lock_file(struct lock_file *lk)
 235{
 236        int fd = lk->fd;
 237
 238        if (fd < 0)
 239                return 0;
 240
 241        lk->fd = -1;
 242        return close(fd);
 243}
 244
 245int reopen_lock_file(struct lock_file *lk)
 246{
 247        if (0 <= lk->fd)
 248                die(_("BUG: reopen a lockfile that is still open"));
 249        if (!lk->filename[0])
 250                die(_("BUG: reopen a lockfile that has been committed"));
 251        lk->fd = open(lk->filename, O_WRONLY);
 252        return lk->fd;
 253}
 254
 255int commit_lock_file(struct lock_file *lk)
 256{
 257        char result_file[PATH_MAX];
 258        size_t i;
 259        if (close_lock_file(lk))
 260                return -1;
 261        strcpy(result_file, lk->filename);
 262        i = strlen(result_file) - 5; /* .lock */
 263        result_file[i] = 0;
 264        if (rename(lk->filename, result_file))
 265                return -1;
 266        lk->filename[0] = 0;
 267        return 0;
 268}
 269
 270int hold_locked_index(struct lock_file *lk, int die_on_error)
 271{
 272        return hold_lock_file_for_update(lk, get_index_file(),
 273                                         die_on_error
 274                                         ? LOCK_DIE_ON_ERROR
 275                                         : 0);
 276}
 277
 278void rollback_lock_file(struct lock_file *lk)
 279{
 280        if (!lk->filename[0])
 281                return;
 282
 283        close_lock_file(lk);
 284        unlink_or_warn(lk->filename);
 285        lk->filename[0] = 0;
 286}