summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2009-03-27 23:21:00 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2009-03-28 08:02:15 -0700
commit17e61b82887fb71800b0fcd39ffe89ddf4d2492e (patch)
tree626d729d96b73a838f84059bd85cd975bd668003
parentmove_temp_to_file(): do not forget to chmod() in "Coda hack" codepath (diff)
downloadtgif-17e61b82887fb71800b0fcd39ffe89ddf4d2492e.tar.xz
set_shared_perm(): sometimes we know what the final mode bits should look like
adjust_shared_perm() first obtains the mode bits from lstat(2), expecting to find what the result of applying user's umask is, and then tweaks it as necessary. When the file to be adjusted is created with mkstemp(3), however, the mode thusly obtained does not have anything to do with user's umask, and we would need to start from 0444 in such a case and there is no point running lstat(2) for such a path. This introduces a new API set_shared_perm() to bypass the lstat(2) and instead force setting the mode bits to the desired value directly. adjust_shared_perm() becomes a thin wrapper to the function. Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--cache.h3
-rw-r--r--path.c25
-rw-r--r--sha1_file.c2
3 files changed, 19 insertions, 11 deletions
diff --git a/cache.h b/cache.h
index 189151de25..e283bbe173 100644
--- a/cache.h
+++ b/cache.h
@@ -613,7 +613,8 @@ enum sharedrepo {
PERM_EVERYBODY = 0664,
};
int git_config_perm(const char *var, const char *value);
-int adjust_shared_perm(const char *path);
+int set_shared_perm(const char *path, int mode);
+#define adjust_shared_perm(path) set_shared_perm((path), 0)
int safe_create_leading_directories(char *path);
int safe_create_leading_directories_const(const char *path);
char *enter_repo(char *path, int strict);
diff --git a/path.c b/path.c
index 42898e0fb1..8a0a6741fd 100644
--- a/path.c
+++ b/path.c
@@ -311,16 +311,23 @@ char *enter_repo(char *path, int strict)
return NULL;
}
-int adjust_shared_perm(const char *path)
+int set_shared_perm(const char *path, int mode)
{
struct stat st;
- int mode, tweak, shared;
+ int tweak, shared, orig_mode;
- if (!shared_repository)
+ if (!shared_repository) {
+ if (mode)
+ return chmod(path, mode & ~S_IFMT);
return 0;
- if (lstat(path, &st) < 0)
- return -1;
- mode = st.st_mode;
+ }
+ if (!mode) {
+ if (lstat(path, &st) < 0)
+ return -1;
+ mode = st.st_mode;
+ orig_mode = mode;
+ } else
+ orig_mode = 0;
if (shared_repository < 0)
shared = -shared_repository;
else
@@ -344,9 +351,9 @@ int adjust_shared_perm(const char *path)
}
if (((shared_repository < 0
- ? (st.st_mode & (FORCE_DIR_SET_GID | 0777))
- : (st.st_mode & mode)) != mode) &&
- chmod(path, mode) < 0)
+ ? (orig_mode & (FORCE_DIR_SET_GID | 0777))
+ : (orig_mode & mode)) != mode) &&
+ chmod(path, (mode & ~S_IFMT)) < 0)
return -2;
return 0;
}
diff --git a/sha1_file.c b/sha1_file.c
index 6f278593e5..d978abf43d 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2280,7 +2280,7 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
}
out:
- if (chmod(filename, 0444) || adjust_shared_perm(filename))
+ if (set_shared_perm(filename, (S_IFREG|0444)))
return error("unable to set permission to '%s'", filename);
return 0;
}