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