Skip to content

Commit 79b25b1

Browse files
committed
Merge branch 'cc/access-on-aix-workaround' into next
Workaround for standard-compliant but less-than-useful behaviour of access(2) for the root user. * cc/access-on-aix-workaround: git-compat-util: work around for access(X_OK) under root
2 parents cf6cce8 + 400caaf commit 79b25b1

File tree

5 files changed

+52
-2
lines changed

5 files changed

+52
-2
lines changed

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ all::
439439
#
440440
# Define FILENO_IS_A_MACRO if fileno() is a macro, not a real function.
441441
#
442+
# Define NEED_ACCESS_ROOT_HANDLER if access() under root may success for X_OK
443+
# even if execution permission isn't granted for any user.
444+
#
442445
# Define PAGER_ENV to a SP separated VAR=VAL pairs to define
443446
# default environment variables to be passed when a pager is spawned, e.g.
444447
#
@@ -1833,6 +1836,11 @@ ifdef FILENO_IS_A_MACRO
18331836
COMPAT_OBJS += compat/fileno.o
18341837
endif
18351838

1839+
ifdef NEED_ACCESS_ROOT_HANDLER
1840+
COMPAT_CFLAGS += -DNEED_ACCESS_ROOT_HANDLER
1841+
COMPAT_OBJS += compat/access.o
1842+
endif
1843+
18361844
ifeq ($(TCLTK_PATH),)
18371845
NO_TCLTK = NoThanks
18381846
endif

compat/access.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#define COMPAT_CODE_ACCESS
2+
#include "../git-compat-util.h"
3+
4+
/* Do the same thing access(2) does, but use the effective uid,
5+
* and don't make the mistake of telling root that any file is
6+
* executable. This version uses stat(2).
7+
*/
8+
int git_access(const char *path, int mode)
9+
{
10+
struct stat st;
11+
12+
/* do not interfere a normal user */
13+
if (geteuid())
14+
return access(path, mode);
15+
16+
if (stat(path, &st) < 0)
17+
return -1;
18+
19+
/* Root can read or write any file. */
20+
if (!(mode & X_OK))
21+
return 0;
22+
23+
/* Root can execute any file that has any one of the execute
24+
* bits set.
25+
*/
26+
if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
27+
return 0;
28+
29+
errno = EACCES;
30+
return -1;
31+
}

compat/fileno.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#define COMPAT_CODE
1+
#define COMPAT_CODE_FILENO
22
#include "../git-compat-util.h"
33

44
int git_fileno(FILE *stream)

config.mak.uname

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ ifeq ($(uname_S),AIX)
272272
NEEDS_LIBICONV = YesPlease
273273
BASIC_CFLAGS += -D_LARGE_FILES
274274
FILENO_IS_A_MACRO = UnfortunatelyYes
275+
NEED_ACCESS_ROOT_HANDLER = UnfortunatelyYes
275276
ifeq ($(shell expr "$(uname_V)" : '[1234]'),1)
276277
NO_PTHREADS = YesPlease
277278
else

git-compat-util.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1237,12 +1237,22 @@ struct tm *git_gmtime_r(const time_t *, struct tm *);
12371237

12381238
#ifdef FILENO_IS_A_MACRO
12391239
int git_fileno(FILE *stream);
1240-
# ifndef COMPAT_CODE
1240+
# ifndef COMPAT_CODE_FILENO
12411241
# undef fileno
12421242
# define fileno(p) git_fileno(p)
12431243
# endif
12441244
#endif
12451245

1246+
#ifdef NEED_ACCESS_ROOT_HANDLER
1247+
int git_access(const char *path, int mode);
1248+
# ifndef COMPAT_CODE_ACCESS
1249+
# ifdef access
1250+
# undef access
1251+
# endif
1252+
# define access(path, mode) git_access(path, mode)
1253+
# endif
1254+
#endif
1255+
12461256
/*
12471257
* Our code often opens a path to an optional file, to work on its
12481258
* contents when we can successfully open it. We can ignore a failure

0 commit comments

Comments
 (0)