Merge branch 'cc/access-on-aix-workaround'
authorJunio C Hamano <gitster@pobox.com>
Mon, 13 May 2019 14:50:35 +0000 (23:50 +0900)
committerJunio C Hamano <gitster@pobox.com>
Mon, 13 May 2019 14:50:35 +0000 (23:50 +0900)
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

1  2 
Makefile
config.mak.uname
git-compat-util.h
diff --combined Makefile
index 5b0855c7e88e83a8ba2f34ff2e896c70e98e0950,b5e2822d82d4b904de004c1e5c2d154b6bb33115..f965509b3c0fbaac60af3305401b7a3c6ea9b865
+++ b/Makefile
@@@ -439,6 -439,9 +439,9 @@@ all:
  #
  # Define FILENO_IS_A_MACRO if fileno() is a macro, not a real function.
  #
+ # Define NEED_ACCESS_ROOT_HANDLER if access() under root may success for X_OK
+ # even if execution permission isn't granted for any user.
+ #
  # Define PAGER_ENV to a SP separated VAR=VAL pairs to define
  # default environment variables to be passed when a pager is spawned, e.g.
  #
  #
  # Define DEVELOPER to enable more compiler warnings. Compiler version
  # and family are auto detected, but could be overridden by defining
 -# COMPILER_FEATURES (see config.mak.dev)
 +# COMPILER_FEATURES (see config.mak.dev). You can still set
 +# CFLAGS="..." in combination with DEVELOPER enables, whether that's
 +# for tweaking something unrelated (e.g. optimization level), or for
 +# selectively overriding something DEVELOPER or one of the DEVOPTS
 +# (see just below) brings in.
  #
  # When DEVELOPER is set, DEVOPTS can be used to control compiler
  # options.  This variable contains keywords separated by
@@@ -510,8 -509,17 +513,8 @@@ GIT-VERSION-FILE: FORC
        @$(SHELL_PATH) ./GIT-VERSION-GEN
  -include GIT-VERSION-FILE
  
 -# CFLAGS and LDFLAGS are for the users to override from the command line.
 -
 -CFLAGS = -g -O2 -Wall
 -LDFLAGS =
 -ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS)
 -ALL_LDFLAGS = $(LDFLAGS)
 -STRIP ?= strip
 -
 -# Create as necessary, replace existing, make ranlib unneeded.
 -ARFLAGS = rcs
 -
 +# Set our default configuration.
 +#
  # Among the variables below, these:
  #   gitexecdir
  #   template_dir
@@@ -556,7 -564,6 +559,7 @@@ perllibdir_relative = $(patsubst $(pref
  
  export prefix bindir sharedir sysconfdir gitwebdir perllibdir localedir
  
 +# Set our default programs
  CC = cc
  AR = ar
  RM = rm -f
@@@ -569,14 -576,29 +572,14 @@@ TCLTK_PATH = wis
  XGETTEXT = xgettext
  MSGFMT = msgfmt
  CURL_CONFIG = curl-config
 -PTHREAD_LIBS = -lpthread
 -PTHREAD_CFLAGS =
  GCOV = gcov
 +STRIP = strip
  SPATCH = spatch
  
  export TCL_PATH TCLTK_PATH
  
 -# user customisation variable for 'sparse' target
 -SPARSE_FLAGS ?=
 -# internal/platform customisation variable for 'sparse'
 -SP_EXTRA_FLAGS =
 -
 -SPATCH_FLAGS = --all-includes --patch .
 -
 -
 -
 -### --- END CONFIGURATION SECTION ---
 -
 -# Those must not be GNU-specific; they are shared with perl/ which may
 -# be built by a different compiler. (Note that this is an artifact now
 -# but it still might be nice to keep that distinction.)
 -BASIC_CFLAGS = -I.
 -BASIC_LDFLAGS =
 +# Set our default LIBS variables
 +PTHREAD_LIBS = -lpthread
  
  # Guard against environment variables
  BUILTIN_OBJS =
@@@ -592,7 -614,6 +595,7 @@@ FUZZ_PROGRAMS 
  LIB_OBJS =
  PROGRAM_OBJS =
  PROGRAMS =
 +EXCLUDED_PROGRAMS =
  SCRIPT_PERL =
  SCRIPT_PYTHON =
  SCRIPT_SH =
@@@ -614,8 -635,10 +617,8 @@@ SCRIPT_SH += git-merge-one-file.s
  SCRIPT_SH += git-merge-resolve.sh
  SCRIPT_SH += git-mergetool.sh
  SCRIPT_SH += git-quiltimport.sh
 -SCRIPT_SH += git-legacy-rebase.sh
 -SCRIPT_SH += git-remote-testgit.sh
 +SCRIPT_SH += git-legacy-stash.sh
  SCRIPT_SH += git-request-pull.sh
 -SCRIPT_SH += git-stash.sh
  SCRIPT_SH += git-submodule.sh
  SCRIPT_SH += git-web--browse.sh
  
@@@ -637,11 -660,17 +640,11 @@@ SCRIPT_PERL += git-svn.per
  
  SCRIPT_PYTHON += git-p4.py
  
 -NO_INSTALL += git-remote-testgit
 -
  # Generated files for scripts
  SCRIPT_SH_GEN = $(patsubst %.sh,%,$(SCRIPT_SH))
  SCRIPT_PERL_GEN = $(patsubst %.perl,%,$(SCRIPT_PERL))
  SCRIPT_PYTHON_GEN = $(patsubst %.py,%,$(SCRIPT_PYTHON))
  
 -SCRIPT_SH_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_SH_GEN))
 -SCRIPT_PERL_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_PERL_GEN))
 -SCRIPT_PYTHON_INS = $(filter-out $(NO_INSTALL),$(SCRIPT_PYTHON_GEN))
 -
  # Individual rules to allow e.g.
  # "make -C ../.. SCRIPT_PERL=contrib/foo/bar.perl build-perl-script"
  # from subdirectories like contrib/*/
@@@ -651,11 -680,11 +654,11 @@@ build-sh-script: $(SCRIPT_SH_GEN
  build-python-script: $(SCRIPT_PYTHON_GEN)
  
  .PHONY: install-perl-script install-sh-script install-python-script
 -install-sh-script: $(SCRIPT_SH_INS)
 +install-sh-script: $(SCRIPT_SH_GEN)
        $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 -install-perl-script: $(SCRIPT_PERL_INS)
 +install-perl-script: $(SCRIPT_PERL_GEN)
        $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 -install-python-script: $(SCRIPT_PYTHON_INS)
 +install-python-script: $(SCRIPT_PYTHON_GEN)
        $(INSTALL) $^ '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
  
  .PHONY: clean-perl-script clean-sh-script clean-python-script
@@@ -666,9 -695,9 +669,9 @@@ clean-perl-script
  clean-python-script:
        $(RM) $(SCRIPT_PYTHON_GEN)
  
 -SCRIPTS = $(SCRIPT_SH_INS) \
 -        $(SCRIPT_PERL_INS) \
 -        $(SCRIPT_PYTHON_INS) \
 +SCRIPTS = $(SCRIPT_SH_GEN) \
 +        $(SCRIPT_PERL_GEN) \
 +        $(SCRIPT_PYTHON_GEN) \
          git-instaweb
  
  ETAGS_TARGET = TAGS
@@@ -738,7 -767,6 +741,7 @@@ TEST_BUILTINS_OBJS += test-repository.
  TEST_BUILTINS_OBJS += test-revision-walking.o
  TEST_BUILTINS_OBJS += test-run-command.o
  TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
 +TEST_BUILTINS_OBJS += test-serve-v2.o
  TEST_BUILTINS_OBJS += test-sha1.o
  TEST_BUILTINS_OBJS += test-sha1-array.o
  TEST_BUILTINS_OBJS += test-sha256.o
@@@ -748,7 -776,6 +751,7 @@@ TEST_BUILTINS_OBJS += test-string-list.
  TEST_BUILTINS_OBJS += test-submodule-config.o
  TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o
  TEST_BUILTINS_OBJS += test-subprocess.o
 +TEST_BUILTINS_OBJS += test-trace2.o
  TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
  TEST_BUILTINS_OBJS += test-xml-encode.o
  TEST_BUILTINS_OBJS += test-wildmatch.o
@@@ -817,12 -844,11 +820,12 @@@ VCSSVN_LIB = vcs-svn/lib.
  
  GENERATED_H += command-list.h
  
 -LIB_H = $(shell $(FIND) . \
 +LIB_H := $(sort $(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \
 +      $(FIND) . \
        -name .git -prune -o \
        -name t -prune -o \
        -name Documentation -prune -o \
 -      -name '*.h' -print)
 +      -name '*.h' -print))
  
  LIB_OBJS += abspath.o
  LIB_OBJS += advice.o
@@@ -994,17 -1020,6 +997,17 @@@ LIB_OBJS += tempfile.
  LIB_OBJS += thread-utils.o
  LIB_OBJS += tmp-objdir.o
  LIB_OBJS += trace.o
 +LIB_OBJS += trace2.o
 +LIB_OBJS += trace2/tr2_cfg.o
 +LIB_OBJS += trace2/tr2_cmd_name.o
 +LIB_OBJS += trace2/tr2_dst.o
 +LIB_OBJS += trace2/tr2_sid.o
 +LIB_OBJS += trace2/tr2_sysenv.o
 +LIB_OBJS += trace2/tr2_tbuf.o
 +LIB_OBJS += trace2/tr2_tgt_event.o
 +LIB_OBJS += trace2/tr2_tgt_normal.o
 +LIB_OBJS += trace2/tr2_tgt_perf.o
 +LIB_OBJS += trace2/tr2_tls.o
  LIB_OBJS += trailer.o
  LIB_OBJS += transport.o
  LIB_OBJS += transport-helper.o
@@@ -1106,6 -1121,7 +1109,6 @@@ BUILTIN_OBJS += builtin/push.
  BUILTIN_OBJS += builtin/range-diff.o
  BUILTIN_OBJS += builtin/read-tree.o
  BUILTIN_OBJS += builtin/rebase.o
 -BUILTIN_OBJS += builtin/rebase--interactive.o
  BUILTIN_OBJS += builtin/receive-pack.o
  BUILTIN_OBJS += builtin/reflog.o
  BUILTIN_OBJS += builtin/remote.o
@@@ -1120,11 -1136,11 +1123,11 @@@ BUILTIN_OBJS += builtin/rev-parse.
  BUILTIN_OBJS += builtin/revert.o
  BUILTIN_OBJS += builtin/rm.o
  BUILTIN_OBJS += builtin/send-pack.o
 -BUILTIN_OBJS += builtin/serve.o
  BUILTIN_OBJS += builtin/shortlog.o
  BUILTIN_OBJS += builtin/show-branch.o
  BUILTIN_OBJS += builtin/show-index.o
  BUILTIN_OBJS += builtin/show-ref.o
 +BUILTIN_OBJS += builtin/stash.o
  BUILTIN_OBJS += builtin/stripspace.o
  BUILTIN_OBJS += builtin/submodule--helper.o
  BUILTIN_OBJS += builtin/symbolic-ref.o
@@@ -1152,25 -1168,6 +1155,25 @@@ ifeq ($(wildcard sha1collisiondetection
  DC_SHA1_SUBMODULE = auto
  endif
  
 +# Set CFLAGS, LDFLAGS and other *FLAGS variables. These might be
 +# tweaked by config.* below as well as the command-line, both of
 +# which'll override these defaults.
 +CFLAGS = -g -O2 -Wall
 +LDFLAGS =
 +BASIC_CFLAGS = -I.
 +BASIC_LDFLAGS =
 +
 +# library flags
 +ARFLAGS = rcs
 +PTHREAD_CFLAGS =
 +
 +# For the 'sparse' target
 +SPARSE_FLAGS ?=
 +SP_EXTRA_FLAGS =
 +
 +# For the 'coccicheck' target
 +SPATCH_FLAGS = --all-includes --patch .
 +
  include config.mak.uname
  -include config.mak.autogen
  -include config.mak
@@@ -1179,9 -1176,6 +1182,9 @@@ ifdef DEVELOPE
  include config.mak.dev
  endif
  
 +ALL_CFLAGS = $(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS)
 +ALL_LDFLAGS = $(LDFLAGS)
 +
  comma := ,
  empty :=
  space := $(empty) $(empty)
@@@ -1192,7 -1186,6 +1195,7 @@@ BASIC_CFLAGS += -fsanitize=$(SANITIZE) 
  BASIC_CFLAGS += -fno-omit-frame-pointer
  ifneq ($(filter undefined,$(SANITIZERS)),)
  BASIC_CFLAGS += -DNO_UNALIGNED_LOADS
 +BASIC_CFLAGS += -DSHA1DC_FORCE_ALIGNED_ACCESS
  endif
  ifneq ($(filter leak,$(SANITIZERS)),)
  BASIC_CFLAGS += -DSUPPRESS_ANNOTATED_LEAKS
@@@ -1336,7 -1329,6 +1339,7 @@@ ifdef NO_CUR
        REMOTE_CURL_PRIMARY =
        REMOTE_CURL_ALIASES =
        REMOTE_CURL_NAMES =
 +      EXCLUDED_PROGRAMS += git-http-fetch git-http-push
  else
        ifdef CURLDIR
                # Try "-Wl,-rpath=$(CURLDIR)/$(lib)" in such a case.
@@@ -1361,11 -1353,7 +1364,11 @@@ endi
        ifeq "$(curl_check)" "070908"
                ifndef NO_EXPAT
                        PROGRAM_OBJS += http-push.o
 +              else
 +                      EXCLUDED_PROGRAMS += git-http-push
                endif
 +      else
 +              EXCLUDED_PROGRAMS += git-http-push
        endif
        curl_check := $(shell (echo 072200; $(CURL_CONFIG) --vernum | sed -e '/^70[BC]/s/^/0/') 2>/dev/null | sort -r | sed -ne 2p)
        ifeq "$(curl_check)" "072200"
@@@ -1611,10 -1599,7 +1614,10 @@@ ifdef NO_INET_PTO
        LIB_OBJS += compat/inet_pton.o
        BASIC_CFLAGS += -DNO_INET_PTON
  endif
 -ifndef NO_UNIX_SOCKETS
 +ifdef NO_UNIX_SOCKETS
 +      BASIC_CFLAGS += -DNO_UNIX_SOCKETS
 +      EXCLUDED_PROGRAMS += git-credential-cache git-credential-cache--daemon
 +else
        LIB_OBJS += unix-socket.o
        PROGRAM_OBJS += credential-cache.o
        PROGRAM_OBJS += credential-cache--daemon.o
@@@ -1833,6 -1818,11 +1836,11 @@@ ifdef FILENO_IS_A_MACR
        COMPAT_OBJS += compat/fileno.o
  endif
  
+ ifdef NEED_ACCESS_ROOT_HANDLER
+       COMPAT_CFLAGS += -DNEED_ACCESS_ROOT_HANDLER
+       COMPAT_OBJS += compat/access.o
+ endif
  ifeq ($(TCLTK_PATH),)
  NO_TCLTK = NoThanks
  endif
@@@ -2133,9 -2123,7 +2141,9 @@@ $(BUILT_INS): git$
  command-list.h: generate-cmdlist.sh command-list.txt
  
  command-list.h: $(wildcard Documentation/git*.txt) Documentation/*config.txt Documentation/config/*.txt
 -      $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@
 +      $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh \
 +              $(patsubst %,--exclude-program %,$(EXCLUDED_PROGRAMS)) \
 +              command-list.txt >$@+ && mv $@+ $@
  
  SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
        $(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\
@@@ -2383,7 -2371,7 +2391,7 @@@ els
  # should _not_ be included here, since they are necessary even when
  # building an object for the first time.
  
 -$(OBJECTS): $(LIB_H)
 +$(OBJECTS): $(LIB_H) $(GENERATED_H)
  endif
  
  exec-cmd.sp exec-cmd.s exec-cmd.o: GIT-PREFIX
@@@ -2468,14 -2456,6 +2476,14 @@@ $(VCSSVN_LIB): $(VCSSVN_OBJS
  
  export DEFAULT_EDITOR DEFAULT_PAGER
  
 +Documentation/GIT-EXCLUDED-PROGRAMS: FORCE
 +      @EXCLUDED='EXCLUDED_PROGRAMS := $(EXCLUDED_PROGRAMS)'; \
 +          if test x"$$EXCLUDED" != \
 +              x"`cat Documentation/GIT-EXCLUDED-PROGRAMS 2>/dev/null`" ; then \
 +              echo >&2 "    * new documentation flags"; \
 +              echo "$$EXCLUDED" >Documentation/GIT-EXCLUDED-PROGRAMS; \
 +            fi
 +
  .PHONY: doc man man-perl html info pdf
  doc: man-perl
        $(MAKE) -C Documentation all
@@@ -2714,6 -2694,7 +2722,6 @@@ endi
  test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X))
  
  all:: $(TEST_PROGRAMS) $(test_bindir_programs)
 -all:: $(NO_INSTALL)
  
  bin-wrappers/%: wrap-for-bin.sh
        @mkdir -p bin-wrappers
@@@ -2763,10 -2744,7 +2771,10 @@@ $(SP_OBJ): %.sp: %.c GIT-CFLAGS FORC
  sparse: $(SP_OBJ)
  
  GEN_HDRS := command-list.h unicode-width.h
 -EXCEPT_HDRS := $(GEN_HDRS) compat% xdiff%
 +EXCEPT_HDRS := $(GEN_HDRS) compat/% xdiff/%
 +ifndef GCRYPT_SHA256
 +      EXCEPT_HDRS += sha256/gcrypt.h
 +endif
  CHK_HDRS = $(filter-out $(EXCEPT_HDRS),$(patsubst ./%,%,$(LIB_H)))
  HCO = $(patsubst %.h,%.hco,$(CHK_HDRS))
  
@@@ -3000,7 -2978,7 +3008,7 @@@ rpm:
  
  artifacts-tar:: $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS) \
                GIT-BUILD-OPTIONS $(TEST_PROGRAMS) $(test_bindir_programs) \
 -              $(NO_INSTALL) $(MOFILES)
 +              $(MOFILES)
        $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) \
                SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)'
        test -n "$(ARTIFACTS_DIRECTORY)"
@@@ -3049,7 -3027,7 +3057,7 @@@ clean: profile-clean coverage-clean coc
        $(RM) $(OBJECTS)
        $(RM) $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
        $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
 -      $(RM) $(TEST_PROGRAMS) $(NO_INSTALL)
 +      $(RM) $(TEST_PROGRAMS)
        $(RM) $(FUZZ_PROGRAMS)
        $(RM) -r bin-wrappers $(dep_dirs)
        $(RM) -r po/build/
        $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
        $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
        $(MAKE) -C Documentation/ clean
 +      $(RM) Documentation/GIT-EXCLUDED-PROGRAMS
  ifndef NO_PERL
        $(MAKE) -C gitweb clean
        $(RM) -r perl/build/
@@@ -3088,13 -3065,13 +3096,13 @@@ ALL_COMMANDS += git-gui git-citoo
  .PHONY: check-docs
  check-docs::
        $(MAKE) -C Documentation lint-docs
 -      @(for v in $(ALL_COMMANDS); \
 +      @(for v in $(patsubst %$X,%,$(ALL_COMMANDS)); \
        do \
                case "$$v" in \
                git-merge-octopus | git-merge-ours | git-merge-recursive | \
                git-merge-resolve | git-merge-subtree | \
                git-fsck-objects | git-init-db | \
 -              git-remote-* | git-stage | \
 +              git-remote-* | git-stage | git-legacy-* | \
                git-?*--?* ) continue ;; \
                esac ; \
                test -f "Documentation/$$v.txt" || \
        ( \
                sed -e '1,/^### command list/d' \
                    -e '/^#/d' \
 +                  -e '/guide$$/d' \
                    -e 's/[     ].*//' \
                    -e 's/^/listed /' command-list.txt; \
                $(MAKE) -C Documentation print-man1 | \
                grep '\.txt$$' | \
 -              sed -e 's|Documentation/|documented |' \
 +              sed -e 's|^|documented |' \
                    -e 's/\.txt//'; \
        ) | while read how cmd; \
        do \
 -              case " $(ALL_COMMANDS) " in \
 +              case " $(patsubst %$X,%,$(ALL_COMMANDS) $(EXCLUDED_PROGRAMS)) " in \
                *" $$cmd "*)    ;; \
                *) echo "removed but $$how: $$cmd" ;; \
                esac; \
diff --combined config.mak.uname
index d916d1dc7ab90d954dcd25f89d09f7478053112a,97ebacc1c5cc8250186f3e48f4d4b6a86fed6460..19ce2f296a79da9275105748cbb222a7fd50e50d
@@@ -114,8 -114,6 +114,8 @@@ ifeq ($(uname_S),Darwin
        HAVE_BSD_SYSCTL = YesPlease
        FREAD_READS_DIRECTORIES = UnfortunatelyYes
        HAVE_NS_GET_EXECUTABLE_PATH = YesPlease
 +      BASIC_CFLAGS += -I/usr/local/include
 +      BASIC_LDFLAGS += -L/usr/local/lib
  endif
  ifeq ($(uname_S),SunOS)
        NEEDS_SOCKET = YesPlease
@@@ -272,6 -270,7 +272,7 @@@ ifeq ($(uname_S),AIX
        NEEDS_LIBICONV = YesPlease
        BASIC_CFLAGS += -D_LARGE_FILES
        FILENO_IS_A_MACRO = UnfortunatelyYes
+       NEED_ACCESS_ROOT_HANDLER = UnfortunatelyYes
        ifeq ($(shell expr "$(uname_V)" : '[1234]'),1)
                NO_PTHREADS = YesPlease
        else
@@@ -395,9 -394,7 +396,9 @@@ ifeq ($(uname_S),Windows
        CFLAGS =
        BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
        COMPAT_OBJS = compat/msvc.o compat/winansi.o \
 +              compat/win32/path-utils.o \
                compat/win32/pthread.o compat/win32/syslog.o \
 +              compat/win32/trace2_win32_process_info.o \
                compat/win32/dirent.o
        COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
        BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE
@@@ -534,6 -531,7 +535,6 @@@ ifneq (,$(findstring MINGW,$(uname_S))
        NO_STRTOUMAX = YesPlease
        NO_MKDTEMP = YesPlease
        NO_SVN_TESTS = YesPlease
 -      NO_PERL_MAKEMAKER = YesPlease
        RUNTIME_PREFIX = YesPlease
        HAVE_WPGMPTR = YesWeDo
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        COMPAT_CFLAGS += -DNOGDI -Icompat -Icompat/win32
        COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
        COMPAT_OBJS += compat/mingw.o compat/winansi.o \
 +              compat/win32/trace2_win32_process_info.o \
                compat/win32/path-utils.o \
                compat/win32/pthread.o compat/win32/syslog.o \
                compat/win32/dirent.o
diff --combined git-compat-util.h
index fd3460108b4f41637def60e8a7232bbaaf075f5c,e3c79b14782dba08eecc64c2352b98e6e08116a1..cc0e7e97334ec90a355f9c8eb088c6810a91193c
  #include "compat/win32/path-utils.h"
  #include "compat/mingw.h"
  #elif defined(_MSC_VER)
 +#include "compat/win32/path-utils.h"
  #include "compat/msvc.h"
  #else
  #include <sys/utsname.h>
@@@ -250,7 -249,7 +250,7 @@@ typedef unsigned long uintptr_t
  
  #ifdef MKDIR_WO_TRAILING_SLASH
  #define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
 -extern int compat_mkdir_wo_trailing_slash(const char*, mode_t);
 +int compat_mkdir_wo_trailing_slash(const char*, mode_t);
  #endif
  
  #ifdef NO_STRUCT_ITIMERVAL
@@@ -268,9 -267,9 +268,9 @@@ struct itimerval 
  #include <libgen.h>
  #else
  #define basename gitbasename
 -extern char *gitbasename(char *);
 +char *gitbasename(char *);
  #define dirname gitdirname
 -extern char *gitdirname(char *);
 +char *gitdirname(char *);
  #endif
  
  #ifndef NO_ICONV
@@@ -447,15 -446,15 +447,15 @@@ static inline char *git_find_last_dir_s
  struct strbuf;
  
  /* General helper functions */
 -extern void vreportf(const char *prefix, const char *err, va_list params);
 -extern NORETURN void usage(const char *err);
 -extern NORETURN void usagef(const char *err, ...) __attribute__((format (printf, 1, 2)));
 -extern NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2)));
 -extern NORETURN void die_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
 -extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 -extern int error_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
 -extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 -extern void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
 +void vreportf(const char *prefix, const char *err, va_list params);
 +NORETURN void usage(const char *err);
 +NORETURN void usagef(const char *err, ...) __attribute__((format (printf, 1, 2)));
 +NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2)));
 +NORETURN void die_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
 +int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 +int error_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
 +void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 +void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
  
  #ifndef NO_OPENSSL
  #ifdef APPLE_COMMON_CRYPTO
@@@ -483,15 -482,15 +483,15 @@@ static inline int const_error(void
  #define error_errno(...) (error_errno(__VA_ARGS__), const_error())
  #endif
  
 -extern void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));
 -extern void set_error_routine(void (*routine)(const char *err, va_list params));
 +void set_die_routine(NORETURN_PTR void (*routine)(const char *err, va_list params));
 +void set_error_routine(void (*routine)(const char *err, va_list params));
  extern void (*get_error_routine(void))(const char *err, va_list params);
 -extern void set_warn_routine(void (*routine)(const char *warn, va_list params));
 +void set_warn_routine(void (*routine)(const char *warn, va_list params));
  extern void (*get_warn_routine(void))(const char *warn, va_list params);
 -extern void set_die_is_recursing_routine(int (*routine)(void));
 +void set_die_is_recursing_routine(int (*routine)(void));
  
 -extern int starts_with(const char *str, const char *prefix);
 -extern int istarts_with(const char *str, const char *prefix);
 +int starts_with(const char *str, const char *prefix);
 +int istarts_with(const char *str, const char *prefix);
  
  /*
   * If the string "str" begins with the string found in "prefix", return 1.
@@@ -614,8 -613,8 +614,8 @@@ static inline int ends_with(const char 
  
  #define mmap git_mmap
  #define munmap git_munmap
 -extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 -extern int git_munmap(void *start, size_t length);
 +void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 +int git_munmap(void *start, size_t length);
  
  #else /* NO_MMAP || USE_WIN32_MMAP */
  
  #undef stat
  #endif
  #define stat(path, buf) git_stat(path, buf)
 -extern int git_stat(const char *, struct stat *);
 +int git_stat(const char *, struct stat *);
  #ifdef fstat
  #undef fstat
  #endif
  #define fstat(fd, buf) git_fstat(fd, buf)
 -extern int git_fstat(int, struct stat *);
 +int git_fstat(int, struct stat *);
  #ifdef lstat
  #undef lstat
  #endif
  #define lstat(path, buf) git_lstat(path, buf)
 -extern int git_lstat(const char *, struct stat *);
 +int git_lstat(const char *, struct stat *);
  #endif
  
  #define DEFAULT_PACKED_GIT_LIMIT \
  
  #ifdef NO_PREAD
  #define pread git_pread
 -extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
 +ssize_t git_pread(int fd, void *buf, size_t count, off_t offset);
  #endif
  /*
   * Forward decl that will remind us if its twin in cache.h changes.
   * This function is used in compat/pread.c.  But we can't include
   * cache.h there.
   */
 -extern ssize_t read_in_full(int fd, void *buf, size_t count);
 +ssize_t read_in_full(int fd, void *buf, size_t count);
  
  #ifdef NO_SETENV
  #define setenv gitsetenv
 -extern int gitsetenv(const char *, const char *, int);
 +int gitsetenv(const char *, const char *, int);
  #endif
  
  #ifdef NO_MKDTEMP
  #define mkdtemp gitmkdtemp
 -extern char *gitmkdtemp(char *);
 +char *gitmkdtemp(char *);
  #endif
  
  #ifdef NO_UNSETENV
  #define unsetenv gitunsetenv
 -extern void gitunsetenv(const char *);
 +void gitunsetenv(const char *);
  #endif
  
  #ifdef NO_STRCASESTR
  #define strcasestr gitstrcasestr
 -extern char *gitstrcasestr(const char *haystack, const char *needle);
 +char *gitstrcasestr(const char *haystack, const char *needle);
  #endif
  
  #ifdef NO_STRLCPY
  #define strlcpy gitstrlcpy
 -extern size_t gitstrlcpy(char *, const char *, size_t);
 +size_t gitstrlcpy(char *, const char *, size_t);
  #endif
  
  #ifdef NO_STRTOUMAX
  #define strtoumax gitstrtoumax
 -extern uintmax_t gitstrtoumax(const char *, char **, int);
 +uintmax_t gitstrtoumax(const char *, char **, int);
  #define strtoimax gitstrtoimax
 -extern intmax_t gitstrtoimax(const char *, char **, int);
 +intmax_t gitstrtoimax(const char *, char **, int);
  #endif
  
  #ifdef NO_HSTRERROR
  #define hstrerror githstrerror
 -extern const char *githstrerror(int herror);
 +const char *githstrerror(int herror);
  #endif
  
  #ifdef NO_MEMMEM
@@@ -762,7 -761,7 +762,7 @@@ char *gitstrdup(const char *s)
  #  endif
  #  define fopen(a,b) git_fopen(a,b)
  # endif
 -extern FILE *git_fopen(const char*, const char*);
 +FILE *git_fopen(const char*, const char*);
  #endif
  
  #ifdef SNPRINTF_RETURNS_BOGUS
  #undef snprintf
  #endif
  #define snprintf git_snprintf
 -extern int git_snprintf(char *str, size_t maxsize,
 -                      const char *format, ...);
 +int git_snprintf(char *str, size_t maxsize,
 +               const char *format, ...);
  #ifdef vsnprintf
  #undef vsnprintf
  #endif
  #define vsnprintf git_vsnprintf
 -extern int git_vsnprintf(char *str, size_t maxsize,
 -                       const char *format, va_list ap);
 +int git_vsnprintf(char *str, size_t maxsize,
 +                const char *format, va_list ap);
  #endif
  
  #ifdef __GLIBC_PREREQ
@@@ -806,11 -805,11 +806,11 @@@ const char *inet_ntop(int af, const voi
  
  #ifdef NO_PTHREADS
  #define atexit git_atexit
 -extern int git_atexit(void (*handler)(void));
 +int git_atexit(void (*handler)(void));
  #endif
  
  typedef void (*try_to_free_t)(size_t);
 -extern try_to_free_t set_try_to_free_routine(try_to_free_t);
 +try_to_free_t set_try_to_free_routine(try_to_free_t);
  
  static inline size_t st_add(size_t a, size_t b)
  {
@@@ -846,28 -845,28 +846,28 @@@ static inline size_t st_sub(size_t a, s
  # define xalloca(size)      (xmalloc(size))
  # define xalloca_free(p)    (free(p))
  #endif
 -extern char *xstrdup(const char *str);
 -extern void *xmalloc(size_t size);
 -extern void *xmallocz(size_t size);
 -extern void *xmallocz_gently(size_t size);
 -extern void *xmemdupz(const void *data, size_t len);
 -extern char *xstrndup(const char *str, size_t len);
 -extern void *xrealloc(void *ptr, size_t size);
 -extern void *xcalloc(size_t nmemb, size_t size);
 -extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 -extern void *xmmap_gently(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 -extern int xopen(const char *path, int flags, ...);
 -extern ssize_t xread(int fd, void *buf, size_t len);
 -extern ssize_t xwrite(int fd, const void *buf, size_t len);
 -extern ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
 -extern int xdup(int fd);
 -extern FILE *xfopen(const char *path, const char *mode);
 -extern FILE *xfdopen(int fd, const char *mode);
 -extern int xmkstemp(char *temp_filename);
 -extern int xmkstemp_mode(char *temp_filename, int mode);
 -extern char *xgetcwd(void);
 -extern FILE *fopen_for_writing(const char *path);
 -extern FILE *fopen_or_warn(const char *path, const char *mode);
 +char *xstrdup(const char *str);
 +void *xmalloc(size_t size);
 +void *xmallocz(size_t size);
 +void *xmallocz_gently(size_t size);
 +void *xmemdupz(const void *data, size_t len);
 +char *xstrndup(const char *str, size_t len);
 +void *xrealloc(void *ptr, size_t size);
 +void *xcalloc(size_t nmemb, size_t size);
 +void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 +void *xmmap_gently(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 +int xopen(const char *path, int flags, ...);
 +ssize_t xread(int fd, void *buf, size_t len);
 +ssize_t xwrite(int fd, const void *buf, size_t len);
 +ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
 +int xdup(int fd);
 +FILE *xfopen(const char *path, const char *mode);
 +FILE *xfdopen(int fd, const char *mode);
 +int xmkstemp(char *temp_filename);
 +int xmkstemp_mode(char *temp_filename, int mode);
 +char *xgetcwd(void);
 +FILE *fopen_for_writing(const char *path);
 +FILE *fopen_or_warn(const char *path, const char *mode);
  
  /*
   * FREE_AND_NULL(ptr) is like free(ptr) followed by ptr = NULL. Note
@@@ -967,13 -966,13 +967,13 @@@ static inline size_t xsize_t(off_t len
  }
  
  __attribute__((format (printf, 3, 4)))
 -extern int xsnprintf(char *dst, size_t max, const char *fmt, ...);
 +int xsnprintf(char *dst, size_t max, const char *fmt, ...);
  
  #ifndef HOST_NAME_MAX
  #define HOST_NAME_MAX 256
  #endif
  
 -extern int xgethostname(char *buf, size_t len);
 +int xgethostname(char *buf, size_t len);
  
  /* in ctype.c, for kwset users */
  extern const unsigned char tolower_trans_tbl[256];
@@@ -1237,12 -1236,22 +1237,22 @@@ struct tm *git_gmtime_r(const time_t *
  
  #ifdef FILENO_IS_A_MACRO
  int git_fileno(FILE *stream);
- # ifndef COMPAT_CODE
+ # ifndef COMPAT_CODE_FILENO
  #  undef fileno
  #  define fileno(p) git_fileno(p)
  # endif
  #endif
  
+ #ifdef NEED_ACCESS_ROOT_HANDLER
+ int git_access(const char *path, int mode);
+ # ifndef COMPAT_CODE_ACCESS
+ #  ifdef access
+ #  undef access
+ #  endif
+ #  define access(path, mode) git_access(path, mode)
+ # endif
+ #endif
  /*
   * Our code often opens a path to an optional file, to work on its
   * contents when we can successfully open it.  We can ignore a failure
@@@ -1258,14 -1267,7 +1268,14 @@@ static inline int is_missing_file_error
        return (errno_ == ENOENT || errno_ == ENOTDIR);
  }
  
 -extern int cmd_main(int, const char **);
 +int cmd_main(int, const char **);
 +
 +/*
 + * Intercept all calls to exit() and route them to trace2 to
 + * optionally emit a message before calling the real exit().
 + */
 +int trace2_cmd_exit_fl(const char *file, int line, int code);
 +#define exit(code) exit(trace2_cmd_exit_fl(__FILE__, __LINE__, (code)))
  
  /*
   * You can mark a stack variable with UNLEAK(var) to avoid it being
   * an annotation, and does nothing in non-leak-checking builds.
   */
  #ifdef SUPPRESS_ANNOTATED_LEAKS
 -extern void unleak_memory(const void *ptr, size_t len);
 +void unleak_memory(const void *ptr, size_t len);
  #define UNLEAK(var) unleak_memory(&(var), sizeof(var))
  #else
  #define UNLEAK(var) do {} while (0)