aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-01-20 11:43:35 -0800
committerJunio C Hamano <gitster@pobox.com>2016-01-20 11:43:35 -0800
commit7a63c9e3da357a21115e9b5de7ed84b744f9d8b1 (patch)
tree97d1f8f28303c0e0f96e2ae3133f252482d28399
parent85705cfb572878296f26a7fef0d174b5ec694161 (diff)
parentea56518dfe4c7934a6895f25edf0f18d2930e4fd (diff)
downloadgit-7a63c9e3da357a21115e9b5de7ed84b744f9d8b1.tar.gz
git-7a63c9e3da357a21115e9b5de7ed84b744f9d8b1.tar.xz
Merge branch 'js/fopen-harder'
Some codepaths used fopen(3) when opening a fixed path in $GIT_DIR (e.g. COMMIT_EDITMSG) that is meant to be left after the command is done. This however did not work well if the repository is set to be shared with core.sharedRepository and the umask of the previous user is tighter. They have been made to work better by calling unlink(2) and retrying after fopen(3) fails with EPERM. * js/fopen-harder: Handle more file writes correctly in shared repos commit: allow editing the commit message even in shared repos
-rw-r--r--builtin/commit.c2
-rw-r--r--builtin/fast-export.c2
-rw-r--r--builtin/fetch.c2
-rw-r--r--git-compat-util.h1
-rw-r--r--wrapper.c13
5 files changed, 17 insertions, 3 deletions
diff --git a/builtin/commit.c b/builtin/commit.c
index d054f8496..89bf6ad38 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -761,7 +761,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
hook_arg2 = "";
}
- s->fp = fopen(git_path(commit_editmsg), "w");
+ s->fp = fopen_for_writing(git_path(commit_editmsg));
if (s->fp == NULL)
die_errno(_("could not open '%s'"), git_path(commit_editmsg));
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index d9ac5d841..2471297f7 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -880,7 +880,7 @@ static void export_marks(char *file)
FILE *f;
int e = 0;
- f = fopen(file, "w");
+ f = fopen_for_writing(file);
if (!f)
die_errno("Unable to open marks file %s for writing.", file);
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 586840d76..33f04c1b4 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -840,7 +840,7 @@ static void check_not_current_branch(struct ref *ref_map)
static int truncate_fetch_head(void)
{
const char *filename = git_path_fetch_head();
- FILE *fp = fopen(filename, "w");
+ FILE *fp = fopen_for_writing(filename);
if (!fp)
return error(_("cannot open %s: %s\n"), filename, strerror(errno));
diff --git a/git-compat-util.h b/git-compat-util.h
index 2da0a75a3..e8f286722 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -733,6 +733,7 @@ extern int xmkstemp_mode(char *template, int mode);
extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
extern int odb_pack_keep(char *name, size_t namesz, const unsigned char *sha1);
extern char *xgetcwd(void);
+extern FILE *fopen_for_writing(const char *path);
#define REALLOC_ARRAY(x, alloc) (x) = xrealloc((x), (alloc) * sizeof(*(x)))
diff --git a/wrapper.c b/wrapper.c
index b43d43763..29a45d265 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -391,6 +391,19 @@ FILE *xfdopen(int fd, const char *mode)
return stream;
}
+FILE *fopen_for_writing(const char *path)
+{
+ FILE *ret = fopen(path, "w");
+
+ if (!ret && errno == EPERM) {
+ if (!unlink(path))
+ ret = fopen(path, "w");
+ else
+ errno = EPERM;
+ }
+ return ret;
+}
+
int xmkstemp(char *template)
{
int fd;