From 1306023a4f0bbae1721a6f323d52c8e4e16ca287 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Mon, 30 Mar 2020 22:01:09 -0400 Subject: [PATCH] [SV 57896] Change directories before checking jobserver auth We want to process -C options as early as possible, before we might write informational messages, so that Entering/Leaving messages have the correct directory. * src/main.c (main): Move code dealing with changing directories before parsing of the jobserver auth flag. * tests/scripts/features/jobserver: Test the order of enter/leave. --- src/main.c | 148 +++++++++++++++---------------- tests/scripts/features/jobserver | 32 ++++--- 2 files changed, 95 insertions(+), 85 deletions(-) diff --git a/src/main.c b/src/main.c index 2696f4fb..bcba2d18 100644 --- a/src/main.c +++ b/src/main.c @@ -1522,6 +1522,18 @@ main (int argc, char **argv, char **envp) /* Set always_make_flag if -B was given and we've not restarted already. */ always_make_flag = always_make_set && (restarts == 0); + /* If the user didn't specify any print-directory options, compute the + default setting: disable under -s / print in sub-makes and under -C. */ + + if (print_directory_flag == -1) + print_directory = !silent_flag && (directories != 0 || makelevel > 0); + else + print_directory = print_directory_flag; + + /* If -R was given, set -r too (doesn't make sense otherwise!) */ + if (no_builtin_variables_flag) + no_builtin_rules_flag = 1; + /* Print version information, and exit. */ if (print_version_flag) { @@ -1587,6 +1599,68 @@ main (int argc, char **argv, char **envp) /* We may move, but until we do, here we are. */ starting_directory = current_directory; + /* If there were -C flags, move ourselves about. */ + if (directories != 0) + { + unsigned int i; + for (i = 0; directories->list[i] != 0; ++i) + { + const char *dir = directories->list[i]; +#ifdef WINDOWS32 + /* WINDOWS32 chdir() doesn't work if the directory has a trailing '/' + But allow -C/ just in case someone wants that. */ + { + char *p = (char *)dir + strlen (dir) - 1; + while (p > dir && (p[0] == '/' || p[0] == '\\')) + --p; + p[1] = '\0'; + } +#endif + if (chdir (dir) < 0) + pfatal_with_name (dir); + } + } + +#ifdef WINDOWS32 + /* + * THIS BLOCK OF CODE MUST COME AFTER chdir() CALL ABOVE IN ORDER + * TO NOT CONFUSE THE DEPENDENCY CHECKING CODE IN implicit.c. + * + * The functions in dir.c can incorrectly cache information for "." + * before we have changed directory and this can cause file + * lookups to fail because the current directory (.) was pointing + * at the wrong place when it was first evaluated. + */ + no_default_sh_exe = !find_and_set_default_shell (NULL); +#endif /* WINDOWS32 */ + + /* Construct the list of include directories to search. */ + + construct_include_path (include_directories == 0 + ? 0 : include_directories->list); + + /* If we chdir'ed, figure out where we are now. */ + if (directories) + { +#ifdef WINDOWS32 + if (getcwd_fs (current_directory, GET_PATH_MAX) == 0) +#else + if (getcwd (current_directory, GET_PATH_MAX) == 0) +#endif + { +#ifdef HAVE_GETCWD + perror_with_name ("getcwd", ""); +#else + OS (error, NILF, "getwd: %s", current_directory); +#endif + starting_directory = 0; + } + else + starting_directory = current_directory; + } + + define_variable_cname ("CURDIR", current_directory, o_file, 0); + /* Validate the arg_job_slots configuration before we define MAKEFLAGS so users get an accurate value in their makefiles. At this point arg_job_slots is the argv setting, if there is one, else @@ -1686,80 +1760,6 @@ main (int argc, char **argv, char **envp) #endif } - /* If there were -C flags, move ourselves about. */ - if (directories != 0) - { - unsigned int i; - for (i = 0; directories->list[i] != 0; ++i) - { - const char *dir = directories->list[i]; -#ifdef WINDOWS32 - /* WINDOWS32 chdir() doesn't work if the directory has a trailing '/' - But allow -C/ just in case someone wants that. */ - { - char *p = (char *)dir + strlen (dir) - 1; - while (p > dir && (p[0] == '/' || p[0] == '\\')) - --p; - p[1] = '\0'; - } -#endif - if (chdir (dir) < 0) - pfatal_with_name (dir); - } - } - -#ifdef WINDOWS32 - /* - * THIS BLOCK OF CODE MUST COME AFTER chdir() CALL ABOVE IN ORDER - * TO NOT CONFUSE THE DEPENDENCY CHECKING CODE IN implicit.c. - * - * The functions in dir.c can incorrectly cache information for "." - * before we have changed directory and this can cause file - * lookups to fail because the current directory (.) was pointing - * at the wrong place when it was first evaluated. - */ - no_default_sh_exe = !find_and_set_default_shell (NULL); -#endif /* WINDOWS32 */ - - /* If the user didn't specify any print-directory options, compute the - default setting: disable under -s / print in sub-makes and under -C. */ - - if (print_directory_flag == -1) - print_directory = !silent_flag && (directories != 0 || makelevel > 0); - else - print_directory = print_directory_flag; - - /* If -R was given, set -r too (doesn't make sense otherwise!) */ - if (no_builtin_variables_flag) - no_builtin_rules_flag = 1; - - /* Construct the list of include directories to search. */ - - construct_include_path (include_directories == 0 - ? 0 : include_directories->list); - - /* If we chdir'ed, figure out where we are now. */ - if (directories) - { -#ifdef WINDOWS32 - if (getcwd_fs (current_directory, GET_PATH_MAX) == 0) -#else - if (getcwd (current_directory, GET_PATH_MAX) == 0) -#endif - { -#ifdef HAVE_GETCWD - perror_with_name ("getcwd", ""); -#else - OS (error, NILF, "getwd: %s", current_directory); -#endif - starting_directory = 0; - } - else - starting_directory = current_directory; - } - - define_variable_cname ("CURDIR", current_directory, o_file, 0); - /* Read any stdin makefiles into temporary files. */ if (makefiles != 0) diff --git a/tests/scripts/features/jobserver b/tests/scripts/features/jobserver index 73d10d9f..2d61e3f4 100644 --- a/tests/scripts/features/jobserver +++ b/tests/scripts/features/jobserver @@ -64,17 +64,18 @@ all:;@echo $@: "/$(SHOW)/" unlink('inc.mk'); run_make_test(q! +.RECIPEPREFIX = > -include inc.mk recur: -# @echo 'MAKEFLAGS = $(MAKEFLAGS)' - @rm -f inc.mk - @$(MAKE) -j2 -f #MAKEFILE# all +#> @echo 'MAKEFLAGS = $(MAKEFLAGS)' +> @rm -f inc.mk +> @$(MAKE) -j2 -f #MAKEFILE# all all: -# @echo 'MAKEFLAGS = $(MAKEFLAGS)' - @echo $@ +#> @echo 'MAKEFLAGS = $(MAKEFLAGS)' +> @echo $@ inc.mk: -# @echo 'MAKEFLAGS = $(MAKEFLAGS)' - @echo 'FOO = bar' > $@ +#> @echo 'MAKEFLAGS = $(MAKEFLAGS)' +> @echo 'FOO = bar' > $@ !, "$np -j2", "#MAKE#[1]: warning: -j2 forced in submake: resetting jobserver mode.\nall\n"); @@ -102,8 +103,17 @@ default: ; @ #MAKEPATH# -f Makefile2 rmfiles('Makefile2'); } -1; +# Ensure enter/leave directory messages appear before jobserver warnings -### Local Variables: -### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action)) -### End: +run_make_test(q! +all: ; @$(MAKE) -C . -f #MAKEFILE# recurse -j1 +recurse: ; @echo hi +!, + '-w -j2', "#MAKE#: Entering directory '#PWD#' +#MAKE#[1]: Entering directory '#PWD#' +#MAKE#[1]: warning: -j1 forced in submake: resetting jobserver mode. +hi +#MAKE#[1]: Leaving directory '#PWD#' +#MAKE#: Leaving directory '#PWD#'\n"); + +1;