summaryrefslogtreecommitdiff
path: root/path.c
diff options
context:
space:
mode:
Diffstat (limited to 'path.c')
-rw-r--r--path.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/path.c b/path.c
index f4ed979997..b7c24a2aac 100644
--- a/path.c
+++ b/path.c
@@ -91,7 +91,8 @@ int validate_headref(const char *path)
struct stat st;
char *buf, buffer[256];
unsigned char sha1[20];
- int len, fd;
+ int fd;
+ ssize_t len;
if (lstat(path, &st) < 0)
return -1;
@@ -266,24 +267,25 @@ int adjust_shared_perm(const char *path)
if (lstat(path, &st) < 0)
return -1;
mode = st.st_mode;
- if (mode & S_IRUSR)
- mode |= (shared_repository == PERM_GROUP
- ? S_IRGRP
- : (shared_repository == PERM_EVERYBODY
- ? (S_IRGRP|S_IROTH)
- : 0));
-
- if (mode & S_IWUSR)
- mode |= S_IWGRP;
-
- if (mode & S_IXUSR)
- mode |= (shared_repository == PERM_GROUP
- ? S_IXGRP
- : (shared_repository == PERM_EVERYBODY
- ? (S_IXGRP|S_IXOTH)
- : 0));
- if (S_ISDIR(mode))
+
+ if (shared_repository) {
+ int tweak = shared_repository;
+ if (!(mode & S_IWUSR))
+ tweak &= ~0222;
+ mode = (mode & ~0777) | tweak;
+ } else {
+ /* Preserve old PERM_UMASK behaviour */
+ if (mode & S_IWUSR)
+ mode |= S_IWGRP;
+ }
+
+ if (S_ISDIR(mode)) {
mode |= FORCE_DIR_SET_GID;
+
+ /* Copy read bits to execute bits */
+ mode |= (shared_repository & 0444) >> 2;
+ }
+
if ((mode & st.st_mode) != mode && chmod(path, mode) < 0)
return -2;
return 0;