diff options
Diffstat (limited to 'boot')
-rw-r--r-- | boot/boot_script.c | 329 |
1 files changed, 148 insertions, 181 deletions
diff --git a/boot/boot_script.c b/boot/boot_script.c index 403988eb..618830f2 100644 --- a/boot/boot_script.c +++ b/boot/boot_script.c @@ -2,37 +2,14 @@ /* Written by Shantanu Goel (goel@cs.columbia.edu). */ -#include <mach/mach_types.h> -#include <mach/message.h> +#include <mach.h> +#include <stdio.h> #include "boot_script.h" -/* This structure describes a command. */ -struct cmd -{ - /* Path of executable. */ - char *path; - - /* Task port. */ - mach_port_t task; - - /* Argument list. */ - struct arg **args; - /* Amount allocated for `args'. */ - int args_alloc; - - /* Next available slot in `args'. */ - int args_index; - - /* List of functions that want to be run on command execution. */ - struct sym **exec_funcs; - - /* Amount allocated for `exec_funcs'. */ - int exec_funcs_alloc; +extern void *malloc (int size); +extern void free (void *ptr); - /* Next available slot in `exec_funcs'. */ - int exec_funcs_index; -}; /* This structure describes a symbol. */ struct sym @@ -58,7 +35,6 @@ struct sym /* Additional values symbols can take. These are only used internally. */ -#define VAL_NONE 0 /* none */ #define VAL_SYM 3 /* symbol table entry */ #define VAL_FUNC 4 /* function pointer */ @@ -99,10 +75,12 @@ void memset (void *str, char c, int size); static int create_task (struct cmd *cmd, int *val) { - cmd->task = boot_script_task_create (); - if (cmd->task == 0) - return BOOT_SCRIPT_MACH_ERROR; - boot_script_task_suspend (cmd->task); + 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; + } *val = (int) cmd->task; return 0; } @@ -111,17 +89,41 @@ create_task (struct cmd *cmd, int *val) static int resume_task (struct cmd *cmd, int *val) { - if (boot_script_task_resume (cmd->task)) - return BOOT_SCRIPT_MACH_ERROR; + if (task_resume (cmd->task)) + { + printf ("(bootstrap): %s: Cannot resume task\n", cmd->path); + return BOOT_SCRIPT_MACH_ERROR; + } return 0; } +/* 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) - return BOOT_SCRIPT_MACH_ERROR; + { + printf ("(bootstrap): %s: Cannot read boot script\n", cmd->path); + return BOOT_SCRIPT_MACH_ERROR; + } return 0; } @@ -130,6 +132,7 @@ 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 }, }; #define NUM_BUILTIN (sizeof (builtin_symbols) / sizeof (builtin_symbols[0])) @@ -143,22 +146,21 @@ free_cmd (struct cmd *cmd, int aborting) if (cmd->task) { if (aborting) - boot_script_task_terminate (cmd->task); + task_terminate (cmd->task); else - boot_script_port_deallocate (boot_script_task_port, cmd->task); + mach_port_deallocate (mach_task_self (), cmd->task); } if (cmd->args) { int i; for (i = 0; i < cmd->args_index; i++) - boot_script_free (cmd->args[i], sizeof (struct arg)); - boot_script_free (cmd->args, cmd->args_alloc * sizeof (struct arg *)); + free (cmd->args[i]); + free (cmd->args); } if (cmd->exec_funcs) - boot_script_free (cmd->exec_funcs, - cmd->exec_funcs_alloc * sizeof (struct sym *)); - boot_script_free (cmd, sizeof (struct cmd)); + free (cmd->exec_funcs); + free (cmd); } /* Free all storage allocated by the parser. @@ -170,13 +172,13 @@ cleanup (int aborting) for (i = 0; i < cmds_index; i++) free_cmd (cmds[i], aborting); - boot_script_free (cmds, cmds_alloc * sizeof (struct cmd *)); + free (cmds); cmds = 0; cmds_index = cmds_alloc = 0; for (i = 0; i < symtab_index; i++) - boot_script_free (symtab[i], sizeof (struct sym)); - boot_script_free (symtab, symtab_alloc * sizeof (struct sym *)); + free (symtab[i]); + free (symtab); symtab = 0; symtab_index = symtab_alloc = 0; } @@ -194,7 +196,7 @@ add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr) void **p; *alloc += incr; - p = boot_script_malloc (*alloc * sizeof (void *)); + p = malloc (*alloc * sizeof (void *)); if (! p) { *alloc -= incr; @@ -203,7 +205,7 @@ add_list (void *ptr, void ***ptr_list, int *alloc, int *index, int incr) if (*ptr_list) { memcpy (p, *ptr_list, *index * sizeof (void *)); - boot_script_free (*ptr_list, *index * sizeof (void *)); + free (*ptr_list); } *ptr_list = p; } @@ -219,7 +221,7 @@ add_arg (struct cmd *cmd, char *text, int type, int val) { struct arg *arg; - arg = boot_script_malloc (sizeof (struct arg)); + arg = malloc (sizeof (struct arg)); if (arg) { arg->text = text; @@ -228,7 +230,7 @@ add_arg (struct cmd *cmd, char *text, int type, int val) if (add_list (arg, (void ***) &cmd->args, &cmd->args_alloc, &cmd->args_index, 5)) { - boot_script_free (arg, sizeof (struct arg)); + free (arg); return 0; } } @@ -253,14 +255,14 @@ sym_enter (const char *name) { struct sym *sym; - sym = boot_script_malloc (sizeof (struct sym)); + sym = 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)) { - boot_script_free (sym, sizeof (struct sym)); + free (sym); return 0; } } @@ -282,6 +284,10 @@ boot_script_parse_line (char *cmdline) if (*p == '#') /* Ignore comment line. */ return 0; + + if (*p && *p != ' ' && *p != '\t' && *p != '\n') + printf ("(bootstrap): %s\n", cmdline); + for (q = p; *q && *q != ' ' && *q != '\t' && *q != '\n'; q++) ; if (p == q) @@ -289,7 +295,7 @@ boot_script_parse_line (char *cmdline) *q = '\0'; /* Allocate a command structure. */ - cmd = boot_script_malloc (sizeof (struct cmd)); + cmd = malloc (sizeof (struct cmd)); if (! cmd) return BOOT_SCRIPT_NOMEM; memset (cmd, 0, sizeof (struct cmd)); @@ -327,7 +333,7 @@ boot_script_parse_line (char *cmdline) for (p += 2;;) { char c; - int i, val, type, is_builtin = 0; + int i, val, type; struct sym *s; /* Parse symbol name. */ @@ -348,57 +354,7 @@ boot_script_parse_line (char *cmdline) break; if (i < NUM_BUILTIN) - { - is_builtin = 1; - s = &builtin_symbols[i]; - - /* Only values are allowed in ${...} constructs. */ - if (end_char == '}' && s->type == VAL_FUNC) - return BOOT_SCRIPT_INVALID_SYM; - - /* Check that assignment is valid. */ - if (end_char == ')' - && (c != end_char - || ((arg || sym) - && s->type == VAL_FUNC - && (s->run_on_exec - || s->ret_type == VAL_NONE)))) - { - error = BOOT_SCRIPT_INVALID_ASG; - goto bad; - } - - /* For function symbols, execute the function. */ - if (s->type == VAL_FUNC) - { - if (! s->run_on_exec) - { - (error - = ((*((int (*) (struct cmd *, int *)) s->val)) - (cmd, &val))); - if (error) - goto bad; - type = s->ret_type; - } - else - { - if (add_list (s, (void ***) &cmd->exec_funcs, - &cmd->exec_funcs_alloc, - &cmd->exec_funcs_index, 5)) - { - error = BOOT_SCRIPT_NOMEM; - goto bad; - } - type = VAL_NONE; - goto out; - } - } - else - { - type = s->type; - val = s->val; - } - } + s = &builtin_symbols[i]; else { /* Look up symbol in symbol table. @@ -413,8 +369,53 @@ boot_script_parse_line (char *cmdline) goto bad; } } + } + + /* Only values are allowed in ${...} constructs. */ + if (end_char == '}' && s->type == VAL_FUNC) + return BOOT_SCRIPT_INVALID_SYM; + + /* Check that assignment is valid. */ + if (c == '=' && s->type == VAL_FUNC) + { + error = BOOT_SCRIPT_INVALID_ASG; + goto bad; + } + + /* For function symbols, execute the function. */ + if (s->type == VAL_FUNC) + { + if (! s->run_on_exec) + { + (error + = ((*((int (*) (struct cmd *, int *)) s->val)) + (cmd, &val))); + if (error) + goto bad; + type = s->ret_type; + } + else + { + if (add_list (s, (void ***) &cmd->exec_funcs, + &cmd->exec_funcs_alloc, + &cmd->exec_funcs_index, 5)) + { + error = BOOT_SCRIPT_NOMEM; + goto bad; + } + type = VAL_NONE; + goto out; + } + } + else if (s->type == VAL_NONE) + { type = VAL_SYM; val = (int) s; + } + else + { + type = s->type; + val = s->val; } if (sym) @@ -451,7 +452,7 @@ boot_script_parse_line (char *cmdline) arg = 0; break; } - if (! is_builtin) + if (s->type != VAL_FUNC) sym = s; } } @@ -504,7 +505,7 @@ boot_script_parse_line (char *cmdline) char *ptr; \ int alloc, i; \ alloc = cmdline_alloc + len - (cmdline_alloc - cmdline_index) + 100; \ - ptr = boot_script_malloc (alloc); \ + ptr = malloc (alloc); \ if (! ptr) \ { \ error = BOOT_SCRIPT_NOMEM; \ @@ -513,7 +514,7 @@ boot_script_parse_line (char *cmdline) memcpy (ptr, cmdline, cmdline_index); \ for (i = 0; i < argc; ++i) \ argv[i] = ptr + (argv[i] - cmdline); \ - boot_script_free (cmdline, cmdline_alloc); \ + free (cmdline); \ cmdline = ptr; \ cmdline_alloc = alloc; \ } \ @@ -539,7 +540,7 @@ boot_script_exec () /* Allocate a command line and copy command name. */ cmdline_index = strlen (cmd->path) + 1; cmdline_alloc = cmdline_index + 100; - cmdline = boot_script_malloc (cmdline_alloc); + cmdline = malloc (cmdline_alloc); if (! cmdline) { cleanup (1); @@ -548,10 +549,10 @@ boot_script_exec () memcpy (cmdline, cmd->path, cmdline_index); /* Allocate argument vector. */ - argv = boot_script_malloc (sizeof (char *) * (cmd->args_index + 2)); + argv = malloc (sizeof (char *) * (cmd->args_index + 2)); if (! argv) { - boot_script_free (cmdline, cmdline_alloc); + free (cmdline); cleanup (1); return BOOT_SCRIPT_NOMEM; } @@ -608,10 +609,12 @@ boot_script_exec () case VAL_PORT: /* Insert send right. */ - if ((boot_script_port_insert_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; } @@ -637,7 +640,7 @@ boot_script_exec () *(cmdline + cmdline_index + len - 1) = '\0'; if (! arg->text) argv[argc++] = &cmdline[cmdline_index]; - cmdline_index += len; + cmdline_index += len; } } @@ -655,8 +658,8 @@ boot_script_exec () error = 0; done: - boot_script_free (cmdline, cmdline_alloc); - boot_script_free (argv, (cmd->args_index + 2) * sizeof (char *)); + free (cmdline); + free (argv); if (error) { cleanup (1); @@ -669,19 +672,18 @@ boot_script_exec () int i; struct cmd *cmd = cmds[cmd_index]; - if (cmd->task) - /* Execute functions that want to be run on 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)) - (cmd, 0)); - if (error) - { - cleanup (1); - return error; - } - } + /* Execute functions that want to be run on 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)) + (cmd, 0)); + if (error) + { + cleanup (1); + return error; + } + } } cleanup (0); @@ -703,6 +705,25 @@ boot_script_set_variable (const char *name, int type, int val) return sym ? 0 : 1; } + +/* 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)) +{ + struct sym *sym = sym_enter (name); + + if (sym) + { + sym->type = VAL_FUNC; + sym->val = (int) func; + sym->ret_type = ret_type; + sym->run_on_exec = ret_type == VAL_NONE; + } + return sym ? 0 : 1; +} + + /* Return a string describing ERR. */ char * boot_script_error_string (int err) @@ -739,60 +760,6 @@ boot_script_error_string (int err) #ifdef BOOT_SCRIPT_TEST #include <stdio.h> -extern void *malloc (int size); -extern void free (void *ptr); - -mach_port_t boot_script_task_port; - -void * -boot_script_malloc (int size) -{ - return malloc (size); -} - -void -boot_script_free (void *ptr, int size) -{ - free (ptr); -} - -mach_port_t -boot_script_task_create () -{ - static mach_port_t task = 10; - - return task++; -} - -void -boot_script_task_terminate (mach_port_t task) -{ -} - -void -boot_script_task_suspend (mach_port_t task) -{ -} - -int -boot_script_task_resume (mach_port_t task) -{ - printf ("boot_script_task_resume()\n"); - return 0; -} - -void -boot_script_port_deallocate (mach_port_t task, mach_port_t port) -{ -} - -int -boot_script_port_insert_right (mach_port_t task, mach_port_t name, - mach_port_t port, mach_msg_type_name_t right) -{ - return 0; -} - int boot_script_exec_cmd (mach_port_t task, char *path, int argc, char **argv, char *strings, int stringlen) |