unpack-trees: allow Porcelain to give different error messages
[gitweb.git] / path.c
diff --git a/path.c b/path.c
index af2716199b92e920df9fe2021035d319e8cafbc6..b7c24a2aacf87ffea6bd6380dbff44e5d317b240 100644 (file)
--- 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))
-               mode |= S_ISGID;
+
+       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;