summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in4
-rw-r--r--builddeps/user.mk3
-rw-r--r--sys/arch/amd64/amd64/proc_machdep.c23
-rw-r--r--sys/include/sys/driver.h2
-rw-r--r--sys/include/sys/proc.h5
-rw-r--r--sys/include/sys/sched.h2
-rw-r--r--sys/include/sys/spawn.h3
-rw-r--r--sys/kern/kern_descrip.c2
-rw-r--r--sys/kern/kern_exec.c2
-rw-r--r--sys/kern/kern_exit.c52
-rw-r--r--sys/kern/kern_sched.c67
-rw-r--r--sys/kern/kern_spawn.c26
-rw-r--r--usr.bin/Makefile1
-rw-r--r--usr.bin/fetch/Makefile6
-rw-r--r--usr.bin/fetch/fetch.c58
-rw-r--r--usr.bin/kmsg/Makefile6
-rw-r--r--usr.bin/kmsg/kmsg.c62
-rw-r--r--usr.bin/osh/osh.c31
18 files changed, 304 insertions, 51 deletions
diff --git a/Makefile.in b/Makefile.in
index 1270a21..508ee1c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -73,12 +73,12 @@ all: stand/boot/ libc sbin bin base/boot/hyra-kernel
.PHONY: sbin
sbin: $(SBIN_MAKEDIRS)
make -C usr.sbin/ LDSCRIPT=$(shell pwd)/usr.sbin/link.ld USRDIR=$(USRDIR)\
- ROOT=$(PROJECT_ROOT)\
+ ROOT=$(PROJECT_ROOT) OSVER=$(HYRA_VERSION) OSARCH=$(ARCH)
.PHONY: bin
bin: $(BIN_MAKEDIRS)
make -C usr.bin/ LDSCRIPT=$(shell pwd)/usr.bin/link.ld USRDIR=$(USRDIR)\
- ROOT=$(PROJECT_ROOT)
+ ROOT=$(PROJECT_ROOT) OSVER=$(HYRA_VERSION) OSARCH=$(ARCH)
.PHONY: libc
libc:
diff --git a/builddeps/user.mk b/builddeps/user.mk
index d7ad582..d991ef8 100644
--- a/builddeps/user.mk
+++ b/builddeps/user.mk
@@ -4,4 +4,5 @@ USRDIR =
LDSCRIPT =
INTERNAL_CFLAGS = -T$(LDSCRIPT) -znoexecstack -nostdlib -I$(USRDIR)/include/ \
-L$(USRDIR)/lib -lc -pie -no-pie -fno-stack-protector \
- -fno-asynchronous-unwind-tables
+ -fno-asynchronous-unwind-tables -D_OSVER=\"$(OSVER)\" \
+ -D_OSARCH=\"$(OSARCH)\"
diff --git a/sys/arch/amd64/amd64/proc_machdep.c b/sys/arch/amd64/amd64/proc_machdep.c
index f6b91f9..4fe8580 100644
--- a/sys/arch/amd64/amd64/proc_machdep.c
+++ b/sys/arch/amd64/amd64/proc_machdep.c
@@ -123,24 +123,37 @@ md_td_kick(struct proc *td)
{
struct trapframe *tfp;
struct cpu_info *ci;
+ uint8_t rpl;
+ uint16_t ds = KERNEL_DS;
tfp = &td->tf;
+ rpl = tfp->cs & 3;
ci = this_cpu();
ci->curtd = td;
+ if (rpl == 3) {
+ td->flags &= ~PROC_KTD;
+ ds = USER_DS | 3;
+ }
+
__ASMV(
- "push %0\n"
+ "mov %0, %%rax\n"
"push %1\n"
- "pushf\n"
"push %2\n"
"push %3\n"
+ "push %%rax\n"
+ "push %4\n"
+ "test $3, %%ax\n"
+ "jz 1f\n"
"lfence\n"
"swapgs\n"
- "iretq"
+ "1:\n"
+ " iretq"
:
- : "i" (USER_DS | 3),
+ : "r" (tfp->cs),
+ "r" (ds),
"r" (tfp->rsp),
- "i" (USER_CS | 3),
+ "m" (tfp->rflags),
"r" (tfp->rip)
);
diff --git a/sys/include/sys/driver.h b/sys/include/sys/driver.h
index 6e4a267..8ab9521 100644
--- a/sys/include/sys/driver.h
+++ b/sys/include/sys/driver.h
@@ -110,7 +110,7 @@ extern char __driversd_init_end[];
}
#define DRIVERS_SCHED() \
- spawn(&g_proc0,__driver_init_td, NULL, 0, NULL)
+ spawn(&g_proc0, __driver_init_td, NULL, 0, NULL)
void __driver_init_td(void);
diff --git a/sys/include/sys/proc.h b/sys/include/sys/proc.h
index 0a7d133..25f5fd3 100644
--- a/sys/include/sys/proc.h
+++ b/sys/include/sys/proc.h
@@ -64,7 +64,7 @@ struct proc {
struct trapframe tf;
struct pcb pcb;
struct proc *parent;
- void *spawn_data;
+ void *data;
size_t priority;
int exit_status;
bool rested;
@@ -84,9 +84,12 @@ struct proc {
#define PROC_LEAFQ BIT(3) /* Leaf queue is active */
#define PROC_WAITED BIT(4) /* Being waited on by parent */
#define PROC_KTD BIT(5) /* Kernel thread */
+#define PROC_SLEEP BIT(6) /* Thread execution paused */
struct proc *this_td(void);
struct proc *get_child(struct proc *cur, pid_t pid);
+void proc_reap(struct proc *td);
+
int md_spawn(struct proc *p, struct proc *parent, uintptr_t ip);
scret_t sys_spawn(struct syscall_args *scargs);
diff --git a/sys/include/sys/sched.h b/sys/include/sys/sched.h
index 80f4d1c..7d17607 100644
--- a/sys/include/sys/sched.h
+++ b/sys/include/sys/sched.h
@@ -37,6 +37,8 @@
void sched_init(void);
void sched_yield(void);
+
+void sched_switch_to(struct trapframe *tf, struct proc *td);
void sched_detach(struct proc *td);
__dead void sched_enter(void);
diff --git a/sys/include/sys/spawn.h b/sys/include/sys/spawn.h
index 3828d5c..9d823db 100644
--- a/sys/include/sys/spawn.h
+++ b/sys/include/sys/spawn.h
@@ -31,6 +31,9 @@
#define _SYS_SPAWN_H_
#include <sys/types.h>
+#include <sys/param.h>
+
+#define SPAWN_WAIT BIT(0)
#if !defined(_KERNEL)
pid_t spawn(const char *pathname, int flags);
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index dd14267..1992d46 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -187,6 +187,7 @@ fd_rw(unsigned int fd, void *buf, size_t count, uint8_t write)
sio.buf = kbuf;
sio.offset = filedes->offset;
+ spinlock_acquire(&filedes->lock);
if (write) {
/* Copy in user buffer */
if (copyin(buf, kbuf, count) < 0) {
@@ -224,6 +225,7 @@ done:
if (kbuf != NULL) {
dynfree(kbuf);
}
+ spinlock_release(&filedes->lock);
return retval;
}
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index bf6a26e..b760912 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -37,6 +37,7 @@
#include <vm/map.h>
#include <vm/physmem.h>
#include <machine/pcb.h>
+#include <machine/cdefs.h>
#include <string.h>
/*
@@ -87,6 +88,7 @@ execve(struct proc *td, const struct execve_args *args)
release_stack(td);
/* Save program state */
+ md_intoff();
memcpy(&td->exec, &prog, sizeof(td->exec));
/* Set new stack and map it to userspace */
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 242b221..b6cbc4e 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -78,6 +78,30 @@ unload_td(struct proc *td)
}
}
+void
+proc_reap(struct proc *td)
+{
+ struct pcb *pcbp;
+ uintptr_t stack;
+
+ pcbp = &td->pcb;
+ stack = td->stack_base;
+
+ /*
+ * If this is on the higher half, it is kernel
+ * mapped and we need to convert it to a physical
+ * address.
+ */
+ if (stack >= VM_HIGHER_HALF) {
+ stack -= VM_HIGHER_HALF;
+ }
+
+ unload_td(td);
+ vm_unmap(pcbp->addrsp, td->stack_base, PROC_STACK_SIZE);
+ vm_free_frame(stack, PROC_STACK_PAGES);
+ pmap_destroy_vas(pcbp->addrsp);
+}
+
/*
* Kill a thread and deallocate its resources.
*
@@ -86,20 +110,18 @@ unload_td(struct proc *td)
int
exit1(struct proc *td, int flags)
{
- struct pcb *pcbp;
struct proc *curtd, *procp;
+ struct proc *parent;
struct cpu_info *ci;
- uintptr_t stack;
pid_t target_pid, curpid;
ci = this_cpu();
target_pid = td->pid;
curtd = this_td();
- pcbp = &td->pcb;
curpid = curtd->pid;
- stack = td->stack_base;
td->flags |= PROC_EXITING;
+ parent = td->parent;
/* If we have any children, kill them too */
if (td->nleaves > 0) {
@@ -108,20 +130,10 @@ exit1(struct proc *td, int flags)
}
}
- /*
- * If this is on the higher half, it is kernel
- * mapped and we need to convert it to a physical
- * address.
- */
- if (stack >= VM_HIGHER_HALF) {
- stack -= VM_HIGHER_HALF;
+ if (target_pid != curpid) {
+ proc_reap(td);
}
- unload_td(td);
- vm_unmap(pcbp->addrsp, td->stack_base, PROC_STACK_SIZE);
- vm_free_frame(stack, PROC_STACK_PAGES);
- pmap_destroy_vas(pcbp->addrsp);
-
/*
* Only free the process structure if we aren't
* being waited on, otherwise let it be so the
@@ -139,6 +151,13 @@ exit1(struct proc *td, int flags)
*/
if (target_pid == curpid) {
ci->curtd = NULL;
+ if (parent->pid == 0)
+ sched_enter();
+ if (td->data == NULL)
+ sched_enter();
+
+ sched_enqueue_td(parent);
+ parent->flags &= ~PROC_SLEEP;
sched_enter();
}
@@ -153,6 +172,7 @@ 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_sched.c b/sys/kern/kern_sched.c
index 2fe0f32..8e456d2 100644
--- a/sys/kern/kern_sched.c
+++ b/sys/kern/kern_sched.c
@@ -104,12 +104,22 @@ sched_dequeue_td(void)
for (size_t i = 0; i < SCHED_NQUEUE; ++i) {
queue = &qlist[i];
- if (!TAILQ_EMPTY(&queue->q)) {
- td = TAILQ_FIRST(&queue->q);
- TAILQ_REMOVE(&queue->q, td, link);
- spinlock_release(&tdq_lock);
- return td;
+ if (TAILQ_EMPTY(&queue->q)) {
+ continue;
}
+
+ td = TAILQ_FIRST(&queue->q);
+ if (td == NULL) {
+ continue;
+ }
+
+ TAILQ_REMOVE(&queue->q, td, link);
+ if (ISSET(td->flags, PROC_SLEEP)) {
+ continue;
+ }
+
+ spinlock_release(&tdq_lock);
+ return td;
}
/* We got nothing */
@@ -125,6 +135,10 @@ sched_enqueue_td(struct proc *td)
{
struct sched_queue *queue;
+ if (ISSET(td->flags, PROC_SLEEP)) {
+ return;
+ }
+
spinlock_acquire(&tdq_lock);
queue = &qlist[td->priority];
@@ -176,15 +190,31 @@ td_pri_update(struct proc *td)
}
}
+void
+sched_switch_to(struct trapframe *tf, struct proc *td)
+{
+ struct cpu_info *ci;
+ struct pcb *pcbp;
+
+ ci = this_cpu();
+
+ if (tf != NULL) {
+ memcpy(tf, &td->tf, sizeof(*tf));
+ }
+
+ ci->curtd = td;
+ pcbp = &td->pcb;
+ pmap_switch_vas(pcbp->addrsp);
+}
+
/*
* Perform a context switch.
*/
void
sched_switch(struct trapframe *tf)
{
- struct cpu_info *ci;
- struct pcb *pcbp;
struct proc *next_td, *td;
+ struct cpu_info *ci;
ci = this_cpu();
td = ci->curtd;
@@ -203,11 +233,7 @@ sched_switch(struct trapframe *tf)
return;
}
- memcpy(tf, &next_td->tf, sizeof(*tf));
- ci->curtd = next_td;
- pcbp = &next_td->pcb;
-
- pmap_switch_vas(pcbp->addrsp);
+ sched_switch_to(tf, next_td);
sched_oneshot(false);
}
@@ -217,6 +243,7 @@ sched_switch(struct trapframe *tf)
void
sched_enter(void)
{
+ md_inton();
sched_oneshot(false);
for (;;) {
md_pause();
@@ -226,12 +253,20 @@ sched_enter(void)
void
sched_yield(void)
{
- struct proc *td = this_td();
+ struct proc *td;
+ struct cpu_info *ci = this_cpu();
- if (td != NULL) {
- td->rested = true;
- sched_switch(&td->tf);
+ if ((td = ci->curtd) == NULL) {
+ return;
}
+
+ td->rested = true;
+ ci->curtd = NULL;
+
+ md_inton();
+ sched_oneshot(false);
+ md_hlt();
+ ci->curtd = td;
}
void
diff --git a/sys/kern/kern_spawn.c b/sys/kern/kern_spawn.c
index 032ba24..4105668 100644
--- a/sys/kern/kern_spawn.c
+++ b/sys/kern/kern_spawn.c
@@ -27,6 +27,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <sys/spawn.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/mman.h>
@@ -70,7 +71,7 @@ spawn_thunk(void)
char *envp[] = { NULL };
cur = this_td();
- args = cur->spawn_data;
+ args = cur->data;
path = args->path;
memcpy(pathbuf, path, strlen(path));
@@ -110,6 +111,7 @@ spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **new
struct proc *newproc;
struct mmap_lgdr *mlgdr;
int error;
+ pid_t pid;
newproc = dynalloc(sizeof(*newproc));
if (newproc == NULL) {
@@ -150,7 +152,7 @@ spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **new
TAILQ_INSERT_TAIL(&cur->leafq, newproc, leaf_link);
atomic_inc_int(&cur->nleaves);
newproc->parent = cur;
- newproc->spawn_data = p;
+ newproc->data = p;
/* Initialize the mmap ledger */
mlgdr->nbytes = 0;
@@ -160,7 +162,25 @@ spawn(struct proc *cur, void(*func)(void), void *p, int flags, struct proc **new
newproc->pid = ++nthreads;
signals_init(newproc);
sched_enqueue_td(newproc);
- return newproc->pid;
+ pid = newproc->pid;
+
+ if (ISSET(flags, SPAWN_WAIT)) {
+ newproc->flags |= PROC_WAITED;
+ cur->flags |= PROC_SLEEP;
+
+ while (ISSET(cur->flags, PROC_SLEEP)) {
+ sched_yield();
+ }
+
+ if (!ISSET(newproc->flags, PROC_ZOMB)) {
+ pr_error("spawn: fatal: %d not zombie\n", newproc->pid);
+ panic("possibly memory corruption\n");
+ }
+
+ proc_reap(newproc);
+ }
+
+ return pid;
}
/*
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 1c973ff..09d593d 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -6,3 +6,4 @@ ARGS = -I$(ROOT)/builddeps LDSCRIPT=$(LDSCRIPT) USRDIR=$(USRDIR) ROOT=$(ROOT)
.PHONY: all
all:
make -C osh/ $(ARGS)
+ make -C kmsg/ $(ARGS)
diff --git a/usr.bin/fetch/Makefile b/usr.bin/fetch/Makefile
new file mode 100644
index 0000000..4b08e84
--- /dev/null
+++ b/usr.bin/fetch/Makefile
@@ -0,0 +1,6 @@
+include user.mk
+
+CFILES = $(shell find . -name "*.c")
+
+$(ROOT)/base/usr/bin/fetch:
+ gcc $(CFILES) -o $@ $(INTERNAL_CFLAGS)
diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c
new file mode 100644
index 0000000..98b2d3c
--- /dev/null
+++ b/usr.bin/fetch/fetch.c
@@ -0,0 +1,58 @@
+/*
+ * 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 <fcntl.h>
+#include <string.h>
+
+#define prcons(FD, STR) write((FD), (STR), strlen((STR)))
+
+#define ASCII_ART \
+ " ____ \n" \
+ " | \\__\\ \n" \
+ " | /\\ \\ user: root\n" \
+ " |/ \\ \\ OS: Hyra/amd64 v"_OSVER"\n" \
+ " \\ R. \\ \\ arch: "_OSARCH"\n" \
+ " \\ I. \\ \\\n"
+
+
+int
+main(void)
+{
+ int fd;
+
+ fd = open("/dev/console", O_WRONLY);
+ if (fd < 0) {
+ return fd;
+ }
+
+ prcons(fd, ASCII_ART);
+ close(fd);
+ return 0;
+}
diff --git a/usr.bin/kmsg/Makefile b/usr.bin/kmsg/Makefile
new file mode 100644
index 0000000..9b76cc2
--- /dev/null
+++ b/usr.bin/kmsg/Makefile
@@ -0,0 +1,6 @@
+include user.mk
+
+CFILES = $(shell find . -name "*.c")
+
+$(ROOT)/base/usr/bin/kmsg:
+ gcc $(CFILES) -o $@ $(INTERNAL_CFLAGS)
diff --git a/usr.bin/kmsg/kmsg.c b/usr.bin/kmsg/kmsg.c
new file mode 100644
index 0000000..678ad8c
--- /dev/null
+++ b/usr.bin/kmsg/kmsg.c
@@ -0,0 +1,62 @@
+/*
+ * 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 <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+int
+main(void)
+{
+ int mfd, cons_fd;
+ ssize_t retval;
+ char linebuf[256];
+
+ if ((mfd = open("/dev/kmsg", O_RDONLY)) < 0) {
+ return mfd;
+ }
+ if ((cons_fd = open("/dev/console", O_WRONLY)) < 0) {
+ close(mfd);
+ return cons_fd;
+ }
+
+ for (;;) {
+ retval = read(mfd, linebuf, sizeof(linebuf) - 1);
+ if (retval <= 0) {
+ break;
+ }
+ linebuf[retval] = '\0';
+ write(cons_fd, linebuf, strlen(linebuf));
+ }
+
+ close(cons_fd);
+ close(mfd);
+ return 0;
+}
diff --git a/usr.bin/osh/osh.c b/usr.bin/osh/osh.c
index c45d9c8..583f29a 100644
--- a/usr.bin/osh/osh.c
+++ b/usr.bin/osh/osh.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/reboot.h>
+#include <sys/spawn.h>
#include <fcntl.h>
#include <stddef.h>
#include <unistd.h>
@@ -49,6 +50,8 @@
"echo - Print the arguments to the console\n" \
"reboot - Reboot the machine\n" \
"shutdown - Power off the machine\n" \
+ "kmsg - Print kernel message buffer\n" \
+ "fetch - System information\n" \
"exit - Exit the shell\n"
#define PROMPT "[root::osmora]~ "
@@ -59,6 +62,7 @@ static int running;
struct command {
const char *name;
+ const char *path;
void (*func)(int fd, int argc, char *argv[]);
};
@@ -165,12 +169,27 @@ getstr(int fd)
}
}
+static void
+command_run(struct command *cmd, int fd, int argc, char *argv[])
+{
+ if (cmd->func != NULL) {
+ cmd->func(fd, argc, argv);
+ return;
+ }
+
+ if (cmd->path != NULL) {
+ spawn(cmd->path, SPAWN_WAIT);
+ }
+}
+
struct command cmds[] = {
- {"help", cmd_help},
- {"echo", cmd_echo},
- {"exit", cmd_exit},
- {"reboot", cmd_reboot},
- {"shutdown", cmd_shutdown},
+ {"help", NULL, cmd_help},
+ {"echo", NULL, cmd_echo},
+ {"exit", NULL, cmd_exit},
+ {"reboot", NULL, cmd_reboot},
+ {"shutdown", NULL, cmd_shutdown},
+ {"kmsg", "/usr/bin/kmsg", NULL},
+ {"fetch", "/usr/bin/fetch", NULL},
{NULL, NULL}
};
@@ -205,7 +224,7 @@ main(void)
for (i = 0; cmds[i].name != NULL; i++) {
if (strcmp(input, cmds[i].name) == 0) {
- cmds[i].func(fd, argc, argv);
+ command_run(&cmds[i], fd, argc, argv);
found = 1;
break;
}