Code

set_shared_perm(): sometimes we know what the final mode bits should look like
authorJunio C Hamano <gitster@pobox.com>
Sat, 28 Mar 2009 06:21:00 +0000 (23:21 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 28 Mar 2009 15:02:15 +0000 (08:02 -0700)
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>
cache.h
path.c
sha1_file.c

diff --git a/cache.h b/cache.h
index 189151de25ffd1a6671b7a70f359fa9b94b82173..e283bbe1736ad7ba321c815b48e58cb41e781e16 100644 (file)
--- 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 42898e0fb129d2d2219ab24a043510775beb8b5c..8a0a6741fd664f98f2883348c0a755d60616035b 100644 (file)
--- 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;
 }
index 6f278593e5ecf6cfb4367fd0a3fd0b9eeefe9da6..d978abf43d26a47c73f98c030802e4c7dffe049f 100644 (file)
@@ -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;
 }