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 int genode_argc;
|
||||||
extern char **genode_envp;
|
extern char **genode_envp;
|
||||||
|
|
||||||
|
/* initial environment for the FreeBSD libc implementation */
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
/* provided by the application */
|
/* provided by the application */
|
||||||
extern "C" int main(int argc, char ** argv, char **envp);
|
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) {
|
env.config([&] (Xml_node const &node) {
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
static char **argv;
|
int envc = 0;
|
||||||
|
char **argv;
|
||||||
|
char **envp;
|
||||||
|
|
||||||
/* count the number of arguments */
|
/* count the number of arguments and environment variables */
|
||||||
node.for_each_sub_node("arg", [&] (Xml_node const &arg_node) {
|
node.for_each_sub_node([&] (Xml_node const &node) {
|
||||||
/* check if the 'value' attribute exists */
|
/* check if the 'value' attribute exists */
|
||||||
if (arg_node.has_attribute("value"))
|
if (node.has_type("arg") && node.has_attribute("value"))
|
||||||
++argc;
|
++argc;
|
||||||
|
else
|
||||||
|
if (node.has_type("env") && node.has_attribute("key") && node.has_attribute("value"))
|
||||||
|
++envc;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0 && envc == 0)
|
||||||
return;
|
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 */
|
/* read the arguments */
|
||||||
int i = 0;
|
int arg_i = 0;
|
||||||
node.for_each_sub_node("arg", [&] (Xml_node const &arg_node) {
|
int env_i = 0;
|
||||||
try {
|
node.for_each_sub_node([&] (Xml_node const &node) {
|
||||||
Xml_attribute attr = arg_node.attribute("value");
|
/* 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;
|
Genode::size_t const arg_len = attr.value_size()+1;
|
||||||
argv[i] = (char*)malloc(arg_len);
|
char *arg = argv[arg_i] = (char*)malloc(arg_len);
|
||||||
attr.value(argv[i], arg_len);
|
|
||||||
++i;
|
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) { }
|
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||||
});
|
});
|
||||||
|
|
||||||
argv[i] = nullptr;
|
envp[env_i] = NULL;
|
||||||
|
|
||||||
/* register command-line arguments at Genode's startup code */
|
/* register command-line arguments at Genode's startup code */
|
||||||
genode_argc = argc;
|
genode_argc = argc;
|
||||||
genode_argv = argv;
|
genode_argv = argv;
|
||||||
|
genode_envp = environ = envp;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* TODO: environment variables, see #2236 */
|
|
||||||
|
|
||||||
exit(main(genode_argc, genode_argv, genode_envp));
|
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
|
||||||
noux_net_netcat
|
noux_net_netcat
|
||||||
libc_ffat
|
libc_ffat
|
||||||
|
libc_getenv
|
||||||
libc_pipe
|
libc_pipe
|
||||||
libc_vfs
|
libc_vfs
|
||||||
libc_vfs_ram
|
libc_vfs_ext2
|
||||||
libc_vfs_fs
|
libc_vfs_fs
|
||||||
|
libc_vfs_ram
|
||||||
timed_semaphore
|
timed_semaphore
|
||||||
signal
|
signal
|
||||||
sub_rm
|
sub_rm
|
||||||
@ -41,7 +43,6 @@ part_blk
|
|||||||
xml_generator
|
xml_generator
|
||||||
blk_cache
|
blk_cache
|
||||||
rump_ext2
|
rump_ext2
|
||||||
libc_vfs_ext2
|
|
||||||
thread
|
thread
|
||||||
pthread
|
pthread
|
||||||
vbox_auto_win7
|
vbox_auto_win7
|
||||||
|
Loading…
Reference in New Issue
Block a user