Hi, With the current m4 from git (branch-1.4), several tests fail on FreeBSD 13 and AIX 7.1 and 7.2, indicating that the syscmd built-in is completely dysfunctional there:
$ gmake check Checking ../../checks/001.preprocess Checking ../../checks/002.debugging_ Checking ../../checks/003.command_li Checking ../../checks/004.command_li Checking ../../checks/005.command_li @ ../doc/m4.texi:991: Origin of test ../../checks/005.command_li: stdout mismatch --- m4-tmp.12976316/m4-xout 2022-09-22 11:14:37.000000000 -0700 +++ m4-tmp.12976316/m4-out 2022-09-22 11:14:37.000000000 -0700 @@ -1 +1 @@ - 1 + 127 ... Failed checks were: ../../checks/005.command_li:out ../../checks/006.command_li:out ../../checks/006.command_li:err ../../checks/007.command_li:out ../../checks/007.command_li:err ../../checks/145.diversions:out ../../checks/145.diversions:err ../../checks/194.syscmd:out ../../checks/194.syscmd:err ../../checks/195.syscmd:err ../../checks/196.esyscmd:out ../../checks/196.esyscmd:err ../../checks/197.sysval:out ../../checks/197.sysval:err ../../checks/199.mkstemp:out ../../checks/199.mkstemp:err ../../checks/200.mkstemp:out ../../checks/200.mkstemp:err ../../checks/201.mkstemp:out ../../checks/201.mkstemp:err ../../checks/209.using_froz:out ../../checks/209.using_froz:err The problem can be reproduced interactively: $ src/m4 syscmd(`echo') echo: --: not found. m4: syscmd subprocess failed What happens, is that this invokes "sh -c -- echo". Which does not work. See: $ sh -c -- echo echo: --: not found $ sh -c -- pwd pwd: --: not found $ sh -c -- foobar foobar: --: not found On Solaris 10, /bin/sh has the same problem, but the configuration of m4 sets SYSCMD_SHELL = "/usr/xpg4/bin/sh", thus working around the problem in an elegant way. On FreeBSD, bash may or may not be installed as /usr/local/bin/bash (part of the ports collection). On AIX, bash may or may not be installed as /usr/bin/bash (part of the Bull Freeware ports). This is a regression, caused by the commit from 2021-11-19 with title "syscmd: Allow commands with leading - or +". Find attached a patch that limits the new behaviour to the commands that actually start with - or +. With this, the set of failed tests shrinks to Failed checks were: ../../checks/006.command_li:err ../../checks/196.esyscmd:out ../../checks/196.esyscmd:err ../../checks/197.sysval:out ../../checks/197.sysval:err ../../checks/198.sysval:out ../../checks/198.sysval:err ../../checks/199.mkstemp:err The added line prog_args[slot + 1] = NULL; is currently technically a nop, but makes the code more future-proof (in case more variation is needed in the prog_args array in the future). Bruno
>From b331bbaf4eb0581fce24f078561283e3616398f8 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Fri, 23 Sep 2022 02:36:48 +0200 Subject: [PATCH] syscmd: Make it work again for most commands on FreeBSD and AIX. * src/builtin.c (m4_syscmd): Use "sh -c -- $cmd" only if $cmd starts with '-' or '+'. --- src/builtin.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/builtin.c b/src/builtin.c index 0715a332..0180d625 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -947,7 +947,7 @@ m4_syscmd (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv) const char *cmd = ARG (1); int status; int sig_status; - int slot = 3; + int slot; const char *prog_args[5] = { "sh", "-c", "--" }; if (bad_argc (argv[0], argc, 2, 2) || !*cmd) { @@ -964,8 +964,23 @@ m4_syscmd (struct obstack *obs MAYBE_UNUSED, int argc, token_data **argv) prog_args[1] = "/c"; slot = 2; } + else #endif + { + if (cmd[0] == '-' || cmd[0] == '+') + /* If cmd starts with '-' or '+', "sh -c $cmd" is not guaranteed to + work. In this case, use "sh -c -- $cmd". + Note: This requires a POSIX compliant SYSCMD_SHELL. It does not + work with /bin/sh on FreeBSD 13 and AIX 7, and on these platforms + 'bash' is not guaranteed to be installed. */ + slot = 3; + else + /* For most commands, the traditional "sh -c $cmd" works fine. + Including on FreeBSD 13 and AIX 7. */ + slot = 2; + } prog_args[slot] = cmd; + prog_args[slot + 1] = NULL; errno = 0; status = execute (ARG (0), SYSCMD_SHELL, prog_args, NULL, false, false, false, false, true, false, &sig_status); -- 2.34.1