From 0ba337c0a41c6245ba204209d7b899dc03767bd6 Mon Sep 17 00:00:00 2001 From: lillo Date: Thu, 18 Jul 2002 13:59:03 +0000 Subject: [PATCH] adding environmental variables support git-svn-id: file:///srv/svn/repos/haiku/trunk/current@304 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/kernel/syscalls.h | 5 ++- headers/os/kernel/thread_types.h | 1 + headers/private/kernel/defines.h | 2 ++ headers/private/kernel/kernel.h | 5 ++- headers/private/kernel/ksyscalls.h | 4 ++- headers/private/kernel/thread.h | 7 ++-- headers/private/kernel/unistd.h | 2 ++ src/kernel/Jamfile | 15 ++++++++ src/kernel/apps/Jamfile | 1 + src/kernel/apps/envtest/Jamfile | 3 ++ src/kernel/apps/envtest/main.c | 57 ++++++++++++++++++++++++++++++ src/kernel/apps/fibo_main.c | 4 +-- src/kernel/apps/init.c | 4 +-- src/kernel/apps/shell/commands.c | 2 +- src/kernel/apps/shell/file_utils.c | 2 +- src/kernel/core/main.c | 3 +- src/kernel/core/syscalls.c | 8 ++++- 17 files changed, 111 insertions(+), 14 deletions(-) create mode 100644 src/kernel/apps/envtest/Jamfile create mode 100644 src/kernel/apps/envtest/main.c diff --git a/headers/os/kernel/syscalls.h b/headers/os/kernel/syscalls.h index a34a5d0aff..611dc87ea3 100755 --- a/headers/os/kernel/syscalls.h +++ b/headers/os/kernel/syscalls.h @@ -65,7 +65,7 @@ int sys_set_sem_owner(sem_id id, proc_id proc); int sys_proc_get_table(struct proc_info *pi, size_t len); void sys_exit(int retcode); -proc_id sys_proc_create_proc(const char *path, const char *name, char **args, int argc, int priority); +proc_id sys_proc_create_proc(const char *path, const char *name, char **args, int argc, char **envp, int envc, int priority); thread_id kern_spawn_thread(int (*func)(void*), const char *, int, void *); thread_id kern_get_current_thread_id(void); @@ -114,6 +114,9 @@ int sys_test_and_set(int *val, int set_to, int test_val); int sys_sysctl(int *, uint, void *, size_t *, void *, size_t); int sys_socket(int, int, int); +int sys_setenv(const char *, const char *, int); +int sys_getenv(const char *, char **); + /* region prototypes */ area_id sys_find_region_by_name(const char *); diff --git a/headers/os/kernel/thread_types.h b/headers/os/kernel/thread_types.h index 09b2bb3d53..a3fe7d5451 100644 --- a/headers/os/kernel/thread_types.h +++ b/headers/os/kernel/thread_types.h @@ -96,6 +96,7 @@ struct proc { aspace_id _aspace_id; vm_address_space *aspace; vm_address_space *kaspace; + addr user_env_base; struct thread *main_thread; struct thread *thread_list; struct arch_proc arch_info; diff --git a/headers/private/kernel/defines.h b/headers/private/kernel/defines.h index e7323a4b44..69a9b397c5 100755 --- a/headers/private/kernel/defines.h +++ b/headers/private/kernel/defines.h @@ -14,4 +14,6 @@ #define SYS_THREAD_ARG_LENGTH_MAX 255 +#define SYS_THREAD_STRING_LENGTH_MAX 2048 + #endif diff --git a/headers/private/kernel/kernel.h b/headers/private/kernel/kernel.h index 3245042770..8663f08c4d 100644 --- a/headers/private/kernel/kernel.h +++ b/headers/private/kernel/kernel.h @@ -36,7 +36,10 @@ extern "C" { * Size of the stack given to processes */ #define STACK_SIZE (PAGE_SIZE*16) - +/** + * Size of the environmental variables space for a process + */ +#define ENV_SIZE (PAGE_SIZE*8) #define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1)) #define ROUNDOWN(a, b) (((a) / (b)) * (b)) diff --git a/headers/private/kernel/ksyscalls.h b/headers/private/kernel/ksyscalls.h index 0567e73cb2..0bfec6a973 100755 --- a/headers/private/kernel/ksyscalls.h +++ b/headers/private/kernel/ksyscalls.h @@ -86,7 +86,9 @@ enum { SYSCALL_READ_DIR, SYSCALL_REWIND_DIR, SYSCALL_OPEN_DIR, - SYSCALL_CREATE_DIR + SYSCALL_CREATE_DIR, + SYSCALL_SETENV, + SYSCALL_GETENV /* 80 */ }; int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_ret); diff --git a/headers/private/kernel/thread.h b/headers/private/kernel/thread.h index 80676f4964..f63a5c120f 100755 --- a/headers/private/kernel/thread.h +++ b/headers/private/kernel/thread.h @@ -48,7 +48,7 @@ thread_id thread_create_user_thread(char *name, proc_id pid, addr entry, void *a thread_id thread_create_kernel_thread(const char *name, int (*func)(void *args), void *args); struct proc *proc_get_kernel_proc(void); -proc_id proc_create_proc(const char *path, const char *name, char **args, int argc, int priority); +proc_id proc_create_proc(const char *path, const char *name, char **args, int argc, char **envp, int envc, int priority); int proc_kill_proc(proc_id); int proc_wait_on_proc(proc_id id, int *retcode); proc_id proc_get_kernel_proc_id(void); @@ -58,7 +58,7 @@ int user_proc_get_arg_count(void); // used in syscalls.c int user_thread_wait_on_thread(thread_id id, int *uretcode); -proc_id user_proc_create_proc(const char *path, const char *name, char **args, int argc, int priority); +proc_id user_proc_create_proc(const char *path, const char *name, char **args, int argc, char **envp, int envc, int priority); int user_proc_wait_on_proc(proc_id id, int *uretcode); thread_id user_thread_create_user_thread(addr, proc_id, const char*, @@ -69,6 +69,9 @@ int user_proc_get_table(struct proc_info *pi, size_t len); int user_getrlimit(int resource, struct rlimit * rlp); int user_setrlimit(int resource, const struct rlimit * rlp); +int user_setenv(const char *name, const char *value, int overwrite); +int user_getenv(const char *name, char **value); + #if 1 // XXX remove later int thread_test(void); diff --git a/headers/private/kernel/unistd.h b/headers/private/kernel/unistd.h index 62ec8e7217..53ec765271 100755 --- a/headers/private/kernel/unistd.h +++ b/headers/private/kernel/unistd.h @@ -39,6 +39,8 @@ extern int optind; extern int optopt; extern int optreset; +extern char **environ; + off_t lseek(int, off_t, int); ssize_t read(int, void *, size_t); ssize_t pread(int, void *, size_t, off_t); diff --git a/src/kernel/Jamfile b/src/kernel/Jamfile index 1344fe805f..681e53010b 100644 --- a/src/kernel/Jamfile +++ b/src/kernel/Jamfile @@ -312,6 +312,7 @@ KernelStaticLibraryObjects libc.a : <$(SOURCE_GRIST)!libc!stdlib>assert.o <$(SOURCE_GRIST)!libc!stdlib>atoi.o <$(SOURCE_GRIST)!libc!stdlib>bsearch.o + <$(SOURCE_GRIST)!libc!stdlib>env.o <$(SOURCE_GRIST)!libc!stdlib>heapsort.o <$(SOURCE_GRIST)!libc!stdlib>merge.o <$(SOURCE_GRIST)!libc!stdlib>multibyte.o @@ -427,6 +428,7 @@ KernelLd libc.so : <$(SOURCE_GRIST)!libc!stdlib>assert.o <$(SOURCE_GRIST)!libc!stdlib>atoi.o <$(SOURCE_GRIST)!libc!stdlib>bsearch.o + <$(SOURCE_GRIST)!libc!stdlib>env.o <$(SOURCE_GRIST)!libc!stdlib>heapsort.o <$(SOURCE_GRIST)!libc!stdlib>merge.o <$(SOURCE_GRIST)!libc!stdlib>multibyte.o @@ -698,6 +700,19 @@ KernelLd filetest : bin/filetest ; +KernelLd envtest : + libglue2.o + <$(SOURCE_GRIST)!apps!envtest>main.o + libc.so + libm.so + : + $(SUBDIR)/ldscripts/$(OBOS_ARCH)/app.ld + : + : + : + bin/envtest + ; + KernelLd loop : <$(SOURCE_GRIST)!add-ons!net!loopback>loop.o kernel.so diff --git a/src/kernel/apps/Jamfile b/src/kernel/apps/Jamfile index 8a4a43dea2..0e379f30ef 100644 --- a/src/kernel/apps/Jamfile +++ b/src/kernel/apps/Jamfile @@ -12,6 +12,7 @@ SubInclude OBOS_TOP src kernel apps mount ; SubInclude OBOS_TOP src kernel apps ps ; SubInclude OBOS_TOP src kernel apps rld ; SubInclude OBOS_TOP src kernel apps shell ; +SubInclude OBOS_TOP src kernel apps envtest ; #SubInclude OBOS_TOP src kernel apps sockettest ; SubInclude OBOS_TOP src kernel apps testapp ; SubInclude OBOS_TOP src kernel apps testdigit ; diff --git a/src/kernel/apps/envtest/Jamfile b/src/kernel/apps/envtest/Jamfile new file mode 100644 index 0000000000..9221a98e85 --- /dev/null +++ b/src/kernel/apps/envtest/Jamfile @@ -0,0 +1,3 @@ +SubDir OBOS_TOP src kernel apps envtest ; + +KernelObjects <$(SOURCE_GRIST)>main.c : -fpic -Wno-unused ; diff --git a/src/kernel/apps/envtest/main.c b/src/kernel/apps/envtest/main.c new file mode 100644 index 0000000000..7ed90d5875 --- /dev/null +++ b/src/kernel/apps/envtest/main.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + + +int main(int argc, char **argv) +{ + int i, rc; + proc_id pid; + char temp[16]; + char *var; + + printf("Setting some env vars...\n"); + + if (setenv("TEST", "This is a test!", 0)) { + printf("setenv() error\n"); + return -1; + } + if (setenv("HOME", "/boot", 1)) { + printf("setenv() error\n"); + return -1; + } + + printf("Getting VAR_1: "); + var = getenv("VAR_1"); + if (var) + printf("found set to: \"%s\"\n", var); + else + printf("not found\n"); + + printf("List of env variables set:\n"); + for (i=0; environ[i]; i++) + printf("%s\n", environ[i]); + + if (argc > 1) { + char buffer[16]; + char *_argv[] = { argv[0], buffer, NULL }; + int val = atoi(argv[1]) - 1; + + sprintf(temp, "VAR_%d", val); + if (setenv(temp, "dummy", 0)) { + printf("setenv() error\n"); + return -1; + } + + if (val > 0) { + printf("Spawning test (%d left)\n", val); + sprintf(buffer, "%d", val); + pid = sys_proc_create_proc(_argv[0], _argv[0], _argv, 2, NULL, 0, 5); + sys_proc_wait_on_proc(pid, &rc); + } + } + return 0; +} + + diff --git a/src/kernel/apps/fibo_main.c b/src/kernel/apps/fibo_main.c index 207e2a8b0b..11a60d6724 100644 --- a/src/kernel/apps/fibo_main.c +++ b/src/kernel/apps/fibo_main.c @@ -50,12 +50,12 @@ main(int argc, char *argv[]) int aaargc= 3; sprintf(buffer, "%d", num-1); - pid= sys_proc_create_proc(aaargv[0], aaargv[0], aaargv, aaargc, 5); + pid= sys_proc_create_proc(aaargv[0], aaargv[0], aaargv, aaargc, NULL, 0, 5); sys_proc_wait_on_proc(pid, &retcode); result= retcode; sprintf(buffer, "%d", num-2); - pid= sys_proc_create_proc(aaargv[0], aaargv[0], aaargv, aaargc, 5); + pid= sys_proc_create_proc(aaargv[0], aaargv[0], aaargv, aaargc, NULL, 0, 5); sys_proc_wait_on_proc(pid, &retcode); result+= retcode; } diff --git a/src/kernel/apps/init.c b/src/kernel/apps/init.c index a9050dcd93..19dd08407f 100644 --- a/src/kernel/apps/init.c +++ b/src/kernel/apps/init.c @@ -33,7 +33,7 @@ int main() if(1) { proc_id pid; - pid = sys_proc_create_proc("/boot/bin/fortune", "/boot/bin/fortune", NULL, 0, 5); + pid = sys_proc_create_proc("/boot/bin/fortune", "/boot/bin/fortune", NULL, 0, NULL, 0, 5); if (pid >= 0) { int retcode; sys_proc_wait_on_proc(pid, &retcode); @@ -46,7 +46,7 @@ int main() while(1) { proc_id pid; - pid = sys_proc_create_proc("/boot/bin/shell", "/boot/bin/shell", NULL, 0, 5); + pid = sys_proc_create_proc("/boot/bin/shell", "/boot/bin/shell", NULL, 0, NULL, 0, 5); if(pid >= 0) { int retcode; printf("init: spawned shell, pid 0x%x\n", pid); diff --git a/src/kernel/apps/shell/commands.c b/src/kernel/apps/shell/commands.c index a2491562dc..beec283fd3 100644 --- a/src/kernel/apps/shell/commands.c +++ b/src/kernel/apps/shell/commands.c @@ -65,7 +65,7 @@ int cmd_create_proc(int argc,char *argv[]) } } - pid = sys_proc_create_proc(filename,filename, argv, argc, 5); + pid = sys_proc_create_proc(filename,filename, argv, argc, NULL, 0, 5); if(pid >= 0) { int retcode; diff --git a/src/kernel/apps/shell/file_utils.c b/src/kernel/apps/shell/file_utils.c index 0534bb217c..803e7dad47 100644 --- a/src/kernel/apps/shell/file_utils.c +++ b/src/kernel/apps/shell/file_utils.c @@ -71,7 +71,7 @@ int exec_file(int argc,char *argv[],int *retcode) if( !find_file_in_path(argv[0],filename,SCAN_SIZE)) return SHE_FILE_NOT_FOUND; - pid = sys_proc_create_proc(filename,filename, argv, argc, 5); + pid = sys_proc_create_proc(filename,filename, argv, argc, NULL, 0, 5); if(pid < 0) return SHE_CANT_EXECUTE; diff --git a/src/kernel/core/main.c b/src/kernel/core/main.c index a31b40c160..7df1e6f2b3 100644 --- a/src/kernel/core/main.c +++ b/src/kernel/core/main.c @@ -121,7 +121,6 @@ static int main2(void *unused) bus_init(&ka); dev_init(&ka); con_init(&ka); - //net_init_postdev(&ka); #if 0 @@ -147,7 +146,7 @@ static int main2(void *unused) // start the init process { proc_id pid; - pid = proc_create_proc("/boot/bin/init", "init", NULL, 0, 5); + pid = proc_create_proc("/boot/bin/init", "init", NULL, 0, NULL, 0, 5); if(pid < 0) kprintf("error starting 'init' error = %d \n",pid); } diff --git a/src/kernel/core/syscalls.c b/src/kernel/core/syscalls.c index f5e86b25f9..f8b5ddafea 100644 --- a/src/kernel/core/syscalls.c +++ b/src/kernel/core/syscalls.c @@ -143,7 +143,7 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re *call_ret = 0; break; case SYSCALL_PROC_CREATE_PROC: - *call_ret = user_proc_create_proc((const char *)arg0, (const char *)arg1, (char **)arg2, (int )arg3, (int)arg4); + *call_ret = user_proc_create_proc((const char *)arg0, (const char *)arg1, (char **)arg2, (int)arg3, (char **)arg4, (int)arg5, (int)arg6); break; case SYSCALL_THREAD_WAIT_ON_THREAD: *call_ret = user_thread_wait_on_thread((thread_id)arg0, (int *)arg1); @@ -301,6 +301,12 @@ int syscall_dispatcher(unsigned long call_num, void *arg_buffer, uint64 *call_re // or just call vfs_getrlimit() *call_ret = (get_current_io_context(false))->table_size; break; + case SYSCALL_SETENV: + *call_ret = user_setenv((const char *)arg0, (const char *)arg1, (int)arg2); + break; + case SYSCALL_GETENV: + *call_ret = user_getenv((const char *)arg0, (char **)arg1); + break; default: *call_ret = -1; }