diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | lib/libc/include/stdio.h | 2 | ||||
-rw-r--r-- | lib/libc/src/hyra/spawn.c | 7 | ||||
-rw-r--r-- | lib/libc/src/main.c | 7 | ||||
-rw-r--r-- | lib/libc/src/stdio/snprintf.c | 15 | ||||
-rw-r--r-- | lib/libc/src/stdio/vsnprintf.c | 6 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/proc_machdep.c | 3 | ||||
-rw-r--r-- | sys/dev/cons/cons.c | 28 | ||||
-rw-r--r-- | sys/dev/cons/cons_ansi.c | 3 | ||||
-rw-r--r-- | sys/dev/pci/pci.c | 77 | ||||
-rw-r--r-- | sys/fs/initramfs.c | 2 | ||||
-rw-r--r-- | sys/include/dev/acpi/tables.h | 30 | ||||
-rw-r--r-- | sys/include/dev/cons/cons.h | 1 | ||||
-rw-r--r-- | sys/include/dev/pci/pci.h | 1 | ||||
-rw-r--r-- | sys/include/sys/limits.h | 1 | ||||
-rw-r--r-- | sys/include/sys/proc.h | 2 | ||||
-rw-r--r-- | sys/include/sys/spawn.h | 2 | ||||
-rw-r--r-- | sys/kern/exec_elf64.c | 1 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 7 | ||||
-rw-r--r-- | sys/kern/kern_spawn.c | 53 | ||||
-rw-r--r-- | usr.bin/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/mex/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/mex/mex.c | 105 | ||||
-rw-r--r-- | usr.bin/osh/osh.c | 11 | ||||
-rw-r--r-- | usr.sbin/install/install.c | 4 |
26 files changed, 337 insertions, 42 deletions
diff --git a/configure.ac b/configure.ac index e8d4f38..3b89a07 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([Hyra], [1.9], [ian@osmora.org]) +AC_INIT([Hyra], [2.0], [ian@osmora.org]) TARGET="amd64" PROJECT_ROOT=`pwd` diff --git a/lib/libc/include/stdio.h b/lib/libc/include/stdio.h index d94990b..88e66f6 100644 --- a/lib/libc/include/stdio.h +++ b/lib/libc/include/stdio.h @@ -77,6 +77,8 @@ size_t fwrite(const void *__restrict ptr, size_t size, size_t n, FILE *__restric int vsnprintf(char *s, size_t size, const char *fmt, va_list ap); int snprintf(char *s, size_t size, const char *fmt, ...); + +int printf(const char *__restrict fmt, ...); int fputc(int c, FILE *stream); int putchar(int c); diff --git a/lib/libc/src/hyra/spawn.c b/lib/libc/src/hyra/spawn.c index 227d8f7..b4c92ef 100644 --- a/lib/libc/src/hyra/spawn.c +++ b/lib/libc/src/hyra/spawn.c @@ -35,10 +35,13 @@ * Spawn a process * * @pathname: Path to executable. + * @argv: Argument vector + * @envp: Environment vector * @flags: Spawn flags. */ pid_t -spawn(const char *pathname, int flags) +spawn(const char *pathname, char **argv, char **envp, int flags) { - return syscall(SYS_spawn, (uintptr_t)pathname, flags); + return syscall(SYS_spawn, (uintptr_t)pathname, (uintptr_t)argv, + (uintptr_t)envp, flags); } diff --git a/lib/libc/src/main.c b/lib/libc/src/main.c index d16b93e..16e27ad 100644 --- a/lib/libc/src/main.c +++ b/lib/libc/src/main.c @@ -38,10 +38,15 @@ int __libc_entry(uint64_t *ctx) { int status; + uint64_t argc; + char **argv; + + argc = *(ctx++); + argv = (char **)((ctx++)); if ((status = __libc_stdio_init()) != 0) { return status; } - return main(0, NULL); + return main(argc, argv); } diff --git a/lib/libc/src/stdio/snprintf.c b/lib/libc/src/stdio/snprintf.c index e343b77..2387950 100644 --- a/lib/libc/src/stdio/snprintf.c +++ b/lib/libc/src/stdio/snprintf.c @@ -30,6 +30,7 @@ #include <sys/types.h> #include <stdio.h> #include <stddef.h> +#include <unistd.h> /* TODO FIXME: Use stdarg.h */ #define __va_start(ap, fmt) __builtin_va_start(ap, fmt) @@ -46,3 +47,17 @@ snprintf(char *s, size_t size, const char *fmt, ...) __va_end(ap); return ret; } + +int +printf(const char *__restrict fmt, ...) +{ + char buf[512]; + va_list ap; + int ret; + + __va_start(ap, fmt); + ret = vsnprintf(buf, sizeof(buf), fmt, ap); + write(stdout->fd, buf, ret); + __va_end(ap); + return ret; +} diff --git a/lib/libc/src/stdio/vsnprintf.c b/lib/libc/src/stdio/vsnprintf.c index 0e29600..24b2df6 100644 --- a/lib/libc/src/stdio/vsnprintf.c +++ b/lib/libc/src/stdio/vsnprintf.c @@ -123,6 +123,12 @@ vsnprintf(char *s, size_t size, const char *fmt, va_list ap) num = __va_arg(ap, uint64_t); itoa(num, num_buf, 16); tmp_len = strlen(num_buf); + if (pad_width > 0) { + num_len = strlen(num_buf); + for (size_t i = num_len; i < pad_width; ++i) + printc(s, size, &off, '0'); + pad_width = 0; + } printstr(s, size, &off, num_buf + 2); break; case 's': diff --git a/sys/arch/amd64/amd64/proc_machdep.c b/sys/arch/amd64/amd64/proc_machdep.c index 407adb1..aa8847a 100644 --- a/sys/arch/amd64/amd64/proc_machdep.c +++ b/sys/arch/amd64/amd64/proc_machdep.c @@ -40,7 +40,7 @@ #include <vm/map.h> #include <string.h> -void +uintptr_t md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog) { uintptr_t *sp = stack_top; @@ -97,6 +97,7 @@ md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog) STACK_PUSH(sp, argc); tfp = &td->tf; tfp->rsp = (uintptr_t)sp - VM_HIGHER_HALF; + return tfp->rsp; } void diff --git a/sys/dev/cons/cons.c b/sys/dev/cons/cons.c index ce2b154..0735f11 100644 --- a/sys/dev/cons/cons.c +++ b/sys/dev/cons/cons.c @@ -65,7 +65,6 @@ static struct cdevsw cons_cdevsw; static void cons_draw_cursor(struct cons_screen *scr, uint32_t color); static int cons_handle_special(struct cons_screen *scr, char c); -static void cons_clear_scr(struct cons_screen *scr, uint32_t bg); static uint32_t rgb_invert(uint32_t rgb) @@ -191,22 +190,14 @@ cons_handle_special(struct cons_screen *scr, char c) SHOW_CURSOR(scr); return 0; case ASCII_LF: - HIDE_CURSOR(scr); - /* Are we past screen width? */ if (scr->ch_row >= scr->nrows - 1) { cons_clear_scr(scr, scr->bg); - cons_flush(scr); - scr->ch_col = 0; - scr->ch_row = 0; - - /* Update cursor */ - scr->curs_row = 0; - scr->curs_col = 0; - SHOW_CURSOR(scr); return 0; } + HIDE_CURSOR(scr); + /* Make a newline */ cons_flush(scr); ++scr->ch_row; @@ -255,18 +246,25 @@ cons_draw_cursor(struct cons_screen *scr, uint32_t color) * @scr: Screen to clear. * @bg: Color to clear it to. */ -static void +void cons_clear_scr(struct cons_screen *scr, uint32_t bg) { struct fbdev fbdev = scr->fbdev; - struct cons_buf *bp; + + cons_flush(scr); + HIDE_CURSOR(scr); + + scr->ch_col = 0; + scr->ch_row = 0; + scr->curs_col = 0; + scr->curs_row = 0; for (size_t i = 0; i < fbdev.height * fbdev.pitch; ++i) { scr->fb_mem[i] = bg; } - bp = scr->ob[scr->nrows - 1]; - bp->flags |= CONS_BUF_CLEAN; + SHOW_CURSOR(scr); + } /* diff --git a/sys/dev/cons/cons_ansi.c b/sys/dev/cons/cons_ansi.c index 4403f9c..ab1f22a 100644 --- a/sys/dev/cons/cons_ansi.c +++ b/sys/dev/cons/cons_ansi.c @@ -90,8 +90,7 @@ ansi_feed(struct ansi_state *statep, char c) return c; case 2: if (c == 'H') { - cons_reset_cursor(&g_root_scr); - ansi_reset(statep); + cons_clear_scr(&g_root_scr, g_root_scr.bg); return ANSI_UPDATE_CURSOR; } break; diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 95fc5e2..9dfb90e 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -32,20 +32,31 @@ #include <sys/syslog.h> #include <sys/errno.h> #include <sys/spinlock.h> +#include <sys/mmio.h> #include <dev/pci/pci.h> #include <dev/pci/pciregs.h> +#include <dev/acpi/acpi.h> +#include <dev/acpi/tables.h> #include <machine/pci/pci.h> #include <vm/dynalloc.h> +#include <vm/vm.h> #include <lib/assert.h> #define pr_trace(fmt, ...) kprintf("pci: " fmt, ##__VA_ARGS__) static TAILQ_HEAD(, pci_device) device_list; static struct spinlock devlist_lock = {0}; +static struct acpi_mcfg *mcfg; struct cam_hook { + /* PCI CAM */ pcireg_t(*cam_readl)(struct pci_device *dev, uint32_t off); void(*cam_writel)(struct pci_device *dev, uint32_t off, pcireg_t val); + + /* PCIe ECAM */ + pcireg_t(*ecam_readl)(struct pci_device *dev, uint32_t off); + void(*ecam_writel)(struct pci_device *dev, uint32_t off, pcireg_t val); + void *ecam_base[1]; } cam_hook = { NULL }; static bool @@ -129,6 +140,9 @@ pci_set_device_info(struct pci_device *dev) dev->prog_if = PCIREG_PROGIF(classrev); dev->hdr_type = (uint8_t)pci_readl(dev, PCIREG_HDRTYPE); + /* This is a PCIe device if it has CAP ID of 0x10 */ + dev->pci_express = pci_get_cap(dev, 0x10) != 0; + /* Set type-specific data */ switch (dev->hdr_type & ~BIT(7)) { case PCI_HDRTYPE_NORMAL: @@ -157,6 +171,53 @@ pci_set_device_info(struct pci_device *dev) static void pci_scan_bus(uint8_t bus); +static inline vaddr_t +pcie_ecam_addr(struct pci_device *dev) +{ + vaddr_t base = (vaddr_t)cam_hook.ecam_base[0]; + + base += dev->bus << 20 | + dev->slot << 15 | + dev->func << 12; + return base; +} + +static pcireg_t +pcie_ecam_readl(struct pci_device *dev, uint32_t offset) +{ + vaddr_t address; + + address = pcie_ecam_addr(dev); + address += (offset & ~3); + return mmio_read32((void *)address); +} + +static void +pcie_ecam_writel(struct pci_device *dev, uint32_t offset, pcireg_t val) +{ + vaddr_t address; + + address = pcie_ecam_addr(dev); + address += (offset & ~3); + mmio_write32((void *)address, val); +} + +static int +pcie_init(struct acpi_mcfg_base *base) +{ + void *iobase; + + pr_trace("[group %02d] @ bus [%02d - %02d]\n", base->seg_grpno, + base->bus_start, base->bus_end); + pr_trace("ecam @ %p\n", base->base_pa); + + iobase = PHYS_TO_VIRT(base->base_pa); + cam_hook.ecam_base[0] = iobase; + cam_hook.ecam_writel = pcie_ecam_writel; + cam_hook.ecam_readl = pcie_ecam_readl; + return 0; +} + /* * Attempt to register a device. * @@ -283,8 +344,10 @@ pci_add_device(struct pci_device *dev) pcireg_t pci_readl(struct pci_device *dev, uint32_t offset) { - if (cam_hook.cam_readl == NULL) { - return (pcireg_t)-1; + bool have_ecam = cam_hook.ecam_readl != NULL; + + if (dev->pci_express && have_ecam) { + return cam_hook.ecam_readl(dev, offset); } return cam_hook.cam_readl(dev, offset); @@ -293,7 +356,10 @@ pci_readl(struct pci_device *dev, uint32_t offset) void pci_writel(struct pci_device *dev, uint32_t offset, pcireg_t val) { - if (cam_hook.cam_writel == NULL) { + bool have_ecam = cam_hook.ecam_writel != NULL; + + if (dev->pci_express && have_ecam) { + cam_hook.ecam_writel(dev, offset, val); return; } @@ -306,6 +372,11 @@ pci_init(void) size_t ndev; TAILQ_INIT(&device_list); + mcfg = acpi_query("MCFG"); + if (mcfg != NULL) { + pcie_init(&mcfg->base[0]); + } + cam_hook.cam_readl = md_pci_readl; cam_hook.cam_writel = md_pci_writel; diff --git a/sys/fs/initramfs.c b/sys/fs/initramfs.c index b12a64b..c3f9b14 100644 --- a/sys/fs/initramfs.c +++ b/sys/fs/initramfs.c @@ -223,6 +223,8 @@ initramfs_read(struct vnode *vp, struct sio_txn *sio) return -EIO; if (sio->buf == NULL) return -EIO; + if (sio->len > n->size) + sio->len = n->size; src = n->data; dest = sio->buf; diff --git a/sys/include/dev/acpi/tables.h b/sys/include/dev/acpi/tables.h index 5215c86..d190150 100644 --- a/sys/include/dev/acpi/tables.h +++ b/sys/include/dev/acpi/tables.h @@ -132,4 +132,34 @@ struct __packed acpi_hpet { uint8_t page_protection; }; +/* + * PCIe / ACPI MCFG base address description + * table. + * + * @base_pa: Enhanced configuration base [physical] + * @seg_grpno: PCI segment group number + * @bus_start: Host bridge bus start + * @bus_end: Host bridge bus end + */ +struct __packed acpi_mcfg_base { + uint64_t base_pa; + uint16_t seg_grpno; + uint8_t bus_start; + uint8_t bus_end; + uint32_t reserved; +}; + +/* + * PCIe / ACPI MCFG structure + * + * @hdr: ACPI header + * @reserved: Do not use + * @base: ECAM MMIO address list + */ +struct __packed acpi_mcfg { + struct acpi_header hdr; + uint32_t reserved[2]; + struct acpi_mcfg_base base[1]; +}; + #endif /* _ACPI_TABLES_H_ */ diff --git a/sys/include/dev/cons/cons.h b/sys/include/dev/cons/cons.h index 9868493..7599dd5 100644 --- a/sys/include/dev/cons/cons.h +++ b/sys/include/dev/cons/cons.h @@ -67,6 +67,7 @@ struct cons_screen { void cons_init(void); void cons_expose(void); void cons_update_color(struct cons_screen *scr, uint32_t fg, uint32_t bg); +void cons_clear_scr(struct cons_screen *scr, uint32_t bg); void cons_reset_color(struct cons_screen *scr); void cons_reset_cursor(struct cons_screen *scr); int cons_putch(struct cons_screen *scr, char c); diff --git a/sys/include/dev/pci/pci.h b/sys/include/dev/pci/pci.h index a4de162..144b500 100644 --- a/sys/include/dev/pci/pci.h +++ b/sys/include/dev/pci/pci.h @@ -62,6 +62,7 @@ struct pci_device { uint8_t pci_subclass; uint8_t prog_if; uint8_t hdr_type; + uint8_t pci_express : 1; uint8_t pri_bus; uint8_t sec_bus; diff --git a/sys/include/sys/limits.h b/sys/include/sys/limits.h index 198c963..f56958e 100644 --- a/sys/include/sys/limits.h +++ b/sys/include/sys/limits.h @@ -32,6 +32,7 @@ #define PATH_MAX 1024 #define SSIZE_MAX 32767 +#define ARG_MAX 4096 #define CHAR_BIT 8 #if defined(_KERNEL) #define CPU_MAX 256 diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h index 2f1470a..241d990 100644 --- a/sys/include/sys/proc.h +++ b/sys/include/sys/proc.h @@ -95,7 +95,7 @@ int md_spawn(struct proc *p, struct proc *parent, uintptr_t ip); scret_t sys_spawn(struct syscall_args *scargs); pid_t spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **newprocp); -void md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog); +uintptr_t md_td_stackinit(struct proc *td, void *stack_top, struct exec_prog *prog); __dead void md_td_kick(struct proc *td); int fork1(struct proc *cur, int flags, void(*ip)(void), struct proc **newprocp); diff --git a/sys/include/sys/spawn.h b/sys/include/sys/spawn.h index 9d823db..0c54e4c 100644 --- a/sys/include/sys/spawn.h +++ b/sys/include/sys/spawn.h @@ -36,6 +36,6 @@ #define SPAWN_WAIT BIT(0) #if !defined(_KERNEL) -pid_t spawn(const char *pathname, int flags); +pid_t spawn(const char *pathname, char **argv, char **envp, int flags); #endif /* _KERNEL */ #endif /* !_SYS_SPAWN_H_ */ diff --git a/sys/kern/exec_elf64.c b/sys/kern/exec_elf64.c index 3767b0b..987dda4 100644 --- a/sys/kern/exec_elf64.c +++ b/sys/kern/exec_elf64.c @@ -192,6 +192,7 @@ elf64_load(const char *pathname, struct proc *td, struct exec_prog *prog) if ((status = elf64_verify(hdr)) != 0) goto done; + memset(loadmap, 0, sizeof(loadmap)); pcbp = &td->pcb; start = -1; end = 0; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index b760912..2a53b8a 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -101,7 +101,7 @@ execve(struct proc *td, const struct execve_args *args) stack_top = td->stack_base + (PROC_STACK_SIZE - 1); /* Setup registers, signals and stack */ - md_td_stackinit(td, (void *)(stack_top + VM_HIGHER_HALF), &prog); + stack_top = md_td_stackinit(td, (void *)(stack_top + VM_HIGHER_HALF), &prog); setregs(td, &prog, stack_top); signals_init(td); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 6afae81..2f9e344 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -137,6 +137,10 @@ exit1(struct proc *td, int flags) proc_reap(td); } + if (td->data != NULL) { + dynfree(td->data); + } + /* * Only free the process structure if we aren't * being waited on, otherwise let it be so the @@ -157,8 +161,6 @@ exit1(struct proc *td, int flags) ci->curtd = NULL; if (parent->pid == 0) sched_enter(); - if (td->data == NULL) - sched_enter(); parent->flags &= ~PROC_SLEEP; sched_enter(); @@ -175,7 +177,6 @@ sys_exit(struct syscall_args *scargs) { struct proc *td = this_td(); - td->data = scargs->tf; td->exit_status = scargs->arg0; exit1(td, 0); __builtin_unreachable(); diff --git a/sys/kern/kern_spawn.c b/sys/kern/kern_spawn.c index 60d8e22..a953a6e 100644 --- a/sys/kern/kern_spawn.c +++ b/sys/kern/kern_spawn.c @@ -45,10 +45,17 @@ #define pr_trace(fmt, ...) kprintf("spawn: " fmt, ##__VA_ARGS__) #define pr_error(...) pr_trace(__VA_ARGS__) +#define ARGVP_MAX (ARG_MAX / sizeof(void *)) + static volatile size_t nthreads = 0; +/* + * TODO: envp + */ struct spawn_args { char path[PATH_MAX]; + char argv_blk[ARG_MAX]; + char *argv[ARGVP_MAX]; }; static inline void @@ -67,7 +74,6 @@ spawn_thunk(void) struct proc *cur; struct execve_args execve_args; struct spawn_args *args; - char *argv[] = { NULL, NULL }; char *envp[] = { NULL }; cur = this_td(); @@ -76,13 +82,10 @@ spawn_thunk(void) memset(pathbuf, 0, sizeof(pathbuf)); memcpy(pathbuf, path, strlen(path)); - argv[0] = (char *)pathbuf; - execve_args.pathname = argv[0]; - execve_args.argv = argv; + execve_args.pathname = pathbuf; + execve_args.argv = (char **)&args->argv[0]; execve_args.envp = envp; - path = NULL; - dynfree(args); if (execve(cur, &execve_args) != 0) { pr_error("execve failed, aborting\n"); @@ -211,19 +214,26 @@ get_child(struct proc *cur, pid_t pid) /* * arg0: The file /path/to/executable - * arg1: Optional flags (`flags') + * arg1: Argv + * arg2: Envp (TODO) + * arg3: Optional flags (`flags') */ scret_t sys_spawn(struct syscall_args *scargs) { struct spawn_args *args; - const char *u_path; + char *path; + const char *u_path, **u_argv; + const char *u_p = NULL; struct proc *td; int flags, error; + size_t len, bytes_copied = 0; + size_t argv_i = 0; td = this_td(); - flags = scargs->arg1; u_path = (const char *)scargs->arg0; + u_argv = (const char **)scargs->arg1; + flags = scargs->arg3; args = dynalloc(sizeof(*args)); if (args == NULL) { @@ -236,5 +246,30 @@ sys_spawn(struct syscall_args *scargs) return error; } + memset(args->argv, 0, ARG_MAX); + for (size_t i = 0; i < ARG_MAX - 1; ++i) { + error = copyin(&u_argv[argv_i], &u_p, sizeof(u_p)); + if (error < 0) { + dynfree(args); + return error; + } + if (u_p == NULL) { + args->argv[argv_i++] = NULL; + break; + } + + path = &args->argv_blk[i]; + error = copyinstr(u_p, path, ARG_MAX - bytes_copied); + if (error < 0) { + dynfree(args); + return error; + } + + args->argv[argv_i++] = &args->argv_blk[i]; + len = strlen(path); + bytes_copied += (len + 1); + i += len; + } + return spawn(td, spawn_thunk, args, flags, NULL); } diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 80eafc7..779aacd 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -10,3 +10,4 @@ all: make -C fetch/ $(ARGS) make -C kfgwm/ $(ARGS) make -C time/ $(ARGS) + make -C mex/ $(ARGS) diff --git a/usr.bin/mex/Makefile b/usr.bin/mex/Makefile new file mode 100644 index 0000000..6c0db59 --- /dev/null +++ b/usr.bin/mex/Makefile @@ -0,0 +1,6 @@ +include user.mk + +CFILES = $(shell find . -name "*.c") + +$(ROOT)/base/usr/bin/mex: + gcc $(CFILES) -o $@ $(INTERNAL_CFLAGS) diff --git a/usr.bin/mex/mex.c b/usr.bin/mex/mex.c new file mode 100644 index 0000000..7e6f8aa --- /dev/null +++ b/usr.bin/mex/mex.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Hyra nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <unistd.h> +#include <stddef.h> +#include <fcntl.h> +#include <string.h> +#include <stdio.h> + +#define LINE_LEN 16 + +static void +dump_line(const char *line, size_t len) +{ + /* The amount of bytes we write */ + const uint8_t BYTE_COUNT = 2; + + for (size_t i = 0; i < LINE_LEN; ++i) { + if (i < len) { + printf("%02x", line[i] & 0xFF); + } else { + printf(" "); + } + + /* Put spacing between bytes */ + if (((i + 1) % BYTE_COUNT) == 0) { + printf(" "); + } + } + + printf(" "); + for (size_t i = 0; i < len; ++i) { + if (line[i] > 31 && line[i] < 127) { + printf("%c", line[i]); + } else { + printf("."); + } + } + + printf("\n"); +} + +static void +dump_file(int fd) +{ + char buf[LINE_LEN]; + ssize_t count; + size_t offset = 0; + + for (;;) { + count = read(fd, buf, sizeof(char) * LINE_LEN); + if (count <= 0) { + break; + } + + printf("%08x: ", offset); + offset += LINE_LEN; + dump_line(buf, count); + } +} + +int +main(int argc, char **argv) +{ + int fd; + + if (argc < 2) { + printf("mex: usage: mex <filename>\n"); + return -1; + } + + if ((fd = open(argv[1], O_RDONLY)) < 0) { + printf("mex: failed to open input\n"); + return fd; + } + + dump_file(fd); + return 0; +} diff --git a/usr.bin/osh/osh.c b/usr.bin/osh/osh.c index 93ac876..db8865d 100644 --- a/usr.bin/osh/osh.c +++ b/usr.bin/osh/osh.c @@ -56,6 +56,7 @@ "kfg - Start up kfgwm\n" \ "bell - Toggle backspace bell\n" \ "time - Get the current time\n" \ + "clear - Clear the screen\n" \ "exit - Exit the shell" #define PROMPT "[root::osmora]~ " @@ -106,6 +107,12 @@ cmd_echo(int argc, char *argv[]) } static void +cmd_clear(int argc, char *argv[]) +{ + fputs("\033[H", stdout); +} + +static void cmd_bell(int argc, char *argv[]) { const char *usage_str = "usage: bell [on/off]"; @@ -219,6 +226,7 @@ static int cmd_run(const char *input, int argc, char *argv[]) { char bin_path[256]; + char *envp[1] = { NULL }; int error; snprintf(bin_path, sizeof(bin_path), "/usr/bin/%s", input); @@ -228,7 +236,7 @@ cmd_run(const char *input, int argc, char *argv[]) return -1; } - if ((error = spawn(bin_path, SPAWN_WAIT)) < 0) { + if ((error = spawn(bin_path, argv, envp, SPAWN_WAIT)) < 0) { return error; } @@ -242,6 +250,7 @@ struct builtin_cmd cmds[] = { {"reboot",cmd_reboot}, {"shutdown", cmd_shutdown}, {"bell", cmd_bell}, + {"clear", cmd_clear}, {NULL, NULL} }; diff --git a/usr.sbin/install/install.c b/usr.sbin/install/install.c index 5cedc06..91f75df 100644 --- a/usr.sbin/install/install.c +++ b/usr.sbin/install/install.c @@ -82,6 +82,8 @@ installer_clearscr(uint32_t color, bool setattr) static void pre_installer(void) { + char *argv[] = { "/usr/bin/osh", NULL }; + char *envp[] = { NULL }; char c; puts("[S]hell/[I]nstall"); @@ -90,7 +92,7 @@ pre_installer(void) if (c == 's') { puts("\033[0m"); installer_clearscr(0x000000, false); - spawn("/usr/bin/osh", SPAWN_WAIT); + spawn(argv[0], argv, envp, SPAWN_WAIT); installer_clearscr(INSTALLER_BG, true); break; } else if (c == 'i') { |