mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 14:37:50 +00:00
lib/posix: populate environment variables from config
Parse ``<env key="..." value=".."/>`` nodes from the config ROM and populate a list at the 'genode_envp' and 'environ' symbols. Test script at run/libc_getenv. Fix #2236
This commit is contained in:
parent
7f7f8063dd
commit
9b3ecb114d
53
repos/libports/run/libc_getenv.run
Normal file
53
repos/libports/run/libc_getenv.run
Normal file
@ -0,0 +1,53 @@
|
||||
build "core init drivers/timer test/libc_getenv"
|
||||
|
||||
create_boot_directory
|
||||
|
||||
install_config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="RAM"/>
|
||||
<service name="RM"/>
|
||||
<service name="ROM"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="test-libc_getenv">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<config>
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
<libc stdout="/dev/log"/>
|
||||
<arg value="test-libc_getenv"/>
|
||||
<arg value="foo"/>
|
||||
<arg value="bar"/>
|
||||
<arg value="baz"/>
|
||||
<env key="foo" value="bar"/>
|
||||
<env key="bar" value="foo"/>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
build_boot_image {
|
||||
core init timer test-libc_getenv
|
||||
ld.lib.so libc.lib.so libm.lib.so
|
||||
}
|
||||
|
||||
append qemu_args " -nographic -m 64 "
|
||||
|
||||
run_genode_until "child .* exited with exit value 0.*\n" 10
|
||||
|
||||
grep_output {\[init -\> test-libc_getenv\]}
|
||||
|
||||
compare_output_to {
|
||||
[init -> test-libc_getenv] foo="bar"
|
||||
[init -> test-libc_getenv] bar="foo"
|
||||
[init -> test-libc_getenv] baz="(null)"
|
||||
}
|
@ -22,6 +22,8 @@ extern char **genode_argv;
|
||||
extern int genode_argc;
|
||||
extern char **genode_envp;
|
||||
|
||||
/* initial environment for the FreeBSD libc implementation */
|
||||
extern char **environ;
|
||||
|
||||
/* provided by the application */
|
||||
extern "C" int main(int argc, char ** argv, char **envp);
|
||||
@ -34,40 +36,72 @@ void Libc::Component::construct(Libc::Env &env)
|
||||
|
||||
env.config([&] (Xml_node const &node) {
|
||||
int argc = 0;
|
||||
static char **argv;
|
||||
int envc = 0;
|
||||
char **argv;
|
||||
char **envp;
|
||||
|
||||
/* count the number of arguments */
|
||||
node.for_each_sub_node("arg", [&] (Xml_node const &arg_node) {
|
||||
/* count the number of arguments and environment variables */
|
||||
node.for_each_sub_node([&] (Xml_node const &node) {
|
||||
/* check if the 'value' attribute exists */
|
||||
if (arg_node.has_attribute("value"))
|
||||
if (node.has_type("arg") && node.has_attribute("value"))
|
||||
++argc;
|
||||
else
|
||||
if (node.has_type("env") && node.has_attribute("key") && node.has_attribute("value"))
|
||||
++envc;
|
||||
});
|
||||
|
||||
if (argc == 0)
|
||||
return;
|
||||
if (argc == 0 && envc == 0)
|
||||
return; /* from lambda */
|
||||
|
||||
argv = (char**)malloc((argc + 1) * sizeof(char*));
|
||||
/* arguments and environment are a contiguous array (but don't count on it) */
|
||||
argv = (char**)malloc((argc + envc + 1) * sizeof(char*));
|
||||
envp = &argv[argc];
|
||||
|
||||
/* read the arguments */
|
||||
int i = 0;
|
||||
node.for_each_sub_node("arg", [&] (Xml_node const &arg_node) {
|
||||
try {
|
||||
Xml_attribute attr = arg_node.attribute("value");
|
||||
int arg_i = 0;
|
||||
int env_i = 0;
|
||||
node.for_each_sub_node([&] (Xml_node const &node) {
|
||||
/* insert an argument */
|
||||
if (node.has_type("arg")) try {
|
||||
Xml_attribute attr = node.attribute("value");
|
||||
|
||||
Genode::size_t const arg_len = attr.value_size()+1;
|
||||
argv[i] = (char*)malloc(arg_len);
|
||||
attr.value(argv[i], arg_len);
|
||||
++i;
|
||||
char *arg = argv[arg_i] = (char*)malloc(arg_len);
|
||||
|
||||
attr.value(arg, arg_len);
|
||||
++arg_i;
|
||||
|
||||
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||
|
||||
else
|
||||
|
||||
/* insert an environment variable */
|
||||
if (node.has_type("env")) try {
|
||||
Xml_attribute key_attr = node.attribute("key");
|
||||
Xml_attribute val_attr = node.attribute("value");
|
||||
|
||||
Genode::size_t const pair_len =
|
||||
key_attr.value_size() +
|
||||
val_attr.value_size() + 1;
|
||||
char *env = envp[env_i] = (char*)malloc(pair_len);
|
||||
|
||||
Genode::size_t off = 0;
|
||||
key_attr.value(&env[off], key_attr.value_size()+1);
|
||||
off = key_attr.value_size();
|
||||
env[off++] = '=';
|
||||
val_attr.value(&env[off], val_attr.value_size()+1);
|
||||
++env_i;
|
||||
|
||||
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||
});
|
||||
|
||||
argv[i] = nullptr;
|
||||
envp[env_i] = NULL;
|
||||
|
||||
/* register command-line arguments at Genode's startup code */
|
||||
genode_argc = argc;
|
||||
genode_argv = argv;
|
||||
genode_envp = environ = envp;
|
||||
});
|
||||
|
||||
/* TODO: environment variables, see #2236 */
|
||||
|
||||
exit(main(genode_argc, genode_argv, genode_envp));
|
||||
}
|
||||
|
26
repos/libports/src/test/libc_getenv/main.c
Normal file
26
repos/libports/src/test/libc_getenv/main.c
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Libc getenv(...) test
|
||||
* \author Emery Hemingway
|
||||
* \date 2017-01-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
char const *key = argv[i];
|
||||
printf("%s=\"%s\"\n", key, getenv(key));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
3
repos/libports/src/test/libc_getenv/target.mk
Normal file
3
repos/libports/src/test/libc_getenv/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET = test-libc_getenv
|
||||
SRC_C = main.c
|
||||
LIBS = posix
|
@ -8,10 +8,12 @@ tar_rom
|
||||
noux
|
||||
noux_net_netcat
|
||||
libc_ffat
|
||||
libc_getenv
|
||||
libc_pipe
|
||||
libc_vfs
|
||||
libc_vfs_ram
|
||||
libc_vfs_ext2
|
||||
libc_vfs_fs
|
||||
libc_vfs_ram
|
||||
timed_semaphore
|
||||
signal
|
||||
sub_rm
|
||||
@ -41,7 +43,6 @@ part_blk
|
||||
xml_generator
|
||||
blk_cache
|
||||
rump_ext2
|
||||
libc_vfs_ext2
|
||||
thread
|
||||
pthread
|
||||
vbox_auto_win7
|
||||
|
Loading…
Reference in New Issue
Block a user