On Wed, Dec 29 14:12, Kevin Wolf wrote: > + libc: Funktionen zum Erstellen und zum anschließend Auslesen eines > Prozessparameterblocks > > Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx> > --- > src/modules/include/init.h | 7 + > src/modules/lib/param.c | 264 ++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 271 insertions(+), 0 deletions(-) > create mode 100644 src/modules/lib/param.c > > diff --git a/src/modules/include/init.h b/src/modules/include/init.h > index d431cee..eb29b3a 100644 > --- a/src/modules/include/init.h > +++ b/src/modules/include/init.h > @@ -30,11 +30,13 @@ > > #include <types.h> > #include <stdio.h> > +#include <stdbool.h> > > #define INIT_PID 1 > > extern void stdio_init(void); > > +struct proc_param_block; > > void init_service_register(char* name); > pid_t init_service_get(char* name); > @@ -42,10 +44,15 @@ char *init_service_get_name(pid_t pid); > > void init_process_exit(int result); > pid_t init_execute(const char* cmd); > +int ppb_from_argv(const char* const argv[]); > > int cmdline_get_argc(const char* args); > void cmdline_copy_argv(char* args, const char** argv, size_t argc); > > +bool ppb_is_valid(struct proc_param_block* ppb, size_t ppb_size); > +int ppb_get_argc(struct proc_param_block* ppb, size_t ppb_size); > +void ppb_copy_argv(struct proc_param_block* ppb, size_t ppb_size, > + char** argv, int argc); > > > #ifdef _USE_START_ > diff --git a/src/modules/lib/param.c b/src/modules/lib/param.c > new file mode 100644 > index 0000000..c3a4f60 > --- /dev/null > +++ b/src/modules/lib/param.c > @@ -0,0 +1,264 @@ > +/* > + * Copyright (c) 2010 The tyndur Project. All rights reserved. > + * > + * This code is derived from software contributed to the tyndur Project > + * by Kevin Wolf. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR > + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR > + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, > + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, > + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; > + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <stdlib.h> > +#include <string.h> > +#include <errno.h> > + > +#include <syscall.h> > +#include <page.h> > + > +enum ppb_entry_type { > + PPB_CMDLINE_ARG = 1, > + PPB_ENV_VAR, > +}; > + > +struct ppb_entry { > + enum ppb_entry_type type; > + ptrdiff_t value; > + size_t len; > +}; > + > +struct proc_param_block { > + size_t num; > + struct ppb_entry entries[]; > +}; > + > +struct ppb_builder { > + struct proc_param_block* ppb; > + size_t ppb_dir_size; > + size_t ppb_dir_used; > + size_t ppb_data_used; > +}; > + > +extern pid_t __init_exec(const char* cmd, int ppb_shm_id); Wofür ist denn das genau gut? > + > +static struct ppb_builder* ppb_builder_init(void) > +{ > + struct ppb_builder* b; > + > + b = malloc(sizeof(*b)); > + if (b == NULL) { > + return NULL; > + } > + Hm wozu brauchst du hier ueberhaupt ganze Pages? Wenn ich das richtig sehe, dann wird das ganze doch am Ende eh in einen SHM-Puffer kopiert und dann freigegeben? > + b->ppb = mem_allocate(PAGE_SIZE, 0); > + b->ppb_dir_size = PAGE_SIZE; > + b->ppb_dir_used = sizeof(struct proc_param_block); > + b->ppb_data_used = 0; > + > + memset(b->ppb, 0, PAGE_SIZE); > + > + return b; > +} > + > +static void* pgrealloc(void* old, size_t old_size, size_t new_size) > +{ > + void* new; > + > + new = mem_allocate(new_size, 0); > + if (new == NULL) { > + return NULL; > + } > + > + memcpy(new, old, old_size); > + mem_free(old, old_size); Hier eventuell noch ein memset(((char*) new) + old_size, 0, new_size - old_size), oder? > + > + return new; > +} > + > +static int ppb_add_entry(struct ppb_builder* b, enum ppb_entry_type type, > + const void* value, size_t len) > +{ > + size_t used; > + int index; > + void* new; > + > + /* Verzeichnis vergroessern falls noetig */ > + used = b->ppb_dir_used + sizeof(struct ppb_entry); > + > + if (used > b->ppb_dir_size) { > + new = pgrealloc(b->ppb, b->ppb_dir_size, NUM_PAGES(used)); > + if (new == NULL) { > + return -ENOMEM; > + } > + > + b->ppb = new; > + b->ppb_dir_size = NUM_PAGES(b->ppb_dir_used); > + } > + > + /* Daten eintragen */ > + index = b->ppb->num++; > + b->ppb->entries[index].type = type; > + b->ppb->entries[index].value = (ptrdiff_t) value; > + b->ppb->entries[index].len = len; > + > + b->ppb_dir_used += sizeof(struct ppb_entry); > + b->ppb_data_used += len; > + > + return 0; > +} > + > +static int ppb_builder_finish(struct ppb_builder* b) > +{ > + int shm; > + size_t size; > + uint8_t* p; > + int i, num_entries; > + ptrdiff_t offset; > + struct ppb_entry* entry; > + > + /* Shared Memory anlegen */ > + size = b->ppb_dir_used + b->ppb_data_used; > + > + shm = create_shared_memory(size); > + if (shm < 0) { > + return shm; > + } > + > + p = open_shared_memory(shm); > + if (p == NULL) { > + return -ENOMEM; > + } > + > + /* Daten kopieren*/ > + num_entries = b->ppb->num; > + offset = b->ppb_dir_used; > + > + for (i = 0; i < num_entries; i++) { > + entry = &b->ppb->entries[i]; > + memcpy(p + offset, (void*) entry->value, entry->len); > + entry->value = offset; > + offset += entry->len; > + } > + > + memcpy(p, b->ppb, b->ppb_dir_used); > + > + /* Strukturen freigeben */ > + mem_free(b->ppb, NUM_PAGES(b->ppb_dir_used)); > + free(b); > + > + return shm; > +} > + > +int ppb_from_argv(const char* const argv[]) > +{ > + struct ppb_builder* b; > + int shm; > + const char* const* p; > + > + b = ppb_builder_init(); > + if (b == NULL) { > + errno = ENOMEM; > + return -1; > + } > + > + p = argv; > + while (*p != NULL) { > + ppb_add_entry(b, PPB_CMDLINE_ARG, *p, strlen(*p) + 1); > + p++; > + } > + > + shm = ppb_builder_finish(b); > + if (shm < 0) { > + errno = -shm; > + return -1; > + } > + > + return shm; > +} > + > +bool ppb_is_valid(struct proc_param_block* ppb, size_t ppb_size) > +{ > + size_t offset; > + size_t len; > + int i; > + > + len = sizeof(*ppb) + ppb->num + sizeof(*ppb->entries); Ich glaube das sollte ein * sein: ^ > + if (ppb_size < len) { > + return false; > + } > + > + ppb_size -= len; > + for (i = 0; i < ppb->num; i++) { > + len = ppb->entries[i].len; > + if (ppb_size < len) { > + return false; > + } > + > + offset = ppb->entries[i].value; > + if (offset > ppb_size || offset + len > ppb_size) { Müsstest du hier nicht mit dem originalen ppb_size vergleichen? > + return false; > + } > + > + ppb_size -= len; > + } > + > + return true; > +} > + > +int ppb_get_argc(struct proc_param_block* ppb, size_t ppb_size) > +{ > + int i; > + int argc = 0; > + > + if (!ppb_is_valid(ppb, ppb_size)) { > + return -EINVAL; > + } > + > + for (i = 0; i < ppb->num; i++) { > + if (ppb->entries[i].type == PPB_CMDLINE_ARG) { > + argc++; > + } > + } > + > + return argc; > +} > + > +void ppb_copy_argv(struct proc_param_block* ppb, size_t ppb_size, > + char** argv, int argc) > +{ > + int i; > + int arg; > + > + if (!ppb_is_valid(ppb, ppb_size)) { > + return; > + } > + > + arg = 0; > + for (i = 0; i < ppb->num; i++) { > + if (ppb->entries[i].type == PPB_CMDLINE_ARG) { > + argv[arg++] = ((char*) ppb) + ppb->entries[i].value; > + if (arg == argc) { > + break; > + } > + } > + } > + > + argv[argc] = NULL; > +} Aber ich glaube von der Idee her finde ich das gut. -- Antoine Kaufmann <toni@xxxxxxxxxxxxxxxx>
Attachment:
pgpMJNg4KHgGy.pgp
Description: PGP signature