[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH 7/7] argv über PPB übergeben
* libc: Die Argumente von neu gestarteten Programmen werden jetzt in
einem PPB statt in der Kommandozeile übergeben
* init: Angepasst, um Programme mit PPB starten zu können
* Pascal-RTL: argv wird jetzt aus dem PPB ausgelesen
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
src/modules/include/init.h | 1 +
src/modules/init/init.c | 76 ++++++++++++++++++++----------------
src/modules/init/loader.c | 7 +++-
src/modules/lib/init.c | 32 +++++++++++++--
src/modules/lib/param.c | 16 ++++++++
src/modules/pas/lib/prt0.asm | 17 +++++++-
src/modules/pas/lib/rtl/system.pas | 61 +++++++----------------------
7 files changed, 122 insertions(+), 88 deletions(-)
diff --git a/src/modules/include/init.h b/src/modules/include/init.h
index eb29b3a..4bd3ebd 100644
--- a/src/modules/include/init.h
+++ b/src/modules/include/init.h
@@ -44,6 +44,7 @@ char *init_service_get_name(pid_t pid);
void init_process_exit(int result);
pid_t init_execute(const char* cmd);
+pid_t init_execv(const char* file, const char* const argv[]);
int ppb_from_argv(const char* const argv[]);
int cmdline_get_argc(const char* args);
diff --git a/src/modules/init/init.c b/src/modules/init/init.c
index 573bccd..384b151 100644
--- a/src/modules/init/init.c
+++ b/src/modules/init/init.c
@@ -76,8 +76,9 @@ void rpc_dev_list(pid_t pid, uint32_t cid, size_t size, void* data);
void load_modules(init_module_list_t* modules);
pid_t load_single_module(void* image, size_t image_size, char* args,
- pid_t parent_pid) ;
-pid_t start_program(char* path, char* args, pid_t parent_pid);
+ pid_t parent_pid, int ppb_shm_id);
+static pid_t start_program(const char* path, char* args, pid_t parent_pid,
+ int shm);
extern void init_sync_messages(void);
struct service_s* get_service_by_name(const char* name);
@@ -355,7 +356,7 @@ void load_modules(init_module_list_t* modules)
{
//printf("Modul %d: %s\n", i, modules->modules[i].cmdline);
load_single_module((Elf32_Ehdr*) modules->modules[i].start,
- modules->modules[i].size, modules->modules[i].cmdline, 0);
+ modules->modules[i].size, modules->modules[i].cmdline, 0, 0);
mem_free(modules->modules[i].start, modules->modules[i].size);
//msleep(50); // Damit die Meldungen nicht durcheinandergeraten
}
@@ -436,7 +437,8 @@ size_t ainflate(void* src, size_t len, void** dest_ptr)
return ret;
}
-pid_t start_program(char* path, char* args, pid_t parent_pid)
+static pid_t start_program(const char* path, char* args, pid_t parent_pid,
+ int shm)
{
pid_t pid;
FILE* f = fopen(path, "r");
@@ -479,10 +481,13 @@ pid_t start_program(char* path, char* args, pid_t parent_pid)
{
/* Skript: Interpreter aufrufen */
char interpreter[256];
- char* new_path;
- char* new_args;
+ char* interp_args;
+ int ppb_argc, interp_argc, argc;
int ret;
size_t i;
+ struct proc_param_block* ppb;
+ size_t ppb_size;
+ int new_shm;
fgets(interpreter, 256, f);
fclose(f);
@@ -496,14 +501,29 @@ pid_t start_program(char* path, char* args, pid_t parent_pid)
return false;
}
- asprintf(&new_args, "%s%s%s",
- interpreter + 2,
- args ? " " : "",
- args ? args : "");
- new_path = strtok(interpreter + 2, " ");
+ interp_args = interpreter + 2;
+
+ ppb = open_shared_memory(shm);
+ if (ppb == NULL) {
+ return false;
+ }
+ ppb_size = PAGE_SIZE; // FIXME
+
+ ppb_argc = ppb_get_argc(ppb, ppb_size);
+ interp_argc = cmdline_get_argc(interp_args);
+ argc = ppb_argc + interp_argc;
+
+ const char* argv[argc + 1];
+
+ cmdline_copy_argv(interp_args, argv, interp_argc);
+ ppb_copy_argv(ppb, ppb_size, (char**) argv + interp_argc, ppb_argc);
+ argv[argc] = NULL;
+
+ new_shm = ppb_from_argv(argv);
+ ret = start_program(argv[0], args, parent_pid, new_shm);
+ close_shared_memory(new_shm);
+ close_shared_memory(shm);
- ret = start_program(new_path, new_args, parent_pid);
- free(new_args);
return ret;
}
else
@@ -514,7 +534,7 @@ pid_t start_program(char* path, char* args, pid_t parent_pid)
}
fclose(f);
- pid = load_single_module(buffer, buffer_size, args, parent_pid);
+ pid = load_single_module(buffer, buffer_size, args, parent_pid, shm);
free(buffer);
return pid;
}
@@ -522,33 +542,21 @@ pid_t start_program(char* path, char* args, pid_t parent_pid)
void rpc_loadelf(pid_t pid, uint32_t correlation_id, size_t data_size, void* data)
{
- char* first_space;
pid_t new_pid;
+ size_t fn_len;
+ int shm;
- // Wir erwarten einen Null-terminierten String
- if (strnlen(data, data_size) == data_size) {
+ // Wir erwarten einen Null-terminierten String und einen Integer
+ fn_len = strnlen(data, data_size);
+
+ if (data_size < fn_len + sizeof(int) + 1) {
rpc_send_dword_response(pid, correlation_id, 0);
return;
}
+ shm = *(int*)((uintptr_t) data + fn_len + 1);
- first_space = strchr(data, ' ');
-
- //Wenn kein leerschlag vorhanden ist, muessen keine Kommandozeilenargumente
- //abgetrennt werden.
- if (first_space == NULL) {
- new_pid = start_program(data, data, pid);
- } else {
- //Sonst wird erst der Name rauskopiert
- size_t filename_length = (uint32_t) first_space - (uint32_t) data;
- char* filename = malloc(filename_length + 1);
- memcpy(filename, data, filename_length);
- filename[filename_length] = '\0';
-
- new_pid = start_program(filename, data, pid);
-
- free(filename);
- }
+ new_pid = start_program(data, data, pid, shm);
rpc_send_dword_response(pid, correlation_id, new_pid);
}
diff --git a/src/modules/init/loader.c b/src/modules/init/loader.c
index 3a5fdea..3f440ca 100644
--- a/src/modules/init/loader.c
+++ b/src/modules/init/loader.c
@@ -99,7 +99,7 @@ bool loader_create_thread(pid_t process, vaddr_t address)
* Erstellt einen neuen Prozess aus einer ELF-Datei
*/
pid_t load_single_module(void* image, size_t image_size, char* args,
- pid_t parent_pid)
+ pid_t parent_pid, int ppb_shm_id)
{
p();
lock(&loader_state.lock);
@@ -110,6 +110,11 @@ pid_t load_single_module(void* image, size_t image_size, char* args,
loader_state.pid = 0;
goto fail;
}
+
+ if (ppb_shm_id) {
+ init_child_ppb(loader_state.pid, ppb_shm_id);
+ }
+
unblock_process(loader_state.pid);
fail:
diff --git a/src/modules/lib/init.c b/src/modules/lib/init.c
index ea0a7d2..2edad3e 100644
--- a/src/modules/lib/init.c
+++ b/src/modules/lib/init.c
@@ -99,9 +99,12 @@ void init_process_exit(int result)
}
/**
+ * Startet einen neuen Prozess
*
+ * @param cmd Dateiname des zu startenden Programms
+ * @param ppb_shm_id ID des SHM, der den Process Parameter Block enthaelt
*/
-pid_t init_execute(const char* cmd)
+pid_t __init_exec(const char* cmd, int ppb_shm_id)
{
pid_t pid;
@@ -161,11 +164,10 @@ pid_t init_execute(const char* cmd)
// Ansonsten wird jetzt der ganze Befehl in einen Puffer kopiert
size_t abs_path_len = strlen(abs_path);
- size_t args_len = strlen(cmd + program_len);
- size_t rpc_size = abs_path_len + args_len + 1;
+ size_t rpc_size = abs_path_len + sizeof(int) + 1;
char rpc_data[rpc_size];
strcpy(rpc_data, abs_path);
- strcpy(rpc_data + abs_path_len, cmd + program_len);
+ *(int*)(rpc_data + abs_path_len + 1) = ppb_shm_id;
free(abs_path);
// TODO: Relative Pfade
@@ -215,6 +217,28 @@ void cmdline_copy_argv(char* args, const char** argv, size_t argc)
argv[argc] = NULL;
}
+pid_t init_execute(const char* args)
+{
+ int argc;
+ char* s;
+ int ret;
+
+ /* Zunaechst die Argumente zaehlen. */
+ argc = cmdline_get_argc(args);
+
+ /* Jetzt argv anlegen und befuellen */
+ const char* argv[argc + 1];
+
+ s = strdup(args);
+ cmdline_copy_argv(s, argv, argc);
+
+ /* Und den Prozess starten */
+ ret = init_execv(args, argv);
+ free(s);
+
+ return ret;
+}
+
int init_dev_register(struct init_dev_desc* dev, size_t size)
{
return rpc_get_int(1, "DEV_REG ", size, (char*) dev);
diff --git a/src/modules/lib/param.c b/src/modules/lib/param.c
index c3a4f60..1267216 100644
--- a/src/modules/lib/param.c
+++ b/src/modules/lib/param.c
@@ -193,6 +193,22 @@ int ppb_from_argv(const char* const argv[])
return shm;
}
+pid_t init_execv(const char* file, const char* const argv[])
+{
+ int shm;
+ pid_t ret;
+
+ shm = ppb_from_argv(argv);
+ if (shm == -1) {
+ return -1;
+ }
+
+ ret = __init_exec(file, shm);
+ close_shared_memory(shm);
+
+ return ret;
+}
+
bool ppb_is_valid(struct proc_param_block* ppb, size_t ppb_size)
{
size_t offset;
diff --git a/src/modules/pas/lib/prt0.asm b/src/modules/pas/lib/prt0.asm
index 8aff18a..4570d62 100644
--- a/src/modules/pas/lib/prt0.asm
+++ b/src/modules/pas/lib/prt0.asm
@@ -1,13 +1,24 @@
; startup
extern PASCALMAIN
-global _start
section .text
+global _start
_start:
+ mov [__ppb_shm_id], eax
+ mov [__ppb_ptr], ebx
+ mov [__ppb_size], ecx
call PASCALMAIN
hlt
-
+
section .data
-
+
section .bss
+
+global __ppb_size
+global __ppb_ptr
+global __ppb_shm_id
+
+__ppb_size: resd 1
+__ppb_ptr: resd 1
+__ppb_shm_id: resd 1
diff --git a/src/modules/pas/lib/rtl/system.pas b/src/modules/pas/lib/rtl/system.pas
index 92701ea..1cc5d7b 100644
--- a/src/modules/pas/lib/rtl/system.pas
+++ b/src/modules/pas/lib/rtl/system.pas
@@ -58,6 +58,11 @@ procedure DisableFlushing(var f: Text);
implementation
+var
+ ppb_size: integer; external name '__ppb_size';
+ ppb_ptr: Pointer; external name '__ppb_ptr';
+ ppb_shm_id: integer; external name '__ppb_shm_id';
+
procedure InitMessaging; cdecl; external name 'init_messaging';
procedure InitEnvironment; cdecl; external name 'init_envvars';
procedure InitWaitpid; cdecl; external name 'init_waitpid';
@@ -96,7 +101,7 @@ end;
{ number of args }
function paramcount : longint;
begin
- paramcount := argc;
+ paramcount := argc - 1;
end;
{ argument number l }
@@ -105,23 +110,7 @@ var
p: PChar;
begin
if (l >= 0) and (l <= argc) then begin
- (*paramstr := StrPas(argv[l])*)
- p := commandline;
- while (l > 0) and (p^ <> #0) do begin
- if p^ = ' ' then begin
- Dec(l);
- while (p+1)^ = ' ' do begin
- Inc(p);
- end;
- end;
- Inc(p);
- end;
-
- paramstr := '';
- while not (p^ in [' ', #0]) do begin
- paramstr := paramstr + p^;
- Inc(p);
- end;
+ paramstr := StrPas(argv[l]);
end else begin
paramstr := '';
end;
@@ -223,41 +212,21 @@ begin
OpenStdIO(StdErr, fmOutput, StdErrorHandle);
end;
+function ppb_get_argc(ppb: Pointer; size: integer): integer;
+ cdecl; external name 'ppb_get_argc';
+procedure ppb_copy_argv(ppb: Pointer; size: integer; argv: PPChar; argc: integer);
+ cdecl; external name 'ppb_copy_argv';
+
procedure InitParams;
var
i: integer;
p: PChar;
space: boolean;
begin
- commandline := GetCmdline();
-
- p := commandline;
- argc := 0;
- space := false;
- while p^ <> #0 do begin
- if p^ = ' ' then begin
- space := true;
- end else if space then begin
- space := false;
- Inc(argc);
- end;
-
- Inc(p);
- end;
+ argc := ppb_get_argc(ppb_ptr, ppb_size);
- (*argv := GetMem((argc + 1) * sizeof(PChar));
-
- p := cmdline;
- argv^ := p;
- i := 1;
- while p^ <> #0 do begin
- if p^ = ' ' then begin
- (argv + i)^ := p;
- Inc(i);
- end;
-
- Inc(p);
- end;*)
+ argv := GetMem((argc + 1) * sizeof(PChar));
+ ppb_copy_argv(ppb_ptr, ppb_size, argv, argc);
end;
Begin
--
1.6.0.2