systemd-activate: pass environment variables through

I need this to test half-installed socket-activated python
script, which requires PYTHONPATH and LD_LIBRARY_PATH set.
I assume that other people might find it useful to.

-E VAR passes through VAR from the environment, while
-E VAR=value sets VAR=value.

systemd-activate -E PYTHONPATH=/var/tmp/inst1/usr/lib64/python3.3/site-packages -E LD_LIBRARY_PATH=/var/tmp/inst1/usr/lib -l 2000 python3 -c 'from systemd.daemon import listen_fds; print(listen_fds())'
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2013-03-15 18:57:44 -04:00
parent 0f59fe5171
commit 5e65c93a43
2 changed files with 43 additions and 4 deletions

View File

@ -99,7 +99,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
</varlistentry>
<varlistentry>
<term><option>-l</option></term>
<term><option>-l <replaceable>address</replaceable></option></term>
<term><option>--listen=<replaceable>address</replaceable></option></term>
<listitem><para>Listen on this <replaceable>address</replaceable>.
@ -116,6 +116,18 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
connection and pass the connection socket as standard input
and standard output.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-E <replaceable>VAR</replaceable><optional>=<replaceable>VALUE</replaceable></optional></option></term>
<term><option>--environment=<replaceable>VAR</replaceable><optional>=<replaceable>VALUE</replaceable></optional></option></term>
<listitem><para>Add this variable to the environment of the
launched process. If <replaceable>VAR</replaceable> is
followed by <literal>=</literal> assume that it is a
variablevalue pair. Otherwise obtain the value from the
environment of <command>systemd-activate</command> itself.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -38,6 +38,7 @@
static char** arg_listen = NULL;
static bool arg_accept = false;
static char** arg_args = NULL;
static char** arg_environ = NULL;
static int add_epoll(int epoll_fd, int fd) {
int r;
@ -164,12 +165,29 @@ static int open_sockets(int *epoll_fd, bool accept) {
}
static int launch(char* name, char **argv, char **environ, int fds) {
unsigned n_env = 0;
char* envp[7] = {NULL}; /* PATH, TERM, HOME, USER, LISTEN_FDS, LISTEN_PID */
unsigned n_env = 0, length;
char **envp = NULL, **s;
static const char* tocopy[] = {"TERM=", "PATH=", "USER=", "HOME="};
char _cleanup_free_ *tmp = NULL;
unsigned i;
length = strv_length(arg_environ);
/* PATH, TERM, HOME, USER, LISTEN_FDS, LISTEN_PID, NULL */
envp = new(char *, length + 7);
STRV_FOREACH(s, arg_environ) {
if (strchr(*s, '='))
envp[n_env++] = *s;
else {
char _cleanup_free_ *p = strappend(*s, "=");
if (!p)
return log_oom();
envp[n_env] = strv_find_prefix(environ, p);
if (envp[n_env])
n_env ++;
}
}
for (i = 0; i < ELEMENTSOF(tocopy); i++) {
envp[n_env] = strv_find_prefix(environ, tocopy[i]);
if (envp[n_env])
@ -312,6 +330,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "listen", required_argument, NULL, 'l' },
{ "accept", no_argument, NULL, 'a' },
{ "environment", required_argument, NULL, 'E' },
{ NULL, 0, NULL, 0 }
};
@ -320,7 +339,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "+hl:sa", options, NULL)) >= 0)
while ((c = getopt_long(argc, argv, "+hl:saE:", options, NULL)) >= 0)
switch(c) {
case 'h':
help();
@ -343,6 +362,14 @@ static int parse_argv(int argc, char *argv[]) {
arg_accept = true;
break;
case 'E': {
int r = strv_extend(&arg_environ, optarg);
if (r < 0)
return r;
break;
}
case '?':
return -EINVAL;