From: Brandon Casey <casey@nrlssc.navy.mil>
To: Git Mailing List <git@vger.kernel.org>,
Junio C Hamano <gitster@pobox.com>
Subject: [PATCH] Improve use of lockfile API
Date: Wed, 16 Jan 2008 13:12:46 -0600 [thread overview]
Message-ID: <478E572E.3020505@nrlssc.navy.mil> (raw)
-Remove remaining double close(2)'s.
i.e. close() before commit_locked_index() or commit_lock_file()
-New close_lock_file() function which will close() the lock descriptor and
assign -1 to it, but will not remove or rename it.
-commit_lock_file() was modified to detect and return -1 on failure
to close the lock file.
---
There are two places where we fdopen() the lock file descriptor.
In builtin-pack-refs.c and fast-import.c.
Presently, I assigned -1 to the lock->fd and added a comment.
Additionally in bundle.c we must assign -1 to the lock->fd
since it is closed by start_command().
We could do something along the lines of:
FILE* fdopen_lock_file(struct lock_file *lk)
{
FILE* f;
if ((f = fdopen(lk->fd)) == NULL)
return NULL;
lk->fd = -1;
return f;
}
But that may be overkill.
I'll think we'll probably catch this case since we are now
checking that the close() succeeds in commit_lock_file().
-brandon
builtin-add.c | 2 +-
builtin-apply.c | 2 +-
builtin-checkout-index.c | 4 ++--
builtin-commit.c | 9 ++++++---
builtin-diff.c | 2 +-
builtin-fetch-pack.c | 1 -
builtin-mv.c | 1 -
builtin-pack-refs.c | 4 ++++
builtin-read-tree.c | 2 +-
builtin-rerere.c | 4 ++--
builtin-reset.c | 1 -
builtin-revert.c | 4 ++--
builtin-rm.c | 2 +-
builtin-update-index.c | 2 +-
builtin-write-tree.c | 9 +++------
bundle.c | 12 ++++++++----
cache.h | 1 +
config.c | 8 ++------
fast-import.c | 10 ++++++++--
lockfile.c | 17 ++++++++++++++---
merge-recursive.c | 2 +-
refs.c | 12 ++++--------
22 files changed, 63 insertions(+), 48 deletions(-)
diff --git a/builtin-add.c b/builtin-add.c
index 5c29cc2..4a91e3e 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -259,7 +259,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
finish:
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_locked_index(&lock_file))
+ commit_locked_index(&lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-apply.c b/builtin-apply.c
index d57bb6e..15432b6 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2921,7 +2921,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
if (update_index) {
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_locked_index(&lock_file))
+ commit_locked_index(&lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index 70d619d..7e42024 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -246,8 +246,8 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
* want to update cache.
*/
if (state.refresh_cache) {
- close(newfd); newfd = -1;
rollback_lock_file(&lock_file);
+ newfd = -1;
}
state.refresh_cache = 0;
}
@@ -297,7 +297,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
if (0 <= newfd &&
(write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_locked_index(&lock_file)))
+ commit_locked_index(&lock_file)))
die("Unable to write new index file");
return 0;
}
diff --git a/builtin-commit.c b/builtin-commit.c
index 16345e9..a764053 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -237,7 +237,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
int fd = hold_locked_index(&index_lock, 1);
add_files_to_cache(0, also ? prefix : NULL, pathspec);
refresh_cache(REFRESH_QUIET);
- if (write_cache(fd, active_cache, active_nr))
+ if (write_cache(fd, active_cache, active_nr) ||
+ close_lock_file(&index_lock))
die("unable to write new_index file");
commit_style = COMMIT_NORMAL;
return index_lock.filename;
@@ -298,7 +299,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
fd = hold_locked_index(&index_lock, 1);
add_remove_files(&partial);
refresh_cache(REFRESH_QUIET);
- if (write_cache(fd, active_cache, active_nr))
+ if (write_cache(fd, active_cache, active_nr) ||
+ close_lock_file(&index_lock))
die("unable to write new_index file");
fd = hold_lock_file_for_update(&false_lock,
@@ -308,7 +310,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
add_remove_files(&partial);
refresh_cache(REFRESH_QUIET);
- if (write_cache(fd, active_cache, active_nr))
+ if (write_cache(fd, active_cache, active_nr) ||
+ close_lock_file(&false_lock))
die("unable to write temporary index file");
return false_lock.filename;
}
diff --git a/builtin-diff.c b/builtin-diff.c
index 29365a0..8d7a569 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -190,7 +190,7 @@ static void refresh_index_quietly(void)
refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED);
if (active_cache_changed &&
- !write_cache(fd, active_cache, active_nr) && !close(fd))
+ !write_cache(fd, active_cache, active_nr))
commit_locked_index(lock_file);
rollback_lock_file(lock_file);
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index 807fa93..e68e015 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -783,7 +783,6 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,
unlink(shallow);
rollback_lock_file(&lock);
} else {
- close(fd);
commit_lock_file(&lock);
}
}
diff --git a/builtin-mv.c b/builtin-mv.c
index a3f9ad1..990e213 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -264,7 +264,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) ||
commit_locked_index(&lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c
index 1923fb1..fbe451f 100644
--- a/builtin-pack-refs.c
+++ b/builtin-pack-refs.c
@@ -108,6 +108,10 @@ static int pack_refs(unsigned int flags)
die("failed to write ref-pack file");
if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
die("failed to write ref-pack file (%s)", strerror(errno));
+ /* Since the lock file was fdopen()'ed and then fclose()'ed above,
+ * assign -1 to the lock file descriptor so that commit_lock_file()
+ * won't try to close() it. */
+ packed.fd = -1;
if (commit_lock_file(&packed) < 0)
die("unable to overwrite old ref-pack file (%s)", strerror(errno));
if (cbdata.flags & PACK_REFS_PRUNE)
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 43cd56a..c0ea034 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -283,7 +283,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
}
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_locked_index(&lock_file))
+ commit_locked_index(&lock_file))
die("unable to write new index file");
return 0;
}
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 37e6248..a9e3ebc 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -61,9 +61,9 @@ static int write_rr(struct path_list *rr, int out_fd)
write_in_full(out_fd, path, length) != length)
die("unable to write rerere record");
}
- if (close(out_fd) != 0)
+ if (commit_lock_file(&write_lock) != 0)
die("unable to write rerere record");
- return commit_lock_file(&write_lock);
+ return 0;
}
static int handle_file(const char *path,
diff --git a/builtin-reset.c b/builtin-reset.c
index 10dba60..7ee811f 100644
--- a/builtin-reset.c
+++ b/builtin-reset.c
@@ -108,7 +108,6 @@ static int update_index_refresh(int fd, struct lock_file *index_lock)
return error("Could not read index");
result = refresh_cache(0) ? 1 : 0;
if (write_cache(fd, active_cache, active_nr) ||
- close(fd) ||
commit_locked_index(index_lock))
return error ("Could not refresh index");
return result;
diff --git a/builtin-revert.c b/builtin-revert.c
index 4bf8eb2..358af53 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -371,13 +371,13 @@ static int revert_or_cherry_pick(int argc, const char **argv)
i++;
}
}
- if (close(msg_fd) || commit_lock_file(&msg_file) < 0)
+ if (commit_lock_file(&msg_file) < 0)
die ("Error wrapping up %s", defmsg);
fprintf(stderr, "Automatic %s failed.%s\n",
me, help_msg(commit->object.sha1));
exit(1);
}
- if (close(msg_fd) || commit_lock_file(&msg_file) < 0)
+ if (commit_lock_file(&msg_file) < 0)
die ("Error wrapping up %s", defmsg);
fprintf(stderr, "Finished one %s.\n", me);
diff --git a/builtin-rm.c b/builtin-rm.c
index a3d25e6..c0a8bb6 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -250,7 +250,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_locked_index(&lock_file))
+ commit_locked_index(&lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-update-index.c b/builtin-update-index.c
index e1a938d..c3a14c7 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -738,7 +738,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
get_index_file(), strerror(lock_error));
}
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_locked_index(lock_file))
+ commit_locked_index(lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index b89d02e..d16b9ed 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -35,11 +35,9 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
missing_ok, 0) < 0)
die("git-write-tree: error building trees");
if (0 <= newfd) {
- if (!write_cache(newfd, active_cache, active_nr)
- && !close(newfd)) {
- commit_lock_file(lock_file);
+ if (!write_cache(newfd, active_cache, active_nr) &&
+ !commit_lock_file(lock_file))
newfd = -1;
- }
}
/* Not being able to write is fine -- we are only interested
* in updating the cache-tree part, and if the next caller
@@ -60,8 +58,7 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
hashcpy(sha1, active_cache_tree->sha1);
if (0 <= newfd)
- close(newfd);
- rollback_lock_file(lock_file);
+ rollback_lock_file(lock_file);
return 0;
}
diff --git a/bundle.c b/bundle.c
index 316aa74..61f388a 100644
--- a/bundle.c
+++ b/bundle.c
@@ -317,6 +317,12 @@ int create_bundle(struct bundle_header *header, const char *path,
rls.git_cmd = 1;
if (start_command(&rls))
return error("Could not spawn pack-objects");
+
+ /* start_command closed bundle_fd if it was > 1
+ * so set the lock fd to -1 so commit_lock_file()
+ * won't fail trying to close it */
+ lock.fd = -1;
+
for (i = 0; i < revs.pending.nr; i++) {
struct object *object = revs.pending.objects[i].item;
if (object->flags & UNINTERESTING)
@@ -326,10 +332,8 @@ int create_bundle(struct bundle_header *header, const char *path,
}
if (finish_command(&rls))
return error ("pack-objects died");
- close(bundle_fd);
- if (!bundle_to_stdout)
- commit_lock_file(&lock);
- return 0;
+
+ return bundle_to_stdout ? close(bundle_fd) : commit_lock_file(&lock);
}
int unbundle(struct bundle_header *header, int bundle_fd)
diff --git a/cache.h b/cache.h
index 39331c2..4f4495f 100644
--- a/cache.h
+++ b/cache.h
@@ -303,6 +303,7 @@ struct lock_file {
char filename[PATH_MAX];
};
extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
+extern int close_lock_file(struct lock_file *);
extern int commit_lock_file(struct lock_file *);
extern int hold_locked_index(struct lock_file *, int);
diff --git a/config.c b/config.c
index 857deb6..526a3f4 100644
--- a/config.c
+++ b/config.c
@@ -955,14 +955,12 @@ int git_config_set_multivar(const char* key, const char* value,
munmap(contents, contents_sz);
}
- if (close(fd) || commit_lock_file(lock) < 0) {
+ if (commit_lock_file(lock) < 0) {
fprintf(stderr, "Cannot commit config file!\n");
ret = 4;
goto out_free;
}
- /* fd is closed, so don't try to close it below. */
- fd = -1;
/*
* lock is committed, so don't try to roll it back below.
* NOTE: Since lockfile.c keeps a linked list of all created
@@ -973,8 +971,6 @@ int git_config_set_multivar(const char* key, const char* value,
ret = 0;
out_free:
- if (0 <= fd)
- close(fd);
if (lock)
rollback_lock_file(lock);
free(config_filename);
@@ -1072,7 +1068,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
}
fclose(config_file);
unlock_and_out:
- if (close(out_fd) || commit_lock_file(lock) < 0)
+ if (commit_lock_file(lock) < 0)
ret = error("Cannot commit config file!");
out:
free(config_filename);
diff --git a/fast-import.c b/fast-import.c
index 82e9161..1ce631c 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -1546,10 +1546,16 @@ static void dump_marks(void)
}
dump_marks_helper(f, 0, marks);
- fclose(f);
- if (commit_lock_file(&mark_lock))
+ if (ferror(f) || fclose(f))
failure |= error("Unable to write marks file %s: %s",
mark_file, strerror(errno));
+ /* Since the lock file was fdopen()'ed and then fclose()'ed above,
+ * assign -1 to the lock file descriptor so that commit_lock_file()
+ * won't try to close() it. */
+ mark_lock.fd = -1;
+ if (commit_lock_file(&mark_lock))
+ failure |= error("Unable to write commit file %s: %s",
+ mark_file, strerror(errno));
}
static int read_next_command(void)
diff --git a/lockfile.c b/lockfile.c
index f45d3ed..bcc4786 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -13,7 +13,8 @@ static void remove_lock_file(void)
while (lock_file_list) {
if (lock_file_list->owner == me &&
lock_file_list->filename[0]) {
- close(lock_file_list->fd);
+ if (lock_file_list->fd >= 0)
+ close(lock_file_list->fd);
unlink(lock_file_list->filename);
}
lock_file_list = lock_file_list->next;
@@ -159,11 +160,20 @@ int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on
return fd;
}
+int close_lock_file(struct lock_file *lk)
+{
+ if (close(lk->fd))
+ return -1;
+ lk->fd = -1;
+ return 0;
+}
+
int commit_lock_file(struct lock_file *lk)
{
char result_file[PATH_MAX];
int i;
- close(lk->fd);
+ if (lk->fd >= 0 && close_lock_file(lk))
+ return -1;
strcpy(result_file, lk->filename);
i = strlen(result_file) - 5; /* .lock */
result_file[i] = 0;
@@ -196,7 +206,8 @@ int commit_locked_index(struct lock_file *lk)
void rollback_lock_file(struct lock_file *lk)
{
if (lk->filename[0]) {
- close(lk->fd);
+ if (lk->fd >= 0)
+ close(lk->fd);
unlink(lk->filename);
}
lk->filename[0] = 0;
diff --git a/merge-recursive.c b/merge-recursive.c
index b34177d..c292a77 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1753,7 +1753,7 @@ int main(int argc, char *argv[])
if (active_cache_changed &&
(write_cache(index_fd, active_cache, active_nr) ||
- close(index_fd) || commit_locked_index(lock)))
+ commit_locked_index(lock)))
die ("unable to write %s", get_index_file());
return clean ? 0: 1;
diff --git a/refs.c b/refs.c
index 58f6d17..2c78956 100644
--- a/refs.c
+++ b/refs.c
@@ -864,7 +864,6 @@ static int repack_without_ref(const char *refname)
die("too long a refname '%s'", list->name);
write_or_die(fd, line, len);
}
- close(fd);
return commit_lock_file(&packlock);
}
@@ -1021,12 +1020,9 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
void unlock_ref(struct ref_lock *lock)
{
- if (lock->lock_fd >= 0) {
- close(lock->lock_fd);
- /* Do not free lock->lk -- atexit() still looks at them */
- if (lock->lk)
- rollback_lock_file(lock->lk);
- }
+ /* Do not free lock->lk -- atexit() still looks at them */
+ if (lock->lk)
+ rollback_lock_file(lock->lk);
free(lock->ref_name);
free(lock->orig_ref_name);
free(lock);
@@ -1132,7 +1128,7 @@ int write_ref_sha1(struct ref_lock *lock,
}
if (write_in_full(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 ||
write_in_full(lock->lock_fd, &term, 1) != 1
- || close(lock->lock_fd) < 0) {
+ || close_lock_file(lock->lk) < 0) {
error("Couldn't write %s", lock->lk->filename);
unlock_ref(lock);
return -1;
--
1.5.4.rc3.14.g44397-dirty
next reply other threads:[~2008-01-16 19:13 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-16 19:12 Brandon Casey [this message]
2008-01-16 19:30 ` [PATCH] Improve use of lockfile API Junio C Hamano
2008-01-16 19:36 ` Brandon Casey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=478E572E.3020505@nrlssc.navy.mil \
--to=casey@nrlssc.navy.mil \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox