(Don't) use this to implement short-form output in ls.
I'm too tired to make a nice column formatting algorithm.
I just wanted something concise when I type "ls".
...by adding a new class called Ext2Inode that inherits CoreInode.
The idea is that a vnode will wrap a CoreInode rather than InodeIdentifier.
Each CoreInode subclass can keep whatever caches they like.
Right now, Ext2Inode caches the list of block indices since it can be very
expensive to retrieve.
I was surprised to find that dup()'ed fds don't share the close-on-exec flag.
That means it has to be stored separately from the FileDescriptor object.
Pass the file name in a stack-allocated buffer instead of using an AK::String
when iterating directories. This dramatically reduces the amount of cycles
spent traversing the filesystem.
First of all, change sys$mmap to take a struct SC_mmap_params since our
sycsall calling convention can't handle more than 3 arguments.
This exposed a bug in Syscall::invoke() needing to use clobber lists.
It was a bit confusing to debug. :^)
This is dirty but pretty cool! If we have a pending, unmasked signal for
a process that's blocked inside the kernel, we set up alternate stacks
for that process and unblock it to execute the signal handler.
A slightly different return trampoline is used here: since we need to
get back into the kernel, a dedicated syscall is used (sys$sigreturn.)
This restores the TSS contents of the process to the state it was in
while we were originally blocking in the kernel.
NOTE: There's currently only one "kernel resume TSS" so signal nesting
definitely won't work.
It only works for sending a signal to a process that's in userspace code.
We implement reception by synthesizing a PUSHA+PUSHF in the receiving process
(operating on values in the TSS.)
The TSS CS:EIP is then rerouted to the signal handler and a tiny return
trampoline is constructed in a dedicated region in the receiving process.
Also hacked up /bin/kill to be able to send arbitrary signals (kill -N PID)
Implemented some syscalls: dup(), dup2(), getdtablesize().
FileHandle is now a retainable, since that's needed for dup()'ed fd's.
I didn't really test any of this beyond a basic smoke check.
This is quite cool! The syscall entry point plumbs the register dump
down to sys$fork(), which uses it to set up the child process's TSS
in order to resume execution right after the int 0x80 fork() call. :^)
This works pretty well, although there is some problem with the kernel
alias mappings used to clone the parent process's regions. If I disable
the MM::release_page_directory() code, there's no problem. Probably there's
a premature freeing of a physical page somehow.
Ran into a horrendous bug where VirtualConsole would overrun its buffer
and scribble right into some other object if we were interrupted while
processing a character. Slapped an InterruptDisabler onto onChar for now.
This provokes an interesting question though.. if a process is killed
while its in kernel space, how the heck do we release any locks it held?
I'm sure there are many different solutions to this problem, but I'll
have to think about it.
I ran out of steam writing library routines and imported two
BSD-licensed libc routines: sscanf() and getopt().
I will most likely rewrite them sooner or later. For now
I just wanted to see figlet running.
We now make three VirtualConsoles at boot: tty0, tty1, and tty2.
We launch an instance of /bin/sh in each one.
You switch between them with Alt+1/2/3
How very very cool :^)