diff options
Diffstat (limited to 'boot')
-rw-r--r-- | boot/ChangeLog | 586 | ||||
-rw-r--r-- | boot/Makefile | 15 | ||||
-rw-r--r-- | boot/boot.c | 852 | ||||
-rw-r--r-- | boot/boot_script.c | 199 | ||||
-rw-r--r-- | boot/boot_script.h | 40 | ||||
-rw-r--r-- | boot/tcattr.c | 592 | ||||
-rw-r--r-- | boot/userland-boot.c | 108 |
7 files changed, 712 insertions, 1680 deletions
diff --git a/boot/ChangeLog b/boot/ChangeLog deleted file mode 100644 index 19d13d51..00000000 --- a/boot/ChangeLog +++ /dev/null @@ -1,586 +0,0 @@ -Thu Aug 1 14:38:38 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> - - * boot_script.h (safe_gets): Declare second parm as type `int'. - * boot.c (safe_gets): Likewise. - -Sun Jul 7 21:10:08 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * boot.c (S_io_reauthenticate): Don't use unsafe MOVE_SEND in - auth_server_authenticate. - -Fri May 10 16:11:49 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * boot.c (S_io_identity): Typo. - -Fri May 10 09:18:53 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * boot.c (S_io_identity): New function. - -Thu May 9 18:57:34 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * boot.c (S_io_select): No longer has TAG parm. - - * boot.c (S_io_reauthenticate): Use new interface. - -Sun Apr 28 22:50:38 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * boot.c (main): Use select instead of SIGIO. - -Mon Apr 15 12:57:29 1996 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * Makefile (uxboot): Permit errors because people might not have - the a.out-mach3 target installed, and that's OK for many users. - - * Makefile (uxboot.0): Find frank1.ld in #(srcdir). - - * boot_script.h (safe_gets): Add decl. - * boot_script.c: Include <stdio.h>. - -Wed Apr 3 18:54:22 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * ux.c (printf): Add %d. - -Wed Mar 27 11:30:29 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * boot.c [notanymore] (S_tioctl_tiocgeta, S_tioctl_tiocseta, - S_tioctl_tiocsetaf, term_modes, term_ccs, term_speeds): - Functions & variables removed. - * Makefile (COMMON-OBJS): Remove tcattr.o. - (SRCS): Remove tcattr.c. - -Thu Mar 14 10:10:20 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu> - - * Makefile (boot): Depend on libthreads.so, nothing wrong with shared - libs. - (uxboot.0, uxboot.1): Use automatic vars in cmds instead of gratuitous - redundancy. - (LDFLAGS-uxboot.0): Remove useless indirection through variable. - -Wed Feb 14 16:50:05 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * boot.c [!UX] - (orig_tty_state): New variable. - (init_termstate, restore_termstate): New hurd versions of these funcs. - * ux.c (init_termstate, restore_termstate, term_sgb, localbits): - Moved here from boot.c - -Tue Feb 13 18:49:26 1996 Miles Bader <miles@gnu.ai.mit.edu> - - * boot.c (load_image, boot_script_read_file, main): Use O_RDONLY, - not 0 (kind of ironic, this...). - (load_image): Give the filename with the error message (and a newline). - - * ux.h (O_RDONLY, O_WRONLY, O_RDWR): New macros. - - * ux.c, ux.h: New files. - * boot.c: Move all the ux-specific grot into ux.c & ux.h. - If UX is defined, include "ux.h", else define hurdish stuff. - (main): Use get_privileged_ports instead of task_by_pid. - (load_image, boot_script_read_file, main, do_mach_notify_no_senders, - do_mach_notify_dead_name): Use host_exit instead of uxexit. - (boot_script_read_file): Use host_stat instead of uxstat. - (init_termstate, S_tioctl_tiocseta): Use sg_flags fld in struct sgttyb. - - * Makefile (all): Depend on `boot' and `uxboot'. - (COMMON-OBJS, UX-OBJS): New macros. - (OBJS): Inherit most names from $(COMMON-OBJS). - (LCLHDRS): Add ux.h. - (LDFLAGS): Use target-specific value. - (uxboot.0-LDFLAGS): New macro (with contents from old LDFLAGS). - (uxboot.o, uxboot.0): New targets. - (uxboot): Target renamed from boot.a. - -Sun Dec 10 18:05:14 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * boot.c (read_reply): Don't call clear_should_read(), just do - things ourselves. - (should_read_lock): Variable deleted. - (service_sigio): Function deleted. - (main): Use read_reply to service SIGIO again, not service_sigio. - - * boot.c (service_sigio): New function, replacing set_should_read. - Calls read_reply() itself too. - (unlock_readlock): New function. - (ds_device_read, ds_device_read_inband, S_io_read): Call - unlock_readlock instead of directly unlocking READLOCK. - (request_server, main): Don't call read_reply() anymore. - - * boot.c (should_read): New variable. - (main): SIGIO uses set_should_read instead of read_reply. - Call read_reply() after sigpause() returns. - (read_reply): Call clear_should_read(), and don't do anything if - SHOULD_READ wasn't set. - (set_should_read): New function. - (clear_should_read): New function. - (request_server): Call read_reply() before returning. - -Sat Dec 9 19:01:10 1995 Miles Bader <miles@gnu.ai.mit.edu> - - * boot.c (S_io_read, ds_device_read_inband, ds_device_read): Don't - block SIGIO. - (main): Don't trap SIGMSG & SIGEMSG. - -Mon Dec 4 23:54:18 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c (main): Request no-senders notification on - pseudo_master_device_port. - Deallocate our send right to it when we no longer need it. - (do_mach_notify_no_senders): Exit only when both pseudo_console and - pseudo_master_device_port have no senders. - (ds_device_read_inband): Unlock readlock properly. - -Thu Nov 30 15:58:47 1995 Michael I. Bushnell, p/BSG <mib@gnu.ai.mit.edu> - - * boot.c (readlock): New variable. - (read_reply): Check FIONREAD before dequeueing QR so that we don't - abandon requests. Lock READLOCK around FIONREAD/read pair. - (ds_device_read): Lock READLOCK around FIONREAD/read pair. - (ds_device_read_inband): Likewise. - (S_io_read): Likewise. - -Nov 22 16:25:01 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c (request_server): Don't call exec_server. - (S_exec_*): Functions removed. - (boot_script_task_port): Variable removed. - (boot_script_task_*, boot_script_port_*): Functions removed. - -Tue Nov 14 12:07:24 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (OBJS): Remove execServer.o. - -Thu Sep 28 14:47:46 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot_script.c (read_file): Pass CMD->path for file name. - (CHECK_CMDLINE_LEN): Update ARGV pointers after reallocating the line - buffer. - -Wed Sep 27 14:01:03 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c (struct uxstat): New type. - (uxfstat): Renamed from fstat; use struct uxstat * for arg. - (boot_script_read_file): Use those. - Return the memory object port, not zero. - - * boot.c (fstat): New syscall function. - - * boot_script.c (read_file): New function. - (builtin_symbols): Add $(read-file) builtin. - * boot_script.h (boot_script_read_file): Declare it. - * boot.c (close): New syscall function. - (defpager): New variable. - (main): Set it up. - (boot_script_read_file): New function. - (useropen_dir): New variable. - (useropen): New function. - (load_image): Call it instead of open. - (main): Grok -D arg to set useropen_dir. - -Sat Sep 23 00:53:51 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * syscall.S: Restore entry SP before return. - - * boot.c (main): Use static const for constant strings. - On boot script error, write script line with error msg. - - * boot_script.c (boot_script_parse_line): Ignore line beginning - with #. - - * boot.c (S_io_pathconf): New function. - - * Makefile (LDFLAGS): Add -static. - -Fri Sep 22 14:14:23 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * mach-crt0.c (__data_start): New variable. - -Tue Aug 29 10:41:29 1995 Michael I. Bushnell, p/BSG <mib@duality.gnu.ai.mit.edu> - - * boot.c (mig_dealloc_reply_port): Remove __ from call to - mach_port_mod_refs. - (main): Look for -d in bootstrap_args, not (nonexistent) - boot_args. Remove `const' keyword from decl of MSG. - - * boot.c (sigblock, sigsetmask): New functions. - (sigmask): New macro. - (ds_device_read): Block SIGIO around critical section. - (ds_device_read_inband): Likewise. - (S_io_read): Likewise. - -Mon Aug 28 17:16:48 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot_script.h, boot_script.c: Updated by Shantanu Goel, to - accept action keywords only inside $(...) and only variable values - inside ${...}. - * boot.c: Updated for changes in boot_script.h protocol by - Shantanu Goel. - (main): Use boot_script_set_variable instead of magic variables. - Under -d, pause between parsing bootscript and executing it. - -Wed Aug 23 16:08:04 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - New script-driven boot mechanism, mostly implemented by Shantanu Goel. - * Makefile (SRCS): Add boot_script.c. - (OBJS): Add boot_script.o. - (LCLHDRS): New variable. - (HURDLIBS): Variable removed. - (boot): Depend on ../libthreads/libthreads.a. - * boot_script.c, boot_script.h: New files. - * boot.c (boot_like_kernel, boot_like_cmudef, boot_like_hurd): - Variables removed. - (main): Don't interpret switches. Instead of servers, take - command line argument of boot script file name. Read the file and - use boot_script functions to parse and execute its directives. - (boot_script_*): New variables and functions for boot_script callbacks. - -Sun Jul 30 23:50:53 1995 Michael I. Bushnell, p/BSG <mib@geech.gnu.ai.mit.edu> - - * Makefile: DISTFILES -> DIST_FILES. - -Sat Jul 8 11:37:32 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * boot.c (free_reply_ports, free_reply_ports_lock): New variables. - (__mig_get_reply_port, __mig_put_reply_port, __mig_dealloc_reply_port, - mig_get_reply_port, mig_put_reply_port, mig_dealloc_reply_port): - Provide better versions of these routines that won't leak reply ports. - -Fri Jul 7 15:55:18 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * mach-crt0.c: New file, from mach4-i386/libmach/standalone. - * boot.c (mach_init_routine): New variable, wanted by mach-crt0.o. - (__mig_get_reply_port, __mig_dealloc_reply_port, __mig_put_reply_port): - New functions, to avoid using hurdish versions. - * Makefile (OBJS): Add mach-crt0.o. - (SRCS): Add mach-crt0.c. - (LDFLAGS): Add -nostartfiles (as we now use mach-crt0.o). - -Thu Jul 6 15:30:18 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * Makefile (boot.1, boot.a): Use $(LD) and $(OBJCOPY) instead of - explicit names. - - * boot.c: Include <mach/mig_support.h>. - (S_io_reauthenticate): Cast first arg to mig_deallocate. - (load_image): Cast second arg to read. - * tcattr.c: Undo last change; add private decl of ioctl. - - * boot.c (bootdevice): Initialize to hard-coded `sd0a' instead of - DEFAULT_BOOTDEVICE. - - * Makefile (all): Depend on boot.a too. - - * Makefile: Removed dependencies that are now automatically - generated. - -Wed May 31 10:02:11 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (DISTFILES): New variable; include frank1.ld and - frankemul.ld. - (CPPFLAGS): Variable removed. - (LDFLAGS): Append -T frank1.ld. - (boot.1, boot.a): New targets. - - * syscall.S: Omit .globl decl for errno; it caused some as - complaint. - -Mon May 22 11:48:58 1995 Michael I Bushnell <mib@duality.gnu.ai.mit.edu> - - * sigvec.S: Remove copyright notice. - -Wed May 17 13:10:27 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * boot.c (load_image): Make sure we actually allocate enough - memory to read into, including the offset into the buffer at which - the segment is read. - - * sigvec.S (sigreturn, _sigreturn, sigvec): Remove the explicit - underscore prefixes from these names, now that we're using elf. - Instead we use the various macros from <i386/asm.h>. Also, return - errors correctly. [Also added a copyright notice] - -Sat May 13 03:37:24 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c (load_image): Fixed alignment calculation in ELF segment - loading. - - * syscall.S: Include i386/asm.h and use ENTRY and EXT macros, - instead of explicit _s. - -Fri May 12 18:36:39 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c (load_image): Grok ELF executables as well as a.out. - (main): Load multiple servers. Suspend all but the first. - The first gets an extra arg, its name for the task port of the - second. - -Wed Apr 12 09:18:50 1995 Miles Bader <miles@churchy.gnu.ai.mit.edu> - - * Makefile: Don't try and install boot in /usr/local/bin. - -Wed Apr 5 17:25:19 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c: Don't include <errno.h>. Define `errno' variable. - * Makefile (SRCS): Add syscall.S. - (OBJS): Add syscall.o. - * syscall.S: Check for errors. - -Thu Jan 19 01:21:24 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c (S_io_select): Updated to new io_select protocol. - -Fri Dec 9 01:23:22 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c: Use mach_msg_type_number_t in place of unsigned int and - int. - -Fri Nov 11 14:05:43 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * boot.c (main): Always set `f' flag (signifying "fake" because we - aren't a real native bootstrap). - -Thu Nov 3 17:26:37 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile (boot.o): Depend on bootstrap_S.h. - -Fri Oct 28 17:08:12 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * boot.c (main): Create the thread before setting it up. - (bootstrap_compat): Make a send right for psuedo_master_device_port. - (main): Explicitly clear NEWTASK's bootstrap port for boot_like_kernel. - (main): Format strings for port names for boot_like_kernel. - -Fri Oct 28 15:26:48 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * boot.c (boot_like_kernel, boot_like_cmudef, boot_like_hurd): New - global vars. - (set_mach_stack_args): New function. - (main): If the -k flag is given, set BOOT_LIKE_KERNEL. - If the -p flag is given, set BOOT_LIKE_CMUDEF. If neither is - given, set BOOT_LIKE_HURD. - Only set a bootstrap port if BOOT_LIKE_CMUDEF or BOOT_LIKE_HURD. - If BOOT_LIKE_KERNEL or BOOT_LIKE_CMUDEF, set up the stack the - Mach way using set_mach_stack_args. - (request_server): Declare and call bootstrap_server. - (do_bootstrap_priveleged_ports, bootstrap_compat): New functions. - * Makefile (OBJS): Require bootstrapServer.o. - * bootstrap.defs: New file. - -Tue Aug 30 11:41:33 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * boot.c (S_io_reauthenticate): Use new authentication protocol. - -Mon Aug 22 13:43:32 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * boot.c: Include <cthreads.h>. - (main): Run msg_thread fork; don't call - mach_msg_server_timeout here. Use sigpause instead of getpid. - (msg_thread): New function. - (queuelock): New variable. - (queue_read): Acquire queuelock. - (read_reply): Acquire queuelock. - * Makefile (HURDLIBS): New var to get threads. - -Thu Aug 18 18:04:36 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * boot.c (restore_termstate): New function. - (do_mach_notify_no_senders): Call restore_termstate before exiting. - - * boot.c (main): New var `usagemsg'; print it if args are wrong. - Allow flags and disk device to be given on command line. - New var `bootfile'. - (bootdevice, bootstrap_args): New vars. - (load_image): Exit nicely if the startup file can't be found. - (S_exec_startup): Use `bootdevice' instead of hardcoded name. - Use `bootstrap_args' instead of hardcoded "-x". - (main): Only do `pausing' hack if -d was provided. - - * Makefile (CPPFLAGS): Define DEFAULT_BOOTDEVICE. - - * Makefile (/usr/local/bin/boot): Depend on boot. - - * boot.c (S_termctty_open_terminal): New "function". - (S_io_select): Added `rettype' arg. - -Sat Jul 23 02:58:05 1994 Roland McGrath <roland@churchy.gnu.ai.mit.edu> - - * Makefile (io-MIGSFLAGS): Renamed from ioMIGSFLAGS. - -Fri Jul 22 15:10:45 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * boot.c (request_server): Remove S_ from io_server and - term_server. - -Thu Jul 21 19:00:36 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * Makefile: Rewritten to use new scheme. - * boot.c: Include io_reply_U.h and device_reply_U.h instead - of io_repl.h and device_reply.h. - -Wed Jul 20 13:19:45 1994 Michael I Bushnell <mib@geech.gnu.ai.mit.edu> - - * boot.c: Comment out bits relating to tioctl interface. - * Makefile: Likewise. - -Tue Jul 19 12:41:46 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * Makefile (boot): Don't use variable $(link) anymore. - -Tue Jul 5 14:19:36 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * Makefile (SRCS): New variable. - -Sun Jul 3 17:20:07 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * tcattr.c: New file. - * boot.c (S_tioctl_tiocgeta): Call tcgetattr. - (S_tioctl_tiocseta): Call tcsetattr. - * Makefile (OBJS): Add tcattr.o. - (DIST_FILES): Add tcattr.c. - -Fri Jul 1 11:16:27 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * boot.c (init_termstate): Enter raw mode here. - -Fri Jun 24 14:27:56 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * boot.c (S_term_open_ctty): Renamed from term_become_ctty. - Deleted SIGPT arg. Add msg type arg for NEWTTY. - -Fri Jun 17 13:46:07 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * boot.c (request_server): Remove S_ prefix from exec_server - and notify_server. - -Fri Jun 17 00:12:16 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * Makefile (boot.o): Depend on term_S.h. - -Tue Jun 14 01:28:10 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * boot.c (request_server): Add S_ prefix to demuxer functions. - -Wed Jun 8 18:02:19 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * boot.c (S_tioctl_tiocseta): Turn off ECHO. - (S_io_select): Implement. - -Tue Jun 7 04:33:42 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * Makefile (tioctlServer.o): Depend on ../hurd/ioctl_types.h. - -Mon Jun 6 20:33:39 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * boot.c (authserver): New variable. - (S_io_reauthenticate): Do auth_server_authenticate and throw away - the returned info. - (S_exec_init): Set authserver to the passed port. - -Sat Jun 4 02:32:03 1994 Roland McGrath (roland@geech.gnu.ai.mit.edu) - - * boot.c: Include term_S.h and tioctl_S.h. - (S_term_getctty): New function. - (S_term_*): Stub functions. - (request_server): Use S_term_server. - - * Makefile (termServer.c term_S.h): New rule. - (OBJS): Add termServer.o. - - * boot.c (S_exec_setexecdata, S_exec_exec): Fix prototypes. - -Tue May 17 18:44:29 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * boot.c (ds_device_write): DATA arg is char *; don't dereference - it in call to write. - -Mon May 16 14:34:15 1994 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu) - - * boot.c (fsname): New variable. - (main): Set fsname to argv[1]. - (S_exec_startup): Include fsname in child's argv[0]. - - * boot.c (init_termstate): Add forward declaration. - (struct sigvec): Make SV_HANDLER member void (*)(). - (sigvec): Add declaration to avoid warning. - -Tue May 10 18:14:39 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * boot.c (tioctl_tiocseta, tioctl_tiocsetw, tioctl_tiocsetf, - tioctl_tiocgeta, init_termstate): New functions. - (term_modes, term_ccs, term_speeds, term_sgb, localbits): Nev - vars. - Also added new bits from ioctl.h. - (main): Call init_termstate. - (request_server): Call tioctl_server. - * Makefile (tioctlServer.c tioctl_S.h): New targets. - (OBJS): Include tioctlServer.o. - (boot.o): Depend on tioctl_S.h - -Fri May 6 13:56:58 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * boot.c (main): Restore braindamage of yesterday relating to - signals; that is, restore declaration of VEC and calls to sigvec. - * Makefile (DIST_FILES): Add sigvec.S. - -Thu May 5 13:16:42 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * Makefile (device_replyUser.c): Mention that this build - device_reply.h as well. - (boot.o): Add dependency on device_reply.h and io_repl.h. - - * boot.c: Include <stdlib.h> for malloc and free prototypes. - Include <string.h> for bcopy and bzero prototypes. - Include <stdio.h> for sprintf prototype. - Include "device_reply.h" for its prototypes. - Include "io_reply.h" for its prototypes. - Declare return type for all the server functions that were lacking - such. - (sigpause): Declare type of MASK. - (ioctl): Declare third arg to be generic pointer, not char *. - (request_server): Declare MiG functions we call. - (load_image): Delete unused variable STACKADDR. - (main): Comment out declaration of VEC. - Comment out calls to sigvec. - Cast STARTPC in call to __mach_setup_thread. - Delete unused variable TIMEOUT. - (read_reply): Cast BUF correctly in call to ds_device_read_reply. - (S_exec_startup): Delete unused variable DTABLE. - (ds_device_write): Double cast arg to write to avoid warning. - (S_io_read): Order args to vm_allocate properly; cast DATA arg. - Check *datalen properly for unsigned type. - - * boot.c: Renamed _exit to uxexit to avoid library name clash. - (do_mach_notify_dead_name, do_mach_notify_no_senders): - Call uxexit instead of _exit. - - * boot.c (S_io_async, S_io_get_icky_async_id, S_io_map_cntl): - Expect new type arg for returned port. - (S_io_prenotify, S_io_postnotify): START and END args are now - vm_offset_t. - - * boot.c: Change error_t to kern_return_t because error_t - is now unsigned and conflicts with MiG's use of kern_return_t. - - * Makefile (io_S.h, ioServer.c): Punt mungio hack; use - -DREPLY_PORTS. - * boot.c: Changed all io server stubs to expect reply ports. - - * mungio: removed file. - * Makefile (DIST_FILES): Removed mungio. - - * boot.c (load_image): Only read from the image file the actual - amount being read, not that amount rounded to the nearest page. - Otherwise, the first bit of the BSS will not be zero, but will be - whatever is in the front of the symbol section of the a.out. - -Thu May 5 07:43:06 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * Makefile: Change uses of $(headers) to $(includedir). - -Mon May 2 16:47:49 1994 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) - - * boot.c (S_io_readable): Implement io_readable fully. - -Fri Apr 1 17:55:38 1994 Roland McGrath (roland@churchy.gnu.ai.mit.edu) - - * Makefile (OBJS): Remove boot_machdep.o. - diff --git a/boot/Makefile b/boot/Makefile index 30838e5d..6c787cfd 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. +# Copyright (C) 1993,94,95,96,97,2001 Free Software Foundation, Inc. # This file is part of the GNU Hurd. # # The GNU Hurd is free software; you can redistribute it and/or modify @@ -18,16 +18,18 @@ dir := boot makemode := utility -SRCS = mach-crt0.c boot.c ux.c sigvec.S syscall.S boot_script.c +SRCS = mach-crt0.c boot.c ux.c sigvec.S syscall.S \ + boot_script.c userland-boot.c COMMON-OBJS = notifyServer.o ourdeviceServer.o \ ioServer.o io_replyUser.o device_replyUser.o \ - termServer.o bootstrapServer.o boot_script.o + termServer.o bootstrapServer.o boot_script.o userland-boot.o OBJS = boot.o $(COMMON-OBJS) UX-OBJS = mach-crt0.o uxboot.o sigvec.o syscall.o ux.o $(COMMON-OBJS) LCLHDRS = boot_script.h ux.h target = boot io-MIGSFLAGS=-DREPLY_PORTS DIST_FILES=frank1.ld frankemul.ld +HURDLIBS=store shouldbeinlibc threads include ../Makeconf @@ -36,12 +38,11 @@ include ../Makeconf #/usr/local/bin/uxboot: uxboot # cp $< $@ -all: boot uxboot +all: boot # uxboot -ourdevice.defs: $(includedir)/device/device.defs - sed -e '/out device : device_t/s/device_t/mach_port_send_t/' $< > $@ +ourdevice.defs: device.defs + $(CPP) $(CPPFLAGS) -x c $< | sed -e '/out[ ]*device[ ]*:[ ]*device_t/s/device_t/mach_port_send_t/' > $@ -boot: ../libthreads/libthreads.so uxboot.o: boot.c $(COMPILE.c) -DUX $< -o $@ diff --git a/boot/boot.c b/boot/boot.c index dcf3bccc..2b143844 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -1,6 +1,7 @@ /* Load a task using the single server, and then run it as if we were the kernel. - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,2006 + Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -30,14 +31,16 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <string.h> #include <stdio.h> #include <cthreads.h> -#include <varargs.h> -#include <fcntlbits.h> +#include <fcntl.h> #include <elf.h> #include <mach/mig_support.h> #include <mach/default_pager.h> +#include <argp.h> +#include <hurd/store.h> +#include <sys/mman.h> +#include <version.h> #include "notify_S.h" -#include "exec_S.h" #include "ourdevice_S.h" #include "io_S.h" #include "device_reply_U.h" @@ -51,6 +54,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <hurd/auth.h> #ifdef UX +#undef STORE /* We can't use libstore when under UX. */ +#else +#define STORE +#endif + +#ifdef UX #include "ux.h" @@ -64,8 +73,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <termios.h> #include <error.h> #include <hurd.h> +#include <assert.h> static struct termios orig_tty_state; +static int isig; +static char *kernel_command_line; static void init_termstate () @@ -77,6 +89,8 @@ init_termstate () orig_tty_state = tty_state; cfmakeraw (&tty_state); + if (isig) + tty_state.c_lflag |= ISIG; if (tcsetattr (0, 0, &tty_state) < 0) error (11, errno, "tcsetattr"); @@ -97,9 +111,11 @@ typedef struct stat host_stat_t; mach_port_t privileged_host_port, master_device_port, defpager; mach_port_t pseudo_master_device_port; mach_port_t receive_set; -mach_port_t pseudo_console; +mach_port_t pseudo_console, pseudo_root; auth_t authserver; +struct store *root_store; + spin_lock_t queuelock = SPIN_LOCK_INITIALIZER; spin_lock_t readlock = SPIN_LOCK_INITIALIZER; @@ -118,10 +134,10 @@ void restore_termstate (); char *fsname; -char *bootstrap_args; -char *bootdevice = "sd0a"; +char bootstrap_args[100] = "-"; +char *bootdevice = 0; +char *bootscript = 0; -void set_mach_stack_args (); void safe_gets (char *buf, int buf_len) { @@ -219,7 +235,8 @@ load_image (task_t t, vm_size_t offs = ph->p_offset & (ph->p_align - 1); vm_size_t bufsz = round_page (ph->p_filesz + offs); - vm_allocate (mach_task_self (), &buf, bufsz, 1); + buf = (vm_address_t) mmap (0, bufsz, + PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); lseek (fd, ph->p_offset, SEEK_SET); read (fd, (void *)(buf + offs), ph->p_filesz); @@ -231,7 +248,7 @@ load_image (task_t t, vm_allocate (t, (vm_address_t*)&ph->p_vaddr, ph->p_memsz, 0); vm_write (t, ph->p_vaddr, buf, bufsz); - vm_deallocate (mach_task_self (), buf, bufsz); + munmap ((caddr_t) buf, bufsz); vm_protect (t, ph->p_vaddr, ph->p_memsz, 0, ((ph->p_flags & PF_R) ? VM_PROT_READ : 0) | ((ph->p_flags & PF_W) ? VM_PROT_WRITE : 0) | @@ -253,15 +270,15 @@ load_image (task_t t, amount = headercruft + hdr.a.a_text + hdr.a.a_data; rndamount = round_page (amount); - vm_allocate (mach_task_self (), (u_int *)&buf, rndamount, 1); + buf = mmap (0, rndamount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); lseek (fd, sizeof hdr.a - headercruft, SEEK_SET); read (fd, buf, amount); vm_allocate (t, &base, rndamount, 0); - vm_write (t, base, (u_int) buf, rndamount); + vm_write (t, base, (vm_address_t) buf, rndamount); if (magic != OMAGIC) vm_protect (t, base, trunc_page (headercruft + hdr.a.a_text), 0, VM_PROT_READ | VM_PROT_EXECUTE); - vm_deallocate (mach_task_self (), (u_int)buf, rndamount); + munmap ((caddr_t) buf, rndamount); bssstart = base + hdr.a.a_text + hdr.a.a_data + headercruft; bsspagestart = round_page (bssstart); @@ -278,18 +295,6 @@ void msg_thread (); /* Callbacks for boot_script.c; see boot_script.h. */ -void * -boot_script_malloc (int size) -{ - return malloc (size); -} - -void -boot_script_free (void *ptr, int size) -{ - free (ptr); -} - mach_port_t boot_script_read_file (const char *filename) { @@ -324,116 +329,243 @@ boot_script_read_file (const char *filename) vm_map (mach_task_self (), ®ion, round_page (st.st_size), 0, 1, memobj, 0, 0, VM_PROT_ALL, VM_PROT_ALL, VM_INHERIT_NONE); read (fd, (char *) region, st.st_size); - vm_deallocate (mach_task_self (), region, round_page (st.st_size)); + munmap ((caddr_t) region, round_page (st.st_size)); close (fd); return memobj; } 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) { char *args, *p; int arg_len, i; - unsigned reg_size; + size_t reg_size; void *arg_pos; vm_offset_t stack_start, stack_end; vm_address_t startpc, str_start; thread_t thread; - struct i386_thread_state regs; write (2, path, strlen (path)); + for (i = 1; i < argc; ++i) + { + write (2, " ", 1); + write (2, argv[i], strlen (argv[i])); + } write (2, "\r\n", 2); startpc = load_image (task, path); - thread_create (task, &thread); arg_len = stringlen + (argc + 2) * sizeof (char *) + sizeof (integer_t); arg_len += 5 * sizeof (int); stack_end = VM_MAX_ADDRESS; stack_start = VM_MAX_ADDRESS - 16 * 1024 * 1024; vm_allocate (task, &stack_start, stack_end - stack_start, FALSE); - reg_size = i386_THREAD_STATE_COUNT; - thread_get_state (thread, i386_THREAD_STATE, - (thread_state_t) ®s, ®_size); - regs.eip = (int) startpc; - regs.uesp = (int) ((stack_end - arg_len) & ~(sizeof (int) - 1)); - thread_set_state (thread, i386_THREAD_STATE, - (thread_state_t) ®s, reg_size); - arg_pos = (void *) regs.uesp; - vm_allocate (mach_task_self (), (vm_address_t *) &args, - stack_end - trunc_page ((vm_offset_t) arg_pos), TRUE); + arg_pos = (void *) ((stack_end - arg_len) & ~(sizeof (natural_t) - 1)); + args = mmap (0, stack_end - trunc_page ((vm_offset_t) arg_pos), + PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); str_start = ((vm_address_t) arg_pos + (argc + 2) * sizeof (char *) + sizeof (integer_t)); p = args + ((vm_address_t) arg_pos & (vm_page_size - 1)); - *((int *) p)++ = argc; + *(int *) p = argc; + p = (void *) p + sizeof (int); for (i = 0; i < argc; i++) - *((char **) p)++ = argv[i] - strings + (char *) str_start; - *((char **) p)++ = 0; - *((char **) p)++ = 0; + { + *(char **) p = argv[i] - strings + (char *) str_start; + p = (void *) p + sizeof (char *); + } + *(char **) p = 0; + p = (void *) p + sizeof (char *); + *(char **) p = 0; + p = (void *) p + sizeof (char *); memcpy (p, strings, stringlen); bzero (args, (vm_offset_t) arg_pos & (vm_page_size - 1)); vm_write (task, trunc_page ((vm_offset_t) arg_pos), (vm_address_t) args, stack_end - trunc_page ((vm_offset_t) arg_pos)); - vm_deallocate (mach_task_self (), (vm_address_t) args, - stack_end - trunc_page ((vm_offset_t) arg_pos)); + munmap ((caddr_t) args, + stack_end - trunc_page ((vm_offset_t) arg_pos)); + + thread_create (task, &thread); +#ifdef i386_THREAD_STATE_COUNT + { + struct i386_thread_state regs; + reg_size = i386_THREAD_STATE_COUNT; + thread_get_state (thread, i386_THREAD_STATE, + (thread_state_t) ®s, ®_size); + regs.eip = (int) startpc; + regs.uesp = (int) arg_pos; + thread_set_state (thread, i386_THREAD_STATE, + (thread_state_t) ®s, reg_size); + } +#elif defined(ALPHA_THREAD_STATE_COUNT) + { + struct alpha_thread_state regs; + reg_size = ALPHA_THREAD_STATE_COUNT; + thread_get_state (thread, ALPHA_THREAD_STATE, + (thread_state_t) ®s, ®_size); + regs.r30 = (natural_t) arg_pos; + regs.pc = (natural_t) startpc; + thread_set_state (thread, ALPHA_THREAD_STATE, + (thread_state_t) ®s, reg_size); + } +#else +# error needs to be ported +#endif + thread_resume (thread); mach_port_deallocate (mach_task_self (), thread); return 0; } +const char *argp_program_version = STANDARD_HURD_VERSION (boot); + +static struct argp_option options[] = +{ + { "boot-root", 'D', "DIR", 0, + "Root of a directory tree in which to find files specified in BOOT-SCRIPT" }, + { "single-user", 's', 0, 0, + "Boot in single user mode" }, + { "kernel-command-line", 'c', "COMMAND LINE", 0, + "Simulated multiboot command line to supply" }, + { "pause" , 'd', 0, 0, + "Pause for user confirmation at various times during booting" }, + { "isig", 'I', 0, 0, + "Do not disable terminal signals, so you can suspend and interrupt boot."}, + { "device", 'f', "device_name=device_file", 0, + "Specify a device file used by subhurd and its virtual name."}, + { 0 } +}; +static char args_doc[] = "BOOT-SCRIPT"; +static char doc[] = "Boot a second hurd"; + +struct dev_map +{ + char *name; + mach_port_t port; + struct dev_map *next; +}; + +static struct dev_map *dev_map_head; + +static struct dev_map *add_dev_map (char *dev_name, char *dev_file) +{ + struct dev_map *map = malloc (sizeof (*map)); + + assert (map); + map->name = dev_name; + map->port = file_name_lookup (dev_file, 0, 0); + if (map->port == MACH_PORT_NULL) + error (1, errno, "file_name_lookup: %s", dev_file); + map->next = dev_map_head; + dev_map_head = map; + return map; +} + +static struct dev_map *lookup_dev (char *dev_name) +{ + struct dev_map *map; + + for (map = dev_map_head; map; map = map->next) + { + if (strcmp (map->name, dev_name) == 0) + return map; + } + return NULL; +} + +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + char *dev_file; + + switch (key) + { + size_t len; + + case 'c': kernel_command_line = arg; break; + + case 'D': useropen_dir = arg; break; + + case 'I': isig = 1; break; + + case 's': case 'd': + len = strlen (bootstrap_args); + if (len >= sizeof bootstrap_args - 1) + argp_error (state, "Too many bootstrap args"); + bootstrap_args[len++] = key; + bootstrap_args[len] = '\0'; + break; + + case 'f': + dev_file = strchr (arg, '='); + if (dev_file == NULL) + return ARGP_ERR_UNKNOWN; + *dev_file = 0; + add_dev_map (arg, dev_file+1); + break; + + case ARGP_KEY_ARG: + if (state->arg_num == 0) + bootscript = arg; + else + return ARGP_ERR_UNKNOWN; + break; + + case ARGP_KEY_INIT: + state->child_inputs[0] = state->input; break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + int main (int argc, char **argv, char **envp) { + error_t err; mach_port_t foo; - static const char usagemsg[] - = "Usage: boot [-D dir] [SWITCHES] SCRIPT ROOT-DEVICE\n"; char *buf = 0; - char *bootscript; int i, len; - char *newargs; + char *root_store_name; + const struct argp_child kids[] = { { &store_argp }, { 0 }}; + struct argp argp = { options, parse_opt, args_doc, doc, kids }; + struct store_argp_params store_argp_params = { 0 }; + + argp_parse (&argp, argc, argv, 0, 0, &store_argp_params); + err = store_parsed_name (store_argp_params.result, &root_store_name); + if (err) + error (2, err, "store_parsed_name"); + + err = store_parsed_open (store_argp_params.result, 0, &root_store); + if (err) + error (4, err, "%s", root_store_name); get_privileged_ports (&privileged_host_port, &master_device_port); defpager = MACH_PORT_NULL; vm_set_default_memory_manager (privileged_host_port, &defpager); - if (argc < 2 || (argv[1][0] == '-' && argc < 3)) - { - usage: - write (2, usagemsg, sizeof usagemsg); - host_exit (1); - } + strcat (bootstrap_args, "f"); - if (!strcmp (argv[1], "-D")) - { - if (argc < 4) - goto usage; - useropen_dir = argv[2]; - argv += 2; - } + mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET, + &receive_set); - if (argv[1][0] != '-') - { - bootstrap_args = "-x"; - bootscript = argv[1]; - bootdevice = argv[2]; - } + if (root_store->class == &store_device_class && root_store->name + && (root_store->flags & STORE_ENFORCED) + && root_store->num_runs == 1 && root_store->runs[0].start == 0) + /* Let known device nodes pass through directly. */ + bootdevice = root_store->name; else + /* Pass a magic value that we can use to do I/O to ROOT_STORE. */ { - bootstrap_args = argv[1]; - bootscript = argv[2]; - bootdevice = argv[3]; + bootdevice = "pseudo-root"; + mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, + &pseudo_root); + mach_port_move_member (mach_task_self (), pseudo_root, receive_set); } - newargs = malloc (strlen (bootstrap_args) + 2); - strcpy (newargs, bootstrap_args); - strcat (newargs, "f"); - bootstrap_args = newargs; - - mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET, - &receive_set); - mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, &pseudo_master_device_port); mach_port_insert_right (mach_task_self (), @@ -458,13 +590,21 @@ main (int argc, char **argv, char **envp) if (foo != MACH_PORT_NULL) mach_port_deallocate (mach_task_self (), foo); + if (kernel_command_line == 0) + asprintf (&kernel_command_line, "%s %s root=%s", + argv[0], bootstrap_args, bootdevice); + /* Initialize boot script variables. */ if (boot_script_set_variable ("host-port", VAL_PORT, (int) privileged_host_port) || boot_script_set_variable ("device-port", VAL_PORT, - (int) pseudo_master_device_port) - || boot_script_set_variable ("root-device", VAL_STR, (int) bootdevice) - || boot_script_set_variable ("boot-args", VAL_STR, (int) bootstrap_args)) + (integer_t) pseudo_master_device_port) + || boot_script_set_variable ("kernel-command-line", VAL_STR, + (integer_t) kernel_command_line) + || boot_script_set_variable ("root-device", + VAL_STR, (integer_t) bootdevice) + || boot_script_set_variable ("boot-args", + VAL_STR, (integer_t) bootstrap_args)) { static const char msg[] = "error setting variable"; @@ -472,10 +612,38 @@ main (int argc, char **argv, char **envp) host_exit (1); } + /* Turn each `FOO=BAR' word in the command line into a boot script + variable ${FOO} with value BAR. */ + { + int len = strlen (kernel_command_line) + 1; + char *s = memcpy (alloca (len), kernel_command_line, len); + char *word; + + while ((word = strsep (&s, " \t")) != 0) + { + char *eq = strchr (word, '='); + if (eq == 0) + continue; + *eq++ = '\0'; + err = boot_script_set_variable (word, VAL_STR, (integer_t) eq); + if (err) + { + char *msg; + asprintf (&msg, "cannot set boot-script variable %s: %s\n", + word, boot_script_error_string (err)); + assert (msg); + write (2, msg, strlen (msg)); + free (msg); + host_exit (1); + } + } + } + /* Parse the boot script. */ { char *p, *line; - static const char filemsg[] = "Can't open boot script"; + static const char filemsg[] = "Can't open boot script\n"; + static const char memmsg[] = "Not enough memory\n"; int amt, fd, err; fd = open (bootscript, O_RDONLY, 0); @@ -485,6 +653,11 @@ main (int argc, char **argv, char **envp) host_exit (1); } p = buf = malloc (500); + if (!buf) + { + write (2, memmsg, sizeof (memmsg)); + host_exit (1); + } len = 500; amt = 0; while (1) @@ -500,6 +673,11 @@ main (int argc, char **argv, char **envp) len += 500; newbuf = realloc (buf, len); + if (!newbuf) + { + write (2, memmsg, sizeof (memmsg)); + host_exit (1); + } p = newbuf + (p - buf); buf = newbuf; } @@ -510,7 +688,7 @@ main (int argc, char **argv, char **envp) while (p < buf + amt && *p != '\n') p++; *p = '\0'; - err = boot_script_parse_line (line); + err = boot_script_parse_line (0, line); if (err) { char *str; @@ -552,6 +730,7 @@ main (int argc, char **argv, char **envp) int i = strlen (str); write (2, str, i); + write (2, "\n", 1); host_exit (1); } free (buf); @@ -568,206 +747,13 @@ main (int argc, char **argv, char **envp) FD_SET (0, &rmask); if (select (1, &rmask, 0, 0, 0) == 1) read_reply (); - else - { /* We hosed */ - perror ("select"); - exit (5); - } + else /* We hosed */ + error (5, errno, "select"); } /* mach_msg_server (request_server, __vm_page_size * 2, receive_set); */ } -/* Set up stack args the Mach way */ -void -set_mach_stack_args (user_task, - user_thread, - startpc, - va_alist) - task_t user_task; - thread_t user_thread; - char *startpc; - va_dcl -{ - /* This code is lifted from .../mk/bootstrap/load.c. */ - va_list argv_ptr; - char * arg_ptr; - - int arg_len; - int arg_count; - char * arg_pos; - unsigned int arg_item_len; - - /* - * Calculate the size of the argument list. - */ - va_start(argv_ptr); - arg_len = 0; - arg_count = 0; - for (;;) { - arg_ptr = va_arg(argv_ptr, char *); - if (arg_ptr == (char *)0) - break; - arg_count++; - arg_len += strlen(arg_ptr) + 1; /* space for '\0' */ - } - va_end(argv_ptr); - /* - * Add space for: - * arg_count - * pointers to arguments - * trailing 0 pointer - * dummy 0 pointer to environment variables - * and align to integer boundary - */ - arg_len += sizeof(integer_t) + (2 + arg_count) * sizeof(char *); - arg_len = (arg_len + (sizeof(integer_t) - 1)) & ~(sizeof(integer_t)-1); - - - /* This small piece is from .../mk/bootstrap/i386/exec.c. */ - { - vm_offset_t stack_start; - vm_offset_t stack_end; - struct i386_thread_state regs; - unsigned int reg_size; - -#define STACK_SIZE (1024 * 1024 * 16) - - /* - * Add space for 5 ints to arguments, for - * PS program. XXX - */ - arg_len += 5 * sizeof(int); - - /* - * Allocate stack. - */ - stack_end = VM_MAX_ADDRESS; - stack_start = VM_MAX_ADDRESS - STACK_SIZE; - (void)vm_allocate(user_task, - &stack_start, - (vm_size_t)(stack_end - stack_start), - FALSE); - - reg_size = i386_THREAD_STATE_COUNT; - (void)thread_get_state(user_thread, - i386_THREAD_STATE, - (thread_state_t)®s, - ®_size); - - regs.eip = (int) startpc; - regs.uesp = (int)((stack_end - arg_len) & ~(sizeof(int)-1)); - - (void)thread_set_state(user_thread, - i386_THREAD_STATE, - (thread_state_t)®s, - reg_size); - - arg_pos = (void *) regs.uesp; - } - - /* - * Copy out the arguments. - */ - { - vm_offset_t u_arg_start; - /* user start of argument list block */ - vm_offset_t k_arg_start; - /* kernel start of argument list block */ - vm_offset_t u_arg_page_start; - /* user start of args, page-aligned */ - vm_size_t arg_page_size; - /* page_aligned size of args */ - vm_offset_t k_arg_page_start; - /* kernel start of args, page-aligned */ - - register - char ** k_ap; /* kernel arglist address */ - char * u_cp; /* user argument string address */ - register - char * k_cp; /* kernel argument string address */ - register - int i; - - /* - * Get address of argument list in user space - */ - u_arg_start = (vm_offset_t)arg_pos; - - /* - * Round to page boundaries, and allocate kernel copy - */ - u_arg_page_start = trunc_page(u_arg_start); - arg_page_size = (vm_size_t)(round_page(u_arg_start + arg_len) - - u_arg_page_start); - - vm_allocate(mach_task_self(), - &k_arg_page_start, - (vm_size_t)arg_page_size, - TRUE); - - /* - * Set up addresses corresponding to user pointers - * in the kernel block - */ - k_arg_start = k_arg_page_start + (u_arg_start - u_arg_page_start); - - k_ap = (char **)k_arg_start; - - /* - * Start the strings after the arg-count and pointers - */ - u_cp = (char *)u_arg_start + arg_count * sizeof(char *) - + 2 * sizeof(char *) - + sizeof(integer_t); - k_cp = (char *)k_arg_start + arg_count * sizeof(char *) - + 2 * sizeof(char *) - + sizeof(integer_t); - - /* - * first the argument count - */ - *k_ap++ = (char *)(natural_t)arg_count; - - /* - * Then the strings and string pointers for each argument - */ - va_start(argv_ptr); - for (i = 0; i < arg_count; i++) { - arg_ptr = va_arg(argv_ptr, char *); - arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */ - - /* set string pointer */ - *k_ap++ = u_cp; - - /* copy string */ - bcopy(arg_ptr, k_cp, arg_item_len); - k_cp += arg_item_len; - u_cp += arg_item_len; - } - va_end(argv_ptr); - - /* - * last, the trailing 0 argument and a null environment pointer. - */ - *k_ap++ = (char *)0; - *k_ap = (char *)0; - - /* - * Now write all of this to user space. - */ - (void) vm_write(user_task, - u_arg_page_start, - k_arg_page_start, - arg_page_size); - - (void) vm_deallocate(mach_task_self(), - k_arg_page_start, - arg_page_size); - } -} - - void msg_thread() { @@ -793,7 +779,7 @@ struct qr struct qr *qrhead, *qrtail; /* Queue a read for later reply. */ -void +kern_return_t queue_read (enum read_type type, mach_port_t reply_port, mach_msg_type_name_t reply_type, @@ -801,9 +787,12 @@ queue_read (enum read_type type, { struct qr *qr; + qr = malloc (sizeof (struct qr)); + if (!qr) + return D_NO_MEMORY; + spin_lock (&queuelock); - qr = malloc (sizeof (struct qr)); qr->type = type; qr->reply_port = reply_port; qr->reply_type = reply_type; @@ -815,6 +804,7 @@ queue_read (enum read_type type, qrhead = qrtail = qr; spin_unlock (&queuelock); + return D_SUCCESS; } /* TRUE if there's data available on stdin, which should be used to satisfy @@ -837,7 +827,7 @@ read_reply () if (! spin_try_lock (&readlock)) return; - /* Since we're commited to servicing the read, no one else need do so. */ + /* Since we're committed to servicing the read, no one else need do so. */ should_read = 0; ioctl (0, FIONREAD, &avail); @@ -864,7 +854,7 @@ read_reply () spin_unlock (&queuelock); if (qr->type == DEV_READ) - vm_allocate (mach_task_self (), (vm_address_t *)&buf, qr->amount, 1); + buf = mmap (0, qr->amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); else buf = alloca (qr->amount); amtread = read (0, buf, qr->amount); @@ -1000,6 +990,8 @@ ds_device_open (mach_port_t master_port, mach_port_t *device, mach_msg_type_name_t *devicetype) { + struct dev_map *map; + if (master_port != pseudo_master_device_port) return D_INVALID_OPERATION; @@ -1015,6 +1007,20 @@ ds_device_open (mach_port_t master_port, *devicetype = MACH_MSG_TYPE_MAKE_SEND; return 0; } + else if (strcmp (name, "pseudo-root") == 0) + /* Magic root device. */ + { + *device = pseudo_root; + *devicetype = MACH_MSG_TYPE_MAKE_SEND; + return 0; + } + + map = lookup_dev (name); + if (map) + { + *devicetype = MACH_MSG_TYPE_MOVE_SEND; + return device_open (map->port, mode, "", device); + } *devicetype = MACH_MSG_TYPE_MOVE_SEND; return device_open (master_device_port, mode, name, device); @@ -1023,7 +1029,7 @@ ds_device_open (mach_port_t master_port, kern_return_t ds_device_close (device_t device) { - if (device != pseudo_console) + if (device != pseudo_console && device != pseudo_root) return D_NO_SUCH_DEVICE; return 0; } @@ -1035,24 +1041,34 @@ ds_device_write (device_t device, dev_mode_t mode, recnum_t recnum, io_buf_ptr_t data, - unsigned int datalen, + size_t datalen, int *bytes_written) { - if (device != pseudo_console) - return D_NO_SUCH_DEVICE; - -#if 0 - if (console_send_rights) + if (device == pseudo_console) { - mach_port_mod_refs (mach_task_self (), pseudo_console, - MACH_PORT_TYPE_SEND, -console_send_rights); - console_send_rights = 0; - } +#if 0 + if (console_send_rights) + { + mach_port_mod_refs (mach_task_self (), pseudo_console, + MACH_PORT_TYPE_SEND, -console_send_rights); + console_send_rights = 0; + } #endif - *bytes_written = write (1, data, datalen); + *bytes_written = write (1, data, datalen); - return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS); + return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS); + } + else if (device == pseudo_root) + { + size_t wrote; + if (store_write (root_store, recnum, data, datalen, &wrote) != 0) + return D_IO_ERROR; + *bytes_written = wrote; + return D_SUCCESS; + } + else + return D_NO_SUCH_DEVICE; } kern_return_t @@ -1062,24 +1078,34 @@ ds_device_write_inband (device_t device, dev_mode_t mode, recnum_t recnum, io_buf_ptr_inband_t data, - unsigned int datalen, + size_t datalen, int *bytes_written) { - if (device != pseudo_console) - return D_NO_SUCH_DEVICE; - -#if 0 - if (console_send_rights) + if (device == pseudo_console) { - mach_port_mod_refs (mach_task_self (), pseudo_console, - MACH_PORT_TYPE_SEND, -console_send_rights); - console_send_rights = 0; - } +#if 0 + if (console_send_rights) + { + mach_port_mod_refs (mach_task_self (), pseudo_console, + MACH_PORT_TYPE_SEND, -console_send_rights); + console_send_rights = 0; + } #endif - *bytes_written = write (1, data, datalen); + *bytes_written = write (1, data, datalen); - return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS); + return (*bytes_written == -1 ? D_IO_ERROR : D_SUCCESS); + } + else if (device == pseudo_root) + { + size_t wrote; + if (store_write (root_store, recnum, data, datalen, &wrote) != 0) + return D_IO_ERROR; + *bytes_written = wrote; + return D_SUCCESS; + } + else + return D_NO_SUCH_DEVICE; } kern_return_t @@ -1090,37 +1116,51 @@ ds_device_read (device_t device, recnum_t recnum, int bytes_wanted, io_buf_ptr_t *data, - unsigned int *datalen) + size_t *datalen) { - int avail; - - if (device != pseudo_console) - return D_NO_SUCH_DEVICE; + if (device == pseudo_console) + { + int avail; #if 0 - if (console_send_rights) - { - mach_port_mod_refs (mach_task_self (), pseudo_console, - MACH_PORT_TYPE_SEND, -console_send_rights); - console_send_rights = 0; - } + if (console_send_rights) + { + mach_port_mod_refs (mach_task_self (), pseudo_console, + MACH_PORT_TYPE_SEND, -console_send_rights); + console_send_rights = 0; + } #endif - spin_lock (&readlock); - ioctl (0, FIONREAD, &avail); - if (avail) - { - vm_allocate (mach_task_self (), (pointer_t *)data, bytes_wanted, 1); - *datalen = read (0, *data, bytes_wanted); - unlock_readlock (); - return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS); + spin_lock (&readlock); + ioctl (0, FIONREAD, &avail); + if (avail) + { + *data = mmap (0, bytes_wanted, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + *datalen = read (0, *data, bytes_wanted); + unlock_readlock (); + return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS); + } + else + { + kern_return_t err; + + unlock_readlock (); + err = queue_read (DEV_READ, reply_port, reply_type, bytes_wanted); + if (err) + return err; + return MIG_NO_REPLY; + } } - else + else if (device == pseudo_root) { - unlock_readlock (); - queue_read (DEV_READ, reply_port, reply_type, bytes_wanted); - return MIG_NO_REPLY; + *datalen = 0; + return + (store_read (root_store, recnum, bytes_wanted, (void **)data, datalen) == 0 + ? D_SUCCESS + : D_IO_ERROR); } + else + return D_NO_SUCH_DEVICE; } kern_return_t @@ -1131,43 +1171,70 @@ ds_device_read_inband (device_t device, recnum_t recnum, int bytes_wanted, io_buf_ptr_inband_t data, - unsigned int *datalen) + size_t *datalen) { - int avail; - - if (device != pseudo_console) - return D_NO_SUCH_DEVICE; + if (device == pseudo_console) + { + int avail; #if 0 - if (console_send_rights) - { - mach_port_mod_refs (mach_task_self (), pseudo_console, - MACH_PORT_TYPE_SEND, -console_send_rights); - console_send_rights = 0; - } + if (console_send_rights) + { + mach_port_mod_refs (mach_task_self (), pseudo_console, + MACH_PORT_TYPE_SEND, -console_send_rights); + console_send_rights = 0; + } #endif - spin_lock (&readlock); - ioctl (0, FIONREAD, &avail); - if (avail) - { - *datalen = read (0, data, bytes_wanted); - unlock_readlock (); - return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS); + spin_lock (&readlock); + ioctl (0, FIONREAD, &avail); + if (avail) + { + *datalen = read (0, data, bytes_wanted); + unlock_readlock (); + return (*datalen == -1 ? D_IO_ERROR : D_SUCCESS); + } + else + { + kern_return_t err; + + unlock_readlock (); + err = queue_read (DEV_READI, reply_port, reply_type, bytes_wanted); + if (err) + return err; + return MIG_NO_REPLY; + } } - else + else if (device == pseudo_root) { - unlock_readlock (); - queue_read (DEV_READI, reply_port, reply_type, bytes_wanted); - return MIG_NO_REPLY; + error_t err; + void *returned = data; + + *datalen = bytes_wanted; + err = + store_read (root_store, recnum, bytes_wanted, (void **)&returned, datalen); + + if (! err) + { + if (returned != data) + { + bcopy (returned, (void *)data, *datalen); + munmap ((caddr_t) returned, *datalen); + } + return D_SUCCESS; + } + else + return D_IO_ERROR; } + else + return D_NO_SUCH_DEVICE; } kern_return_t ds_xxx_device_set_status (device_t device, dev_flavor_t flavor, dev_status_t status, - u_int statu_cnt) + size_t statu_cnt) { if (device != pseudo_console) return D_NO_SUCH_DEVICE; @@ -1178,9 +1245,9 @@ kern_return_t ds_xxx_device_get_status (device_t device, dev_flavor_t flavor, dev_status_t status, - u_int *statuscnt) + size_t *statuscnt) { - if (device != pseudo_console) + if (device != pseudo_console && device != pseudo_root) return D_NO_SUCH_DEVICE; return D_INVALID_OPERATION; } @@ -1190,9 +1257,9 @@ ds_xxx_device_set_filter (device_t device, mach_port_t rec, int pri, filter_array_t filt, - unsigned int len) + size_t len) { - if (device != pseudo_console) + if (device != pseudo_console && device != pseudo_root) return D_NO_SUCH_DEVICE; return D_INVALID_OPERATION; } @@ -1205,7 +1272,7 @@ ds_device_map (device_t device, memory_object_t *pager, int unmap) { - if (device != pseudo_console) + if (device != pseudo_console && device != pseudo_root) return D_NO_SUCH_DEVICE; return D_INVALID_OPERATION; } @@ -1214,9 +1281,9 @@ kern_return_t ds_device_set_status (device_t device, dev_flavor_t flavor, dev_status_t status, - unsigned int statuslen) + size_t statuslen) { - if (device != pseudo_console) + if (device != pseudo_console && device != pseudo_root) return D_NO_SUCH_DEVICE; return D_INVALID_OPERATION; } @@ -1225,11 +1292,25 @@ kern_return_t ds_device_get_status (device_t device, dev_flavor_t flavor, dev_status_t status, - unsigned int *statuslen) + size_t *statuslen) { - if (device != pseudo_console) + if (device == pseudo_console) + return D_INVALID_OPERATION; + else if (device == pseudo_root) + if (flavor == DEV_GET_SIZE) + if (*statuslen < DEV_GET_SIZE_COUNT) + return D_INVALID_SIZE; + else + { + status[DEV_GET_SIZE_DEVICE_SIZE] = root_store->size; + status[DEV_GET_SIZE_RECORD_SIZE] = root_store->block_size; + *statuslen = DEV_GET_SIZE_COUNT; + return D_SUCCESS; + } + else + return D_INVALID_OPERATION; + else return D_NO_SUCH_DEVICE; - return D_INVALID_OPERATION; } kern_return_t @@ -1237,9 +1318,9 @@ ds_device_set_filter (device_t device, mach_port_t receive_port, int priority, filter_array_t filter, - unsigned int filterlen) + size_t filterlen) { - if (device != pseudo_console) + if (device != pseudo_console && device != pseudo_root) return D_NO_SUCH_DEVICE; return D_INVALID_OPERATION; } @@ -1383,15 +1464,18 @@ S_io_read (mach_port_t object, if (avail) { if (amount > *datalen) - vm_allocate (mach_task_self (), (vm_address_t *) data, amount, 1); + *data = mmap (0, amount, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); *datalen = read (0, *data, amount); unlock_readlock (); return *datalen == -1 ? errno : 0; } else { + kern_return_t err; unlock_readlock (); - queue_read (IO_READ, reply_port, reply_type, amount); + err = queue_read (IO_READ, reply_port, reply_type, amount); + if (err) + return err; return MIG_NO_REPLY; } } @@ -1554,11 +1638,16 @@ S_io_reauthenticate (mach_port_t object, { uid_t *gu, *au; gid_t *gg, *ag; - unsigned int gulen = 0, aulen = 0, gglen = 0, aglen = 0; + size_t gulen = 0, aulen = 0, gglen = 0, aglen = 0; + error_t err; + + err = mach_port_insert_right (mach_task_self (), object, object, + MACH_MSG_TYPE_MAKE_SEND); + assert_perror (err); if (! auth_server_authenticate (authserver, rend, MACH_MSG_TYPE_COPY_SEND, - object, MACH_MSG_TYPE_MAKE_SEND, + object, MACH_MSG_TYPE_COPY_SEND, &gu, &gulen, &au, &aulen, &gg, &gglen, @@ -1570,6 +1659,7 @@ S_io_reauthenticate (mach_port_t object, mig_deallocate ((vm_address_t) au, aulen * sizeof *gu); } mach_port_deallocate (mach_task_self (), rend); + mach_port_deallocate (mach_task_self (), object); return 0; } @@ -1581,9 +1671,9 @@ S_io_restrict_auth (mach_port_t object, mach_port_t *newobject, mach_msg_type_name_t *newobjtype, uid_t *uids, - u_int nuids, + size_t nuids, uid_t *gids, - u_int ngids) + size_t ngids) { if (object != pseudo_console) return EOPNOTSUPP; @@ -1730,7 +1820,14 @@ S_io_identity (mach_port_t obj, mach_msg_type_name_t *idtype, mach_port_t *fsid, mach_msg_type_name_t *fsidtype, - int *fileno) + ino_t *fileno) +{ + return EOPNOTSUPP; +} + +kern_return_t +S_io_revoke (mach_port_t obj, + mach_port_t reply, mach_msg_type_name_t replyPoly) { return EOPNOTSUPP; } @@ -1791,6 +1888,13 @@ kern_return_t S_term_get_nodename ) { return EOPNOTSUPP; } +kern_return_t S_term_get_peername +( + io_t terminal, + string_t name +) +{ return EOPNOTSUPP; } + kern_return_t S_term_set_filenode ( io_t terminal, 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)); diff --git a/boot/boot_script.h b/boot/boot_script.h index d2db1a14..62458693 100644 --- a/boot/boot_script.h +++ b/boot/boot_script.h @@ -1,5 +1,8 @@ /* Definitions for boot script parser for Mach. */ +#ifndef _boot_script_h +#define _boot_script_h + /* Written by Shantanu Goel (goel@cs.columbia.edu). */ /* Error codes returned by boot_script_parse_line() @@ -18,15 +21,19 @@ #define VAL_NONE 0 /* none -- function runs at exec time */ #define VAL_STR 1 /* string */ #define VAL_PORT 2 /* port */ +#define VAL_TASK 3 /* task port */ /* This structure describes a command. */ struct cmd { + /* Cookie passed in to boot_script_parse_line. */ + void *hook; + /* Path of executable. */ char *path; /* Task port. */ - mach_port_t task; + task_t task; /* Argument list. */ struct arg **args; @@ -48,19 +55,37 @@ struct cmd }; +/* The user must define these functions, we work like malloc and free. */ +void *boot_script_malloc (unsigned int); +void boot_script_free (void *, unsigned int); + /* The user must define this function. Load the image of the executable specified by PATH in TASK. Create a thread in TASK and point it at the executable's entry point. Initialize TASK's stack with argument vector ARGV of length ARGC whose strings are STRINGS. STRINGS has length STRINGLEN. Return 0 for success, non-zero otherwise. */ -int boot_script_exec_cmd (mach_port_t task, char *path, int argc, +int boot_script_exec_cmd (void *hook, + task_t task, char *path, int argc, char **argv, char *strings, int stringlen); /* The user must define this function. Load the contents of FILE into a fresh anonymous memory object and return the memory object port. */ mach_port_t boot_script_read_file (const char *file); +/* The user must define this functions to perform the corresponding + Mach task manipulations. */ +int boot_script_task_create (struct cmd *); /* task_create + task_suspend */ +int boot_script_task_resume (struct cmd *); +int boot_script_prompt_task_resume (struct cmd *); +int boot_script_insert_right (struct cmd *, mach_port_t, mach_port_t *namep); +int boot_script_insert_task_port (struct cmd *, task_t, mach_port_t *namep); + +/* The user must define this function to clean up the `task_t' + returned by boot_script_task_create. */ +void boot_script_free_task (task_t task, int aborting); + + /* Parse the command line LINE. This causes the command line to be converted into an internal format. Returns 0 for success, non-zero otherwise. @@ -68,7 +93,7 @@ mach_port_t boot_script_read_file (const char *file); NOTE: The parser writes into the line so it must not be a string constant. It is also the responsibility of the caller not to deallocate the line across calls to the parser. */ -int boot_script_parse_line (char *cmdline); +int boot_script_parse_line (void *hook, char *cmdline); /* Execute the command lines prevously parsed. Returns 0 for success, non-zero otherwise. */ @@ -77,14 +102,15 @@ int boot_script_exec (void); /* Create an entry in the symbol table for variable NAME, whose type is TYPE and value is VAL. Returns 0 on success, non-zero otherwise. */ -int boot_script_set_variable (const char *name, int type, int val); +int boot_script_set_variable (const char *name, int type, integer_t 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)); /* Returns a string describing the error ERR. */ char *boot_script_error_string (int err); - -void safe_gets (char *, int); + +#endif /* _boot_script_h */ diff --git a/boot/tcattr.c b/boot/tcattr.c deleted file mode 100644 index fcd3293e..00000000 --- a/boot/tcattr.c +++ /dev/null @@ -1,592 +0,0 @@ -/* Copyright (C) 1991, 1993, 1995 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ - -#include <errno.h> -#include <stddef.h> -#include <termios.h> - -#undef B0 -#undef B50 -#undef B75 -#undef B110 -#undef B134 -#undef B150 -#undef B200 -#undef B300 -#undef B600 -#undef B1200 -#undef B1800 -#undef B2400 -#undef B4800 -#undef B9600 -#undef B19200 -#undef B38400 -#undef EXTA -#undef EXTB -#undef ECHO -#undef TOSTOP -#undef NOFLSH -#undef MDMBUF -#undef FLUSHO -#undef PENDIN -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS -#undef CERASE -#undef CKILL -#undef CINTR -#undef CQUIT -#undef CSTART -#undef CSTOP -#undef CEOF -#undef CEOT -#undef CBRK -#undef CSUSP -#undef CDSUSP -#undef CRPRNT -#undef CFLUSH -#undef CWERASE -#undef CLNEXT -#undef CSTATUS - -#define IOCPARM_MASK 0x7f -#define IOC_OUT 0x40000000 -#define IOC_IN 0x80000000 -#define _IOR(x,y,t) (IOC_OUT|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y) -#define _IOW(x,y,t) (IOC_IN|((sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y) -#define FIONREAD _IOR('f', 127, int) -#define FIOASYNC _IOW('f', 125, int) -#define TIOCGETP _IOR('t', 8, struct sgttyb) -#define TIOCLGET _IOR('t', 124, int) -#define TIOCLSET _IOW('t', 125, int) -#define TIOCSETN _IOW('t', 10, struct sgttyb) -#define TIOCSETP _IOW('t', 9,struct sgttyb)/* set parameters -- stty */ -#define TIOCFLUSH _IOW('t', 16, int) /* flush buffers */ -#define TIOCSETC _IOW('t',17,struct tchars)/* set special characters */ -#define TIOCGETC _IOR('t',18,struct tchars)/* get special characters */ -#define TANDEM 0x00000001 /* send stopc on out q full */ -#define CBREAK 0x00000002 /* half-cooked mode */ -#define LCASE 0x00000004 /* simulate lower case */ -#define ECHO 0x00000008 /* echo input */ -#define CRMOD 0x00000010 /* map \r to \r\n on output */ -#define RAW 0x00000020 /* no i/o processing */ -#define ODDP 0x00000040 /* get/send odd parity */ -#define EVENP 0x00000080 /* get/send even parity */ -#define ANYP 0x000000c0 /* get any parity/send none */ -#define PRTERA 0x00020000 /* \ ... / erase */ -#define CRTERA 0x00040000 /* " \b " to wipe out char */ -#define TILDE 0x00080000 /* hazeltine tilde kludge */ -#define MDMBUF 0x00100000 /* start/stop output on carrier intr */ -#define LITOUT 0x00200000 /* literal output */ -#define TOSTOP 0x00400000 /* SIGSTOP on background output */ -#define FLUSHO 0x00800000 /* flush output to terminal */ -#define NOHANG 0x01000000 /* no SIGHUP on carrier drop */ -#define L001000 0x02000000 -#define CRTKIL 0x04000000 /* kill line with " \b " */ -#define PASS8 0x08000000 -#define CTLECH 0x10000000 /* echo control chars as ^X */ -#define PENDIN 0x20000000 /* tp->t_rawq needs reread */ -#define DECCTQ 0x40000000 /* only ^Q starts after ^S */ -#define NOFLSH 0x80000000 /* no output flush on signal */ -#define TIOCLSET _IOW('t', 125, int) /* set entire local mode word */ -#define TIOCLGET _IOR('t', 124, int) /* get local modes */ -#define LCRTBS (CRTBS>>16) -#define LPRTERA (PRTERA>>16) -#define LCRTERA (CRTERA>>16) -#define LTILDE (TILDE>>16) -#define LMDMBUF (MDMBUF>>16) -#define LLITOUT (LITOUT>>16) -#define LTOSTOP (TOSTOP>>16) -#define LFLUSHO (FLUSHO>>16) -#define LNOHANG (NOHANG>>16) -#define LCRTKIL (CRTKIL>>16) -#define LPASS8 (PASS8>>16) -#define LCTLECH (CTLECH>>16) -#define LPENDIN (PENDIN>>16) -#define LDECCTQ (DECCTQ>>16) -#define LNOFLSH (NOFLSH>>16) -#define TIOCSLTC _IOW('t',117,struct ltchars)/* set local special chars */ -#define TIOCGLTC _IOR('t',116,struct ltchars)/* get local special chars */ - - -#if defined(TIOCGETC) || defined(TIOCSETC) -/* Type of ARG for TIOCGETC and TIOCSETC requests. */ -struct tchars -{ - char t_intrc; /* Interrupt character. */ - char t_quitc; /* Quit character. */ - char t_startc; /* Start-output character. */ - char t_stopc; /* Stop-output character. */ - char t_eofc; /* End-of-file character. */ - char t_brkc; /* Input delimiter character. */ -}; - -#define _IOT_tchars /* Hurd ioctl type field. */ \ - _IOT (_IOTS (char), 6, 0, 0, 0, 0) -#endif - -#if defined(TIOCGLTC) || defined(TIOCSLTC) -/* Type of ARG for TIOCGLTC and TIOCSLTC requests. */ -struct ltchars -{ - char t_suspc; /* Suspend character. */ - char t_dsuspc; /* Delayed suspend character. */ - char t_rprntc; /* Reprint-line character. */ - char t_flushc; /* Flush-output character. */ - char t_werasc; /* Word-erase character. */ - char t_lnextc; /* Literal-next character. */ -}; - -#define _IOT_ltchars /* Hurd ioctl type field. */ \ - _IOT (_IOTS (char), 6, 0, 0, 0, 0) -#endif - -/* Type of ARG for TIOCGETP and TIOCSETP requests (and gtty and stty). */ -struct sgttyb -{ - char sg_ispeed; /* Input speed. */ - char sg_ospeed; /* Output speed. */ - char sg_erase; /* Erase character. */ - char sg_kill; /* Kill character. */ - short int sg_flags; /* Mode flags. */ -}; - - - - -const speed_t __bsd_speeds[] = - { - 0, - 50, - 75, - 110, - 134, - 150, - 200, - 300, - 600, - 1200, - 1800, - 2400, - 4800, - 9600, - 19200, - 38400, - }; - -extern int ioctl (); - -/* Set the state of FD to *TERMIOS_P. */ -int -tcsetattr (int fd, int optional_actions, const struct termios *termios_p) -{ - struct sgttyb buf; - struct tchars tchars; - struct ltchars ltchars; - int local; -#ifdef TIOCGETX - int extra; -#endif - size_t i; - - if (ioctl(fd, TIOCGETP, &buf) < 0 || - ioctl(fd, TIOCGETC, &tchars) < 0 || - ioctl(fd, TIOCGLTC, <chars) < 0 || -#ifdef TIOCGETX - ioctl(fd, TIOCGETX, &extra) < 0 || -#endif - ioctl(fd, TIOCLGET, &local) < 0) - return -1; - - if (termios_p == NULL) - { - errno = EINVAL; - return -1; - } - - buf.sg_ispeed = buf.sg_ospeed = -1; - for (i = 0; i <= sizeof (__bsd_speeds) / sizeof (__bsd_speeds[0]); ++i) - { - if (__bsd_speeds[i] == termios_p->__ispeed) - buf.sg_ispeed = i; - if (__bsd_speeds[i] == termios_p->__ospeed) - buf.sg_ospeed = i; - } - if (buf.sg_ispeed == -1 || buf.sg_ospeed == -1) - { - errno = EINVAL; - return -1; - } - - buf.sg_flags &= ~(CBREAK|RAW); - if (!(termios_p->c_lflag & ICANON)) - buf.sg_flags |= (termios_p->c_cflag & ISIG) ? CBREAK : RAW; -#ifdef LPASS8 - if (termios_p->c_oflag & CS8) - local |= LPASS8; - else - local &= ~LPASS8; -#endif - if (termios_p->c_lflag & _NOFLSH) - local |= LNOFLSH; - else - local &= ~LNOFLSH; - if (termios_p->c_oflag & OPOST) - local &= ~LLITOUT; - else - local |= LLITOUT; -#ifdef TIOCGETX - if (termios_p->c_lflag & ISIG) - extra &= ~NOISIG; - else - extra |= NOISIG; - if (termios_p->c_cflag & CSTOPB) - extra |= STOPB; - else - extra &= ~STOPB; -#endif - if (termios_p->c_iflag & ICRNL) - buf.sg_flags |= CRMOD; - else - buf.sg_flags &= ~CRMOD; - if (termios_p->c_iflag & IXOFF) - buf.sg_flags |= TANDEM; - else - buf.sg_flags &= ~TANDEM; - - buf.sg_flags &= ~(ODDP|EVENP); - if (!(termios_p->c_cflag & PARENB)) - buf.sg_flags |= ODDP | EVENP; - else if (termios_p->c_cflag & PARODD) - buf.sg_flags |= ODDP; - else - buf.sg_flags |= EVENP; - - if (termios_p->c_lflag & _ECHO) - buf.sg_flags |= ECHO; - else - buf.sg_flags &= ~ECHO; - if (termios_p->c_lflag & ECHOE) - local |= LCRTERA; - else - local &= ~LCRTERA; - if (termios_p->c_lflag & ECHOK) - local |= LCRTKIL; - else - local &= ~LCRTKIL; - if (termios_p->c_lflag & _TOSTOP) - local |= LTOSTOP; - else - local &= ~LTOSTOP; - - buf.sg_erase = termios_p->c_cc[VERASE]; - buf.sg_kill = termios_p->c_cc[VKILL]; - tchars.t_eofc = termios_p->c_cc[VEOF]; - tchars.t_intrc = termios_p->c_cc[VINTR]; - tchars.t_quitc = termios_p->c_cc[VQUIT]; - ltchars.t_suspc = termios_p->c_cc[VSUSP]; - tchars.t_startc = termios_p->c_cc[VSTART]; - tchars.t_stopc = termios_p->c_cc[VSTOP]; - - if (ioctl(fd, TIOCSETP, &buf) < 0 || - ioctl(fd, TIOCSETC, &tchars) < 0 || - ioctl(fd, TIOCSLTC, <chars) < 0 || -#ifdef TIOCGETX - ioctl(fd, TIOCSETX, &extra) < 0 || -#endif - ioctl(fd, TIOCLSET, &local) < 0) - return -1; - return 0; -} - - -#undef tcgetattr - -/* Put the state of FD into *TERMIOS_P. */ -int -tcgetattr (int fd, struct termios *termios_p) -{ - struct sgttyb buf; - struct tchars tchars; - struct ltchars ltchars; - int local; -#ifdef TIOCGETX - int extra; -#endif - - if (termios_p == NULL) - { - errno = EINVAL; - return -1; - } - - if (ioctl(fd, TIOCGETP, &buf) < 0 || - ioctl(fd, TIOCGETC, &tchars) < 0 || - ioctl(fd, TIOCGLTC, <chars) < 0 || -#ifdef TIOCGETX - ioctl(fd, TIOCGETX, &extra) < 0 || -#endif - ioctl(fd, TIOCLGET, &local) < 0) - return -1; - - termios_p->__ispeed = __bsd_speeds[(unsigned char) buf.sg_ispeed]; - termios_p->__ospeed = __bsd_speeds[(unsigned char) buf.sg_ospeed]; - - termios_p->c_iflag = 0; - termios_p->c_oflag = 0; - termios_p->c_cflag = 0; - termios_p->c_lflag = 0; - termios_p->c_oflag |= CREAD | HUPCL; -#ifdef LPASS8 - if (local & LPASS8) - termios_p->c_oflag |= CS8; - else -#endif - termios_p->c_oflag |= CS7; - if (!(buf.sg_flags & RAW)) - { - termios_p->c_iflag |= IXON; - termios_p->c_cflag |= OPOST; -#ifndef NOISIG - termios_p->c_lflag |= ISIG; -#endif - } - if ((buf.sg_flags & (CBREAK|RAW)) == 0) - termios_p->c_lflag |= ICANON; - if (!(buf.sg_flags & RAW) && !(local & LLITOUT)) - termios_p->c_oflag |= OPOST; - if (buf.sg_flags & CRMOD) - termios_p->c_iflag |= ICRNL; - if (buf.sg_flags & TANDEM) - termios_p->c_iflag |= IXOFF; -#ifdef TIOCGETX - if (!(extra & NOISIG)) - termios_p->c_lflag |= ISIG; - if (extra & STOPB) - termios_p->c_cflag |= CSTOPB; -#endif - - switch (buf.sg_flags & (EVENP|ODDP)) - { - case EVENP|ODDP: - break; - case ODDP: - termios_p->c_cflag |= PARODD; - default: - termios_p->c_cflag |= PARENB; - termios_p->c_iflag |= IGNPAR | INPCK; - break; - } - if (buf.sg_flags & ECHO) - termios_p->c_lflag |= _ECHO; - if (local & LCRTERA) - termios_p->c_lflag |= ECHOE; - if (local & LCRTKIL) - termios_p->c_lflag |= ECHOK; - if (local & LTOSTOP) - termios_p->c_lflag |= _TOSTOP; - if (local & LNOFLSH) - termios_p->c_lflag |= _NOFLSH; - - termios_p->c_cc[VEOF] = tchars.t_eofc; - termios_p->c_cc[VEOL] = '\n'; - termios_p->c_cc[VERASE] = buf.sg_erase; - termios_p->c_cc[VKILL] = buf.sg_kill; - termios_p->c_cc[VINTR] = tchars.t_intrc; - termios_p->c_cc[VQUIT] = tchars.t_quitc; - termios_p->c_cc[VSTART] = tchars.t_startc; - termios_p->c_cc[VSTOP] = tchars.t_stopc; - termios_p->c_cc[VSUSP] = ltchars.t_suspc; - termios_p->c_cc[VMIN] = -1; - termios_p->c_cc[VTIME] = -1; - - return 0; -} diff --git a/boot/userland-boot.c b/boot/userland-boot.c new file mode 100644 index 00000000..d048c00e --- /dev/null +++ b/boot/userland-boot.c @@ -0,0 +1,108 @@ +/* boot_script.c support functions for running in a Mach user task. + Copyright (C) 2001 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <mach.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <error.h> +#include "boot_script.h" + +void * +boot_script_malloc (unsigned int size) +{ + return malloc (size); +} + +void +boot_script_free (void *ptr, unsigned int size) +{ + free (ptr); +} + + +int +boot_script_task_create (struct cmd *cmd) +{ + error_t err = task_create (mach_task_self (), 0, &cmd->task); + if (err) + { + error (0, err, "%s: task_create", cmd->path); + return BOOT_SCRIPT_MACH_ERROR; + } + err = task_suspend (cmd->task); + if (err) + { + error (0, err, "%s: task_resume", cmd->path); + return BOOT_SCRIPT_MACH_ERROR; + } + return 0; +} + +int +boot_script_task_resume (struct cmd *cmd) +{ + error_t err = task_resume (cmd->task); + if (err) + { + error (0, err, "%s: task_resume", cmd->path); + return BOOT_SCRIPT_MACH_ERROR; + } + return 0; +} + +int +boot_script_prompt_task_resume (struct cmd *cmd) +{ + char xx[5]; + + printf ("Hit return to resume %s...", cmd->path); + fgets (xx, sizeof xx, stdin); + + return boot_script_task_resume (cmd); +} + +void +boot_script_free_task (task_t task, int aborting) +{ + if (aborting) + task_terminate (task); + else + mach_port_deallocate (mach_task_self (), task); +} + +int +boot_script_insert_right (struct cmd *cmd, mach_port_t port, mach_port_t *name) +{ + error_t err = mach_port_insert_right (cmd->task, + port, port, MACH_MSG_TYPE_COPY_SEND); + if (err) + { + error (0, err, "%s: mach_port_insert_right", cmd->path); + return BOOT_SCRIPT_MACH_ERROR; + } + *name = port; + return 0; +} + +int +boot_script_insert_task_port (struct cmd *cmd, task_t task, mach_port_t *name) +{ + return boot_script_insert_right (cmd, task, name); +} |