summaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/boot_script.c329
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)