diff options
Diffstat (limited to 'boot/boot_script.c')
-rw-r--r-- | boot/boot_script.c | 199 |
1 files changed, 85 insertions, 114 deletions
diff --git a/boot/boot_script.c b/boot/boot_script.c index 618830f2..6fd449b2 100644 --- a/boot/boot_script.c +++ b/boot/boot_script.c @@ -2,15 +2,13 @@ /* Written by Shantanu Goel (goel@cs.columbia.edu). */ -#include <mach.h> -#include <stdio.h> +#include <mach/mach_types.h> +#if !KERNEL || OSKIT_MACH +#include <string.h> +#endif #include "boot_script.h" -extern void *malloc (int size); -extern void free (void *ptr); - - /* This structure describes a symbol. */ struct sym { @@ -21,7 +19,7 @@ struct sym int type; /* Symbol value. */ - int val; + integer_t val; /* For function symbols; type of value returned by function. */ int ret_type; @@ -35,8 +33,8 @@ struct sym /* Additional values symbols can take. These are only used internally. */ -#define VAL_SYM 3 /* symbol table entry */ -#define VAL_FUNC 4 /* function pointer */ +#define VAL_SYM 10 /* symbol table entry */ +#define VAL_FUNC 11 /* function pointer */ /* This structure describes an argument. */ struct arg @@ -48,7 +46,7 @@ struct arg int type; /* Argument value. */ - int val; + integer_t val; }; /* List of commands. */ @@ -68,72 +66,37 @@ static int symtab_alloc = 0; /* Next available slot in `symtab'. */ static int symtab_index = 0; - -void memset (void *str, char c, int size); -/* Create a task. */ +/* Create a task and suspend it. */ static int create_task (struct cmd *cmd, int *val) { - if (task_create (mach_task_self (), 0, (task_t *) &cmd->task) || - task_suspend (cmd->task)) - { - printf ("(bootstrap): %s: Cannot create task\n", cmd->path); - return BOOT_SCRIPT_MACH_ERROR; - } + int err = boot_script_task_create (cmd); *val = (int) cmd->task; - return 0; + return err; } /* Resume a task. */ static int resume_task (struct cmd *cmd, int *val) { - if (task_resume (cmd->task)) - { - printf ("(bootstrap): %s: Cannot resume task\n", cmd->path); - return BOOT_SCRIPT_MACH_ERROR; - } - return 0; + return boot_script_task_resume (cmd); } /* Resume a task when the user hits return. */ static int prompt_resume_task (struct cmd *cmd, int *val) { - char c; - - printf ("Hit return to resume %s...", cmd->path); - safe_gets (&c, 1); - - if (task_resume (cmd->task)) - { - printf ("(bootstrap): %s: Cannot resume task\n", cmd->path); - return BOOT_SCRIPT_MACH_ERROR; - } - - return 0; -} - -static int -read_file (struct cmd *cmd, int *val) -{ - *val = boot_script_read_file (cmd->path); - if (*val == 0) - { - printf ("(bootstrap): %s: Cannot read boot script\n", cmd->path); - return BOOT_SCRIPT_MACH_ERROR; - } - return 0; + return boot_script_prompt_task_resume (cmd); } /* List of builtin symbols. */ static struct sym builtin_symbols[] = { - { "task-create", VAL_FUNC, (int) create_task, VAL_PORT, 0 }, - { "task-resume", VAL_FUNC, (int) resume_task, VAL_NONE, 1 }, - { "prompt-task-resume", VAL_FUNC, (int) prompt_resume_task, VAL_NONE, 1 }, - { "read-file", VAL_FUNC, (int) read_file, VAL_PORT, 0 }, + { "task-create", VAL_FUNC, (integer_t) create_task, VAL_TASK, 0 }, + { "task-resume", VAL_FUNC, (integer_t) resume_task, VAL_NONE, 1 }, + { "prompt-task-resume", + VAL_FUNC, (integer_t) prompt_resume_task, VAL_NONE, 1 }, }; #define NUM_BUILTIN (sizeof (builtin_symbols) / sizeof (builtin_symbols[0])) @@ -144,23 +107,18 @@ static void free_cmd (struct cmd *cmd, int aborting) { if (cmd->task) - { - if (aborting) - task_terminate (cmd->task); - else - mach_port_deallocate (mach_task_self (), cmd->task); - } + boot_script_free_task (cmd->task, aborting); if (cmd->args) { int i; - for (i = 0; i < cmd->args_index; i++) - free (cmd->args[i]); - free (cmd->args); + boot_script_free (cmd->args[i], sizeof *cmd->args[i]); + boot_script_free (cmd->args, sizeof cmd->args[0] * cmd->args_alloc); } if (cmd->exec_funcs) - free (cmd->exec_funcs); - free (cmd); + boot_script_free (cmd->exec_funcs, + sizeof cmd->exec_funcs[0] * cmd->exec_funcs_alloc); + boot_script_free (cmd, sizeof *cmd); } /* Free all storage allocated by the parser. @@ -172,13 +130,13 @@ cleanup (int aborting) for (i = 0; i < cmds_index; i++) free_cmd (cmds[i], aborting); - free (cmds); + boot_script_free (cmds, sizeof cmds[0] * cmds_alloc); cmds = 0; cmds_index = cmds_alloc = 0; for (i = 0; i < symtab_index; i++) - free (symtab[i]); - free (symtab); + boot_script_free (symtab[i], sizeof *symtab[i]); + boot_script_free (symtab, sizeof symtab[0] * symtab_alloc); symtab = 0; symtab_index = symtab_alloc = 0; } @@ -196,7 +154,7 @@ add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr) void **p; *alloc += incr; - p = malloc (*alloc * sizeof (void *)); + p = boot_script_malloc (*alloc * sizeof (void *)); if (! p) { *alloc -= incr; @@ -205,7 +163,7 @@ add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr) if (*ptr_list) { memcpy (p, *ptr_list, *index * sizeof (void *)); - free (*ptr_list); + boot_script_free (*ptr_list, (*alloc - incr) * sizeof (void *)); } *ptr_list = p; } @@ -217,20 +175,20 @@ add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr) /* Create an argument with TEXT, value type TYPE, and value VAL. Add the argument to the argument list of CMD. */ static struct arg * -add_arg (struct cmd *cmd, char *text, int type, int val) +add_arg (struct cmd *cmd, const char *text, int textlen, int type, int val) { struct arg *arg; - arg = malloc (sizeof (struct arg)); + arg = boot_script_malloc (sizeof (struct arg) + textlen); if (arg) { - arg->text = text; + arg->text = text == 0 ? 0 : memcpy (arg + 1, text, textlen); arg->type = type; arg->val = val; if (add_list (arg, (void ***) &cmd->args, &cmd->args_alloc, &cmd->args_index, 5)) { - free (arg); + boot_script_free (arg, sizeof *arg); return 0; } } @@ -255,14 +213,14 @@ sym_enter (const char *name) { struct sym *sym; - sym = malloc (sizeof (struct sym)); + sym = boot_script_malloc (sizeof (struct sym)); if (sym) { memset (sym, 0, sizeof (struct sym)); sym->name = name; if (add_list (sym, (void ***) &symtab, &symtab_alloc, &symtab_index, 20)) { - free (sym); + boot_script_free (sym, sizeof *sym); return 0; } } @@ -271,7 +229,7 @@ sym_enter (const char *name) /* Parse the command line CMDLINE. */ int -boot_script_parse_line (char *cmdline) +boot_script_parse_line (void *hook, char *cmdline) { char *p, *q; int error; @@ -285,22 +243,28 @@ boot_script_parse_line (char *cmdline) /* Ignore comment line. */ return 0; +#if 0 if (*p && *p != ' ' && *p != '\t' && *p != '\n') - printf ("(bootstrap): %s\n", cmdline); + { + printf ("(bootstrap): %s\n", cmdline); + } +#endif for (q = p; *q && *q != ' ' && *q != '\t' && *q != '\n'; q++) ; if (p == q) - return 0; - *q = '\0'; + return 0; + + *q++ = '\0'; /* Allocate a command structure. */ - cmd = malloc (sizeof (struct cmd)); + cmd = boot_script_malloc (sizeof (struct cmd) + (q - p)); if (! cmd) return BOOT_SCRIPT_NOMEM; memset (cmd, 0, sizeof (struct cmd)); - cmd->path = p; - p = q + 1; + cmd->hook = hook; + cmd->path = memcpy (cmd + 1, p, q - p); + p = q; for (arg = 0;;) { @@ -333,7 +297,8 @@ boot_script_parse_line (char *cmdline) for (p += 2;;) { char c; - int i, val, type; + int i, type; + integer_t val; struct sym *s; /* Parse symbol name. */ @@ -388,7 +353,7 @@ boot_script_parse_line (char *cmdline) if (! s->run_on_exec) { (error - = ((*((int (*) (struct cmd *, int *)) s->val)) + = ((*((int (*) (struct cmd *, integer_t *)) s->val)) (cmd, &val))); if (error) goto bad; @@ -410,7 +375,7 @@ boot_script_parse_line (char *cmdline) else if (s->type == VAL_NONE) { type = VAL_SYM; - val = (int) s; + val = (integer_t) s; } else { @@ -443,7 +408,7 @@ boot_script_parse_line (char *cmdline) associated with an argument. */ if (! arg && end_char == '}') { - if (! add_arg (cmd, 0, type, val)) + if (! add_arg (cmd, 0, 0, type, val)) { error = BOOT_SCRIPT_NOMEM; goto bad; @@ -472,7 +437,7 @@ boot_script_parse_line (char *cmdline) *q = '\0'; /* Add argument to list. */ - arg = add_arg (cmd, p, VAL_NONE, 0); + arg = add_arg (cmd, p, q + 1 - p, VAL_NONE, 0); if (! arg) { error = BOOT_SCRIPT_NOMEM; @@ -491,6 +456,7 @@ boot_script_parse_line (char *cmdline) } } + bad: free_cmd (cmd, 1); cleanup (1); @@ -505,7 +471,7 @@ boot_script_parse_line (char *cmdline) char *ptr; \ int alloc, i; \ alloc = cmdline_alloc + len - (cmdline_alloc - cmdline_index) + 100; \ - ptr = malloc (alloc); \ + ptr = boot_script_malloc (alloc); \ if (! ptr) \ { \ error = BOOT_SCRIPT_NOMEM; \ @@ -514,7 +480,7 @@ boot_script_parse_line (char *cmdline) memcpy (ptr, cmdline, cmdline_index); \ for (i = 0; i < argc; ++i) \ argv[i] = ptr + (argv[i] - cmdline); \ - free (cmdline); \ + boot_script_free (cmdline, cmdline_alloc); \ cmdline = ptr; \ cmdline_alloc = alloc; \ } \ @@ -540,7 +506,7 @@ boot_script_exec () /* Allocate a command line and copy command name. */ cmdline_index = strlen (cmd->path) + 1; cmdline_alloc = cmdline_index + 100; - cmdline = malloc (cmdline_alloc); + cmdline = boot_script_malloc (cmdline_alloc); if (! cmdline) { cleanup (1); @@ -549,10 +515,10 @@ boot_script_exec () memcpy (cmdline, cmd->path, cmdline_index); /* Allocate argument vector. */ - argv = malloc (sizeof (char *) * (cmd->args_index + 2)); + argv = boot_script_malloc (sizeof (char *) * (cmd->args_index + 2)); if (! argv) { - free (cmdline); + boot_script_free (cmdline, cmdline_alloc); cleanup (1); return BOOT_SCRIPT_NOMEM; } @@ -582,6 +548,7 @@ boot_script_exec () { char *p, buf[50]; int len; + mach_port_t name; if (arg->type == VAL_SYM) { @@ -607,19 +574,21 @@ boot_script_exec () len = strlen (p); break; + case VAL_TASK: case VAL_PORT: - /* Insert send right. */ - if ((mach_port_insert_right - (cmd->task, (mach_port_t) arg->val, - (mach_port_t) arg->val, MACH_MSG_TYPE_COPY_SEND))) - { - printf ("(bootstrap): %s: Cannot insert port right %d\n", - cmd->path, arg->val); - error = BOOT_SCRIPT_MACH_ERROR; - goto done; - } - - i = arg->val; + if (arg->type == VAL_TASK) + /* Insert send right to task port. */ + error = boot_script_insert_task_port + (cmd, (task_t) arg->val, &name); + else + /* Insert send right. */ + error = boot_script_insert_right (cmd, + (mach_port_t) arg->val, + &name); + if (error) + goto done; + + i = name; p = buf + sizeof (buf); len = 0; do @@ -648,7 +617,7 @@ boot_script_exec () argv[argc] = 0; /* Execute the command. */ - if (boot_script_exec_cmd (cmd->task, cmd->path, + if (boot_script_exec_cmd (cmd->hook, cmd->task, cmd->path, argc, argv, cmdline, cmdline_index)) { error = BOOT_SCRIPT_EXEC_ERROR; @@ -658,8 +627,8 @@ boot_script_exec () error = 0; done: - free (cmdline); - free (argv); + boot_script_free (cmdline, cmdline_alloc); + boot_script_free (argv, sizeof (char *) * (cmd->args_index + 2)); if (error) { cleanup (1); @@ -676,7 +645,7 @@ boot_script_exec () for (i = 0; i < cmd->exec_funcs_index; i++) { struct sym *sym = cmd->exec_funcs[i]; - int error = ((*((int (*) (struct cmd *, int *)) sym->val)) + int error = ((*((int (*) (struct cmd *, integer_t *)) sym->val)) (cmd, 0)); if (error) { @@ -693,7 +662,7 @@ boot_script_exec () /* Create an entry for the variable NAME with TYPE and value VAL, in the symbol table. */ int -boot_script_set_variable (const char *name, int type, int val) +boot_script_set_variable (const char *name, int type, integer_t val) { struct sym *sym = sym_enter (name); @@ -709,14 +678,15 @@ boot_script_set_variable (const char *name, int type, int val) /* Define the function NAME, which will return type RET_TYPE. */ int boot_script_define_function (const char *name, int ret_type, - int (*func) (const struct cmd *cmd, int *val)) + int (*func) (const struct cmd *cmd, + integer_t *val)) { struct sym *sym = sym_enter (name); if (sym) { sym->type = VAL_FUNC; - sym->val = (int) func; + sym->val = (integer_t) func; sym->ret_type = ret_type; sym->run_on_exec = ret_type == VAL_NONE; } @@ -761,7 +731,8 @@ boot_script_error_string (int err) #include <stdio.h> int -boot_script_exec_cmd (mach_port_t task, char *path, int argc, +boot_script_exec_cmd (void *hook, + mach_port_t task, char *path, int argc, char **argv, char *strings, int stringlen) { int i; @@ -805,7 +776,7 @@ main (int argc, char **argv) int i, err; i = strlen (p) + 1; - err = boot_script_parse_line (p); + err = boot_script_parse_line (0, p); if (err) { fprintf (stderr, "error %s\n", boot_script_error_string (err)); |