If a program locks a refs file (as git-ssh-pull -w now does for an
existing file), it should unlock it again if it exits without changing
it. Some trickiness is required to make this not happen in forks of the
process.

Signed-off-by: Daniel Barkalow <[EMAIL PROTECTED]>

---
commit 8934c88118c900fe38abbf60f893ee9ef4e83b3c
tree 62a74516551505e5fd2b5c2fd14486f3ac8a400e
parent 2045e6098dfa0f8760b6a4a65227a6ea51de990d
author Daniel Barkalow <[EMAIL PROTECTED]> 1120507109 -0400
committer Daniel Barkalow <[EMAIL PROTECTED](none)> 1120507109 -0400

Index: refs.c
===================================================================
--- 3d3e671c0ac57ea66434768c2b3432352b7c20ae/refs.c  (mode:100644 
sha1:447080edde385a470a815944c2f002c1e51699a5)
+++ 62a74516551505e5fd2b5c2fd14486f3ac8a400e/refs.c  (mode:100644 
sha1:6e75e82665f5c8e3e155579228c5104c16318239)
@@ -2,6 +2,14 @@
 #include "cache.h"
 
 #include <errno.h>
+#include <signal.h>
+
+#define MAX_LOCKS 10
+
+static int setup = 0;
+
+static int num_locks = 0;
+static char *locknames[MAX_LOCKS];
 
 static int read_ref(const char *path, unsigned char *sha1)
 {
@@ -88,6 +96,22 @@
        return ret;
 }
 
+static void remove_lock_files(void)
+{
+       int i;
+       if (getpid() != setup)
+               return;
+       for (i = 0; i < num_locks; i++) {
+               unlink(locknames[i]);
+       }
+       num_locks = 0;
+}
+
+static void remove_lock_files_on_signal(int signo) 
+{
+       remove_lock_files();
+}
+
 static int read_ref_file(const char *filename, unsigned char *sha1) {
        int fd = open(filename, O_RDONLY);
        char hex[41];
@@ -120,9 +144,12 @@
 static int lock_ref_file(const char *filename, const char *lock_filename,
                         const unsigned char *old_sha1)
 {
-       int fd = open(lock_filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
+       int fd;
        unsigned char current_sha1[20];
        int retval;
+       if (num_locks >= MAX_LOCKS)
+               return error("Too many locks in refs.c");
+       fd = open(lock_filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
        if (fd < 0) {
                return error("Couldn't open lock file for %s: %s",
                             filename, strerror(errno));
@@ -151,6 +178,12 @@
                                     sha1_to_hex(current_sha1), filename);
                }
        }
+       if (!setup) {
+               signal(SIGINT, remove_lock_files_on_signal);
+               atexit(remove_lock_files);
+               setup = getpid();
+       }
+       locknames[num_locks++] = strdup(lock_filename);
        return fd;
 }
 
@@ -175,6 +208,7 @@
 {
        char *hex = sha1_to_hex(sha1);
        char term = '\n';
+       int i;
        if (write(fd, hex, 40) < 40 ||
            write(fd, &term, 1) < 1) {
                error("Couldn't write %s\n", filename);
@@ -182,7 +216,14 @@
                return -1;
        }
        close(fd);
-       rename(lock_filename, filename);
+       if (rename(lock_filename, filename))
+               return error("Couldn't update %s", filename);
+       for (i = 0; i < num_locks; i++) {
+               if (!strcmp(lock_filename, locknames[i])) {
+                       locknames[i] = locknames[--num_locks];
+                       break;
+               }
+       }
        return 0;
 }
 

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to