diff options
| author | Michael Forney <mforney@mforney.org> | 2016-12-10 00:48:42 -0800 |
|---|---|---|
| committer | Michael Forney <mforney@mforney.org> | 2016-12-10 11:56:37 -0800 |
| commit | 54d24bc3b0de58ee417a040c404e1c26a36244ec (patch) | |
| tree | 83c7a504062edc6a5868b31f5e196a4c97b1472e | |
| parent | 1a47d9c6870e4b4e4fcd033d184f31a5b94a7a47 (diff) | |
perms-hook: Handle GIT_DIR and GIT_WORK_TREE
| -rw-r--r-- | util/perms-hook.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/util/perms-hook.c b/util/perms-hook.c index 7f92053b..d2afbaa8 100644 --- a/util/perms-hook.c +++ b/util/perms-hook.c @@ -40,6 +40,7 @@ struct special { extern char **environ; static dev_t rootdev; +static int rootfd = AT_FDCWD; static struct special oldsp, newsp; static int status; @@ -148,14 +149,14 @@ static int chmod_v(const char *path, mode_t mode) { printf("chmod(\"%s\", %#o)\n", path, mode); - return chmod(path, mode); + return fchmodat(rootfd, path, mode, AT_SYMLINK_NOFOLLOW); } static int mkdir_v(const char *path, mode_t mode) { printf("mkdir(\"%s\", %#o)\n", path, mode); - return mkdir(path, mode); + return mkdirat(rootfd, path, mode); } static int @@ -164,7 +165,7 @@ defperm(const char *name) struct stat st; mode_t mode; - if (lstat(name, &st) < 0) + if (fstatat(rootfd, name, &st, AT_SYMLINK_NOFOLLOW) < 0) return -1; if (st.st_dev != rootdev) { errno = EXDEV; @@ -196,7 +197,7 @@ specialperm(struct perm *p) if (p->attempted) return 0; p->attempted = true; - if (lstat(p->name, &st) < 0) { + if (fstatat(rootfd, p->name, &st, AT_SYMLINK_NOFOLLOW) < 0) { if (errno != ENOENT || !S_ISDIR(p->mode)) return -1; if (mkdir_v(p->name, p->mode & ~S_IFMT) < 0) @@ -333,7 +334,7 @@ readchanges(char *old, char *new) int main(int argc, char *argv[]) { - char *prog, *old, *new; + char *prog, *old, *new, *tree; struct stat st; prog = basename(argv[0]); @@ -355,10 +356,16 @@ main(int argc, char *argv[]) exit(2); } - if (stat(".git", &st) < 0) + if (!getenv("GIT_DIR") && stat(".git", &st) < 0) die("stat .git:"); - if (stat(".", &st) < 0) - die("stat .:"); + tree = getenv("GIT_WORK_TREE"); + if (!tree) + tree = "."; + rootfd = open(tree, O_RDONLY); + if (rootfd < 0) + die("open %s:", tree); + if (fstat(rootfd, &st) < 0) + die("fstat:", tree); rootdev = st.st_dev; if (old) |
