summaryrefslogtreecommitdiff
path: root/src/variable.c
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2022-06-18 20:25:30 -0400
committerPaul Smith <psmith@gnu.org>2022-07-09 10:44:21 -0400
commit98da874c43035a490cdca81331724f233a3d0c9a (patch)
tree1894a4e883fd03ff762dfcfe4357cf1d68de483f /src/variable.c
parent88d6c22a487cc45b6d615d5c055ced5c9d5cb56d (diff)
downloadmake-git-98da874c43035a490cdca81331724f233a3d0c9a.tar.gz
[SV 10593] Export variables to $(shell ...) commands
Export all variables, including exported makefile variables, when invoking a shell for the $(shell ...) function. If we detect a recursive variable expansion, silently ignore that variable and do not export it. We do print a debug message. * NEWS: Announce the potential backward-incompatibility. * doc/make.texi (Shell Function): Document the export behavior. * src/main.c (main): Add "shell-export" to .FEATURES. * src/job.h: New function to free struct childbase. * src/job.c (free_childbase): Implement it; call from free_child. * src/function.c (func_shell_base): Use target_environment() to obtain the proper environment for the shell function. Use free_childbase() to free memory. (windows32_openpipe): Don't reset the environment: the caller already provided a proper PATH variable in envp. * src/variable.c (target_environment): If we detect a recursive expansion and we're called from func_shell, ignore the variable. (sync_Path_environment): Simplify and reduce memory allocation. * tests/scripts/functions/shell: Add tests for this.
Diffstat (limited to 'src/variable.c')
-rw-r--r--src/variable.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/src/variable.c b/src/variable.c
index 3cddfd6d..c53ce5a7 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -19,6 +19,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
#include <assert.h>
#include "filedef.h"
+#include "debug.h"
#include "dep.h"
#include "job.h"
#include "commands.h"
@@ -1099,17 +1100,24 @@ target_environment (struct file *file)
/* If V is recursively expanded and didn't come from the environment,
expand its value. If it came from the environment, it should
go back into the environment unchanged. */
- if (v->recursive
- && v->origin != o_env && v->origin != o_env_override)
+ if (v->recursive && v->origin != o_env && v->origin != o_env_override)
{
- char *value = recursively_expand_for_file (v, file);
+ /* If V is being recursively expanded and this is for a shell
+ function, just skip it. */
+ if (v->expanding && file == NULL)
+ DB (DB_VERBOSE, (_("%s:%lu: Skipping export of %s to shell function due to recursive expansion"),
+ v->fileinfo.filenm, v->fileinfo.lineno, v->name));
+ else
+ {
+ char *value = recursively_expand_for_file (v, file);
#ifdef WINDOWS32
- if (strcmp (v->name, "Path") == 0 ||
- strcmp (v->name, "PATH") == 0)
- convert_Path_to_windows32 (value, ';');
+ if (strcmp (v->name, "Path") == 0 ||
+ strcmp (v->name, "PATH") == 0)
+ convert_Path_to_windows32 (value, ';');
#endif
- *result++ = xstrdup (concat (3, v->name, "=", value));
- free (value);
+ *result++ = xstrdup (concat (3, v->name, "=", value));
+ free (value);
+ }
}
else
{
@@ -1858,21 +1866,20 @@ print_target_variables (const struct file *file)
#ifdef WINDOWS32
void
-sync_Path_environment (void)
+sync_Path_environment ()
{
- char *path = allocated_variable_expand ("$(PATH)");
static char *environ_path = NULL;
+ char *oldpath = environ_path;
+ char *path = allocated_variable_expand ("PATH=$(PATH)");
if (!path)
return;
- /* If done this before, free the previous entry before allocating new one. */
- free (environ_path);
-
- /* Create something WINDOWS32 world can grok. */
+ /* Convert PATH into something WINDOWS32 world can grok. */
convert_Path_to_windows32 (path, ';');
- environ_path = xstrdup (concat (3, "PATH", "=", path));
+
+ environ_path = path;
putenv (environ_path);
- free (path);
+ free (oldpath);
}
#endif