lockfile.con commit index-format.txt: add a missing closing quote (f2667a8)
   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
 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                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
 159static 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
 175int 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
 183NORETURN void unable_to_lock_index_die(const char *path, int err)
 184{
 185        die("%s", unable_to_lock_message(path, err));
 186}
 187
 188int 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
 196int 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
 224int close_lock_file(struct lock_file *lk)
 225{
 226        int fd = lk->fd;
 227        lk->fd = -1;
 228        return close(fd);
 229}
 230
 231int 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
 246int 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
 254void 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}