[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