On Wed, Dec 29 14:12, Kevin Wolf wrote: > * 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 Wäre der letzte Punkt nicht eher was für einen separaten Pätsch? > > 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 Was gehoert denn hier in richtig hin? Ein shm_size-Syscall? > + > + 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); Hier vielleicht noch etwas Fehlerbehandlung? > > - (*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 Weiter fällt mir auf, dass die crt0 noch den Code für ohne PPB enthält, aber prt0 nicht. Hat das irgend einen konkreten Grund? ;-) Sonst könnte das wohl etwa hinkommen, glaube ich. -- Antoine Kaufmann <toni@xxxxxxxxxxxxxxxx>
Attachment:
pgp9_tN38mhuw.pgp
Description: PGP signature