chiark / gitweb /
systemd-activate: pass environment variables through
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 15 Mar 2013 22:57:44 +0000 (18:57 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 16 Mar 2013 02:55:24 +0000 (22:55 -0400)
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())'

man/systemd-activate.xml
src/activate/activate.c

index a5cab8e3b702acb0ef2e1f5cfb22137754083394..b62cf44ec4e96d93c53637039fb824c4cd9aea8e 100644 (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
+        variable–value pair. Otherwise obtain the value from the
+        environment of <command>systemd-activate</command> itself.
+        </para></listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
index 7fcb0a97c495df868eedbf95b2cb904ad101d724..be40be48a453855d9522ae1f8e6df0ce5ba9625b 100644 (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;