lockfile.con commit Update description of -z option. (654a7cc)
   1/*
   2 * Copyright (c) 2005, Junio C Hamano
   3 */
   4#include "cache.h"
   5
   6static struct lock_file *lock_file_list;
   7static const char *alternate_index_output;
   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                        unlink(lock_file_list->filename);
  17                lock_file_list = lock_file_list->next;
  18        }
  19}
  20
  21static void remove_lock_file_on_signal(int signo)
  22{
  23        remove_lock_file();
  24        signal(SIGINT, SIG_DFL);
  25        raise(signo);
  26}
  27
  28static int lock_file(struct lock_file *lk, const char *path)
  29{
  30        int fd;
  31        struct stat st;
  32
  33        if ((!lstat(path, &st)) && S_ISLNK(st.st_mode)) {
  34                ssize_t sz;
  35                static char target[PATH_MAX];
  36                sz = readlink(path, target, sizeof(target));
  37                if (sz < 0)
  38                        warning("Cannot readlink %s", path);
  39                else if (target[0] != '/')
  40                        warning("Cannot lock target of relative symlink %s", path);
  41                else
  42                        path = target;
  43        }
  44        sprintf(lk->filename, "%s.lock", path);
  45        fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
  46        if (0 <= fd) {
  47                if (!lock_file_list) {
  48                        signal(SIGINT, remove_lock_file_on_signal);
  49                        atexit(remove_lock_file);
  50                }
  51                lk->owner = getpid();
  52                if (!lk->on_list) {
  53                        lk->next = lock_file_list;
  54                        lock_file_list = lk;
  55                        lk->on_list = 1;
  56                }
  57                if (adjust_shared_perm(lk->filename))
  58                        return error("cannot fix permission bits on %s",
  59                                     lk->filename);
  60        }
  61        else
  62                lk->filename[0] = 0;
  63        return fd;
  64}
  65
  66int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on_error)
  67{
  68        int fd = lock_file(lk, path);
  69        if (fd < 0 && die_on_error)
  70                die("unable to create '%s.lock': %s", path, strerror(errno));
  71        return fd;
  72}
  73
  74int commit_lock_file(struct lock_file *lk)
  75{
  76        char result_file[PATH_MAX];
  77        int i;
  78        strcpy(result_file, lk->filename);
  79        i = strlen(result_file) - 5; /* .lock */
  80        result_file[i] = 0;
  81        i = rename(lk->filename, result_file);
  82        lk->filename[0] = 0;
  83        return i;
  84}
  85
  86int hold_locked_index(struct lock_file *lk, int die_on_error)
  87{
  88        return hold_lock_file_for_update(lk, get_index_file(), die_on_error);
  89}
  90
  91void set_alternate_index_output(const char *name)
  92{
  93        alternate_index_output = name;
  94}
  95
  96int commit_locked_index(struct lock_file *lk)
  97{
  98        if (alternate_index_output) {
  99                int result = rename(lk->filename, alternate_index_output);
 100                lk->filename[0] = 0;
 101                return result;
 102        }
 103        else
 104                return commit_lock_file(lk);
 105}
 106
 107void rollback_lock_file(struct lock_file *lk)
 108{
 109        if (lk->filename[0])
 110                unlink(lk->filename);
 111        lk->filename[0] = 0;
 112}