summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Barkalow <barkalow@iabervon.org>2008-04-17 19:32:26 -0400
committerJunio C Hamano <gitster@pobox.com>2008-05-04 17:41:44 -0700
commitea3cd5c7c63fadacd66c364ae4b8c6d01e5809b1 (patch)
treeee93cdbc2c39dc0b976440418249e9a6e2d37156
parent2d5c298f91b4b76a8b51b9b66283ef5a872736a0 (diff)
downloadgit-ea3cd5c7c63fadacd66c364ae4b8c6d01e5809b1.tar.gz
Add a lockfile function to append to a file
This takes care of copying the original contents into the replacement file after the lock is held, so that concurrent additions can't miss each other's changes. [jc: munged to drop mmap in favor of copy_file.] Signed-off-by: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--cache.h1
-rw-r--r--lockfile.c28
2 files changed, 29 insertions, 0 deletions
diff --git a/cache.h b/cache.h
index 5a28dddec9..396eabf6ed 100644
--- a/cache.h
+++ b/cache.h
@@ -391,6 +391,7 @@ struct lock_file {
char filename[PATH_MAX];
};
extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
+extern int hold_lock_file_for_append(struct lock_file *, const char *path, int);
extern int commit_lock_file(struct lock_file *);
extern int hold_locked_index(struct lock_file *, int);
diff --git a/lockfile.c b/lockfile.c
index 663f18f9c4..e9e0095e9f 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -160,6 +160,34 @@ int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on
return fd;
}
+int hold_lock_file_for_append(struct lock_file *lk, const char *path, int die_on_error)
+{
+ int fd, orig_fd;
+
+ fd = lock_file(lk, path);
+ if (fd < 0) {
+ if (die_on_error)
+ die("unable to create '%s.lock': %s", path, strerror(errno));
+ return fd;
+ }
+
+ orig_fd = open(path, O_RDONLY);
+ if (orig_fd < 0) {
+ if (errno != ENOENT) {
+ if (die_on_error)
+ die("cannot open '%s' for copying", path);
+ close(fd);
+ return error("cannot open '%s' for copying", path);
+ }
+ } else if (copy_fd(orig_fd, fd)) {
+ if (die_on_error)
+ exit(128);
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
int close_lock_file(struct lock_file *lk)
{
int fd = lk->fd;