From: Masahiro Yamada <masahiroy@kernel.org>
To: linux-kbuild@vger.kernel.org
Cc: Nick Desaulniers <ndesaulniers@google.com>,
Alexandre Belloni <alexandre.belloni@bootlin.com>,
Randy Dunlap <rdunlap@infradead.org>,
Richard Purdie <richard.purdie@linuxfoundation.org>,
Masahiro Yamada <masahiroy@kernel.org>,
Jonathan Corbet <corbet@lwn.net>,
Michal Marek <michal.lkml@markovi.net>,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 2/3] kconfig: allow to choose the shell for $(shell ) functions
Date: Fri, 19 Aug 2022 15:56:02 +0900 [thread overview]
Message-ID: <20220819065604.295572-3-masahiroy@kernel.org> (raw)
In-Reply-To: <20220819065604.295572-1-masahiroy@kernel.org>
GNU Make uses /bin/sh by default for running recipe lines and $(shell )
functions. You can change the shell by setting the 'SHELL' variable.
Unlike most variables, 'SHELL' is never set from the environment. [1]
Currently, Kconfig does not provide any way to change the default shell.
/bin/sh is always used for running $(shell,...) because do_shell() is
implemented by using popen(3).
This commit allows users to change the shell for Kconfig in a similar
way to GNU Make; you can set the 'SHELL' variable in a Kconfig file to
override the default shell. It is not taken from the environment. The
change is effective only for $(shell,...) invocations called after the
'SHELL' assignment.
[1]: https://www.gnu.org/software/make/manual/html_node/Choosing-the-Shell.html
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---
.../kbuild/kconfig-macro-language.rst | 4 ++
scripts/kconfig/internal.h | 1 +
scripts/kconfig/parser.y | 1 +
scripts/kconfig/preprocess.c | 65 +++++++++++++++----
4 files changed, 57 insertions(+), 14 deletions(-)
diff --git a/Documentation/kbuild/kconfig-macro-language.rst b/Documentation/kbuild/kconfig-macro-language.rst
index 6163467f6ae4..fe8c6982179e 100644
--- a/Documentation/kbuild/kconfig-macro-language.rst
+++ b/Documentation/kbuild/kconfig-macro-language.rst
@@ -112,6 +112,10 @@ Kconfig currently supports the following built-in functions.
replaced with a space. Any trailing newlines are deleted. The standard error
is not returned, nor is any program exit status.
+ The program used as the shell is taken from the variable SHELL. If it is not
+ set anywhere in your Kconfig file, /bin/sh is used as the shell.
+ Unlike most variables, the variable SHELL is never set from the environment.
+
- $(info,text)
The "info" function takes a single argument and prints it to stdout.
diff --git a/scripts/kconfig/internal.h b/scripts/kconfig/internal.h
index 8e0e6d315b6c..c18017650e54 100644
--- a/scripts/kconfig/internal.h
+++ b/scripts/kconfig/internal.h
@@ -19,6 +19,7 @@ enum variable_flavor {
void env_write_dep(FILE *f, const char *auto_conf_name);
void variable_add(const char *name, const char *value,
enum variable_flavor flavor);
+void variable_init(void);
void variable_all_del(void);
char *expand_dollar(const char **str);
char *expand_one_token(const char **str);
diff --git a/scripts/kconfig/parser.y b/scripts/kconfig/parser.y
index 2af7ce4e1531..436afaef9228 100644
--- a/scripts/kconfig/parser.y
+++ b/scripts/kconfig/parser.y
@@ -483,6 +483,7 @@ void conf_parse(const char *name)
zconf_initscan(name);
_menu_init();
+ variable_init();
if (getenv("ZCONF_DEBUG"))
yydebug = 1;
diff --git a/scripts/kconfig/preprocess.c b/scripts/kconfig/preprocess.c
index aeb3fe362c04..608a84e7f5d6 100644
--- a/scripts/kconfig/preprocess.c
+++ b/scripts/kconfig/preprocess.c
@@ -8,6 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "list.h"
#include "lkc.h"
@@ -141,24 +142,59 @@ static char *do_lineno(int argc, char *argv[])
static char *do_shell(int argc, char *argv[])
{
- FILE *p;
+ int pipefd[2];
+ pid_t pid;
char buf[4096];
- char *cmd;
- size_t nread;
+ ssize_t nread;
int i;
- cmd = argv[0];
-
- p = popen(cmd, "r");
- if (!p) {
- perror(cmd);
+ if (pipe(pipefd) < 0) {
+ perror("pipe");
+ exit(1);
+ }
+ pid = fork();
+ if (pid < -1) {
+ perror("fork");
exit(1);
}
- nread = fread(buf, 1, sizeof(buf), p);
+ if (pid == 0) { /* child */
+ char *shell;
+
+ /* duplicate the write end to stdout */
+ if (dup2(pipefd[1], STDOUT_FILENO) < 0) {
+ perror("dup2");
+ _exit(1);
+ }
+
+ /*
+ * Do not leak file descriptors to the child process
+ * (including the read end of the pipe).
+ * Closing up to 15 is enough for us?
+ */
+ for (i = STDERR_FILENO + 1; i < 16; i++)
+ close(i);
+
+ shell = expand_string("$(SHELL)");
+
+ execl(shell, shell, "-c", argv[0], NULL);
+ perror("execl");
+
+ free(shell);
+
+ _exit(1);
+ }
+
+ /* parent */
+
+ close(pipefd[1]); /* the write end is unneeded */
+
+ nread = read(pipefd[0], buf, sizeof(buf));
if (nread == sizeof(buf))
nread--;
+ close(pipefd[0]); /* now close the read end */
+
/* remove trailing new lines */
while (nread > 0 && buf[nread - 1] == '\n')
nread--;
@@ -171,11 +207,6 @@ static char *do_shell(int argc, char *argv[])
buf[i] = ' ';
}
- if (pclose(p) == -1) {
- perror(cmd);
- exit(1);
- }
-
return xstrdup(buf);
}
@@ -330,6 +361,12 @@ static void variable_del(struct variable *v)
free(v);
}
+void variable_init(void)
+{
+ /* Set the default shell */
+ variable_add("SHELL", "/bin/sh", VAR_RECURSIVE);
+}
+
void variable_all_del(void)
{
struct variable *v, *tmp;
--
2.34.1
next prev parent reply other threads:[~2022-08-19 6:58 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-19 6:56 [RFC PATCH 0/3] kbuild: change the default shell to bash Masahiro Yamada
2022-08-19 6:56 ` Masahiro Yamada [this message]
2022-08-19 8:58 ` [RFC PATCH 2/3] kconfig: allow to choose the shell for $(shell ) functions Bagas Sanjaya
2022-08-19 21:37 ` David Laight
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220819065604.295572-3-masahiroy@kernel.org \
--to=masahiroy@kernel.org \
--cc=alexandre.belloni@bootlin.com \
--cc=corbet@lwn.net \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michal.lkml@markovi.net \
--cc=ndesaulniers@google.com \
--cc=rdunlap@infradead.org \
--cc=richard.purdie@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).