lockfile.con commit Use $Id$ as the ident attribute keyword rather than $ident$ to be consistent with other VCSs (af9b54b)
   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        sprintf(lk->filename, "%s.lock", path);
  32        fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
  33        if (0 <= fd) {
  34                lk->owner = getpid();
  35                if (!lk->on_list) {
  36                        lk->next = lock_file_list;
  37                        lock_file_list = lk;
  38                        lk->on_list = 1;
  39                }
  40                if (lock_file_list) {
  41                        signal(SIGINT, remove_lock_file_on_signal);
  42                        atexit(remove_lock_file);
  43                }
  44                if (adjust_shared_perm(lk->filename))
  45                        return error("cannot fix permission bits on %s",
  46                                     lk->filename);
  47        }
  48        else
  49                lk->filename[0] = 0;
  50        return fd;
  51}
  52
  53int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on_error)
  54{
  55        int fd = lock_file(lk, path);
  56        if (fd < 0 && die_on_error)
  57                die("unable to create '%s.lock': %s", path, strerror(errno));
  58        return fd;
  59}
  60
  61int commit_lock_file(struct lock_file *lk)
  62{
  63        char result_file[PATH_MAX];
  64        int i;
  65        strcpy(result_file, lk->filename);
  66        i = strlen(result_file) - 5; /* .lock */
  67        result_file[i] = 0;
  68        i = rename(lk->filename, result_file);
  69        lk->filename[0] = 0;
  70        return i;
  71}
  72
  73int hold_locked_index(struct lock_file *lk, int die_on_error)
  74{
  75        return hold_lock_file_for_update(lk, get_index_file(), die_on_error);
  76}
  77
  78void set_alternate_index_output(const char *name)
  79{
  80        alternate_index_output = name;
  81}
  82
  83int commit_locked_index(struct lock_file *lk)
  84{
  85        if (alternate_index_output) {
  86                int result = rename(lk->filename, alternate_index_output);
  87                lk->filename[0] = 0;
  88                return result;
  89        }
  90        else
  91                return commit_lock_file(lk);
  92}
  93
  94void rollback_lock_file(struct lock_file *lk)
  95{
  96        if (lk->filename[0])
  97                unlink(lk->filename);
  98        lk->filename[0] = 0;
  99}
 100