Compare commits

...

1737 Commits

Author SHA1 Message Date
8e1a0d0e13
libos+LICENSE: Update copyright year
Some checks failed
Build and test / build (push) Failing after 1m37s
Happy new year!
2025-01-06 16:10:00 +01:00
773cd576d1
tools: Print clang-format version
Some checks failed
Build and test / build (push) Failing after 1m41s
2024-12-23 23:12:57 +01:00
498c371547
tools: Show format violations
Some checks failed
Build and test / build (push) Failing after 1m40s
2024-12-23 23:10:11 +01:00
b0be170b41
CI: Automatically check formatting
Some checks failed
Build and test / build (push) Failing after 1m40s
2024-12-23 23:05:04 +01:00
5cb4b8b1fe
docs: Add clang-format dependency
All checks were successful
Build and test / build (push) Successful in 1m41s
2024-12-23 22:59:57 +01:00
d9713723c9
tools: Update sources list and run clang-format 2024-12-23 22:56:56 +01:00
c0cf952113
docs: Clarify the wording in dependencies.md
All checks were successful
Build and test / build (push) Successful in 1m31s
2024-12-22 19:27:11 +01:00
22766a6724
docs: Correct a few details in boot_process.md
All checks were successful
Build and test / build (push) Successful in 1m35s
2024-12-21 13:40:53 +01:00
abdaad5ea4
docs: Update boot_process.md
All checks were successful
Build and test / build (push) Successful in 1m39s
2024-12-21 10:30:33 +01:00
f116afd59d
docs: Fix relative source path
All checks were successful
Build and test / build (push) Successful in 1m30s
2024-12-19 21:17:27 +01:00
1b80111938
Fix a couple of Markdown links
All checks were successful
Build and test / build (push) Successful in 1m37s
2024-12-19 21:15:22 +01:00
f91800f5e1
docs: Add dependency information separately
All checks were successful
Build and test / build (push) Successful in 1m41s
2024-12-19 21:12:49 +01:00
6dcdc43dc2
gui+su+base: Store hashed passwords and use those to log in
All checks were successful
Build and test / build (push) Successful in 1m34s
Unsalted SHA256 passwords are still a long way from being secure, but at least we're not storing plaintext anymore.
2024-12-14 12:48:13 +01:00
00382421b2
libluna: Add move versions of value_or 2024-12-14 12:46:36 +01:00
5d5c85a022
gui/InputField: Calculate correct length for the returned StringView 2024-12-14 12:46:14 +01:00
48ee803e58
init: Avoid "No child processes" error spam
All checks were successful
Build and test / build (push) Successful in 1m41s
2024-12-14 12:19:13 +01:00
984200ca9a
loginui: Pledge unix 2024-12-14 12:18:59 +01:00
ac260d0397
wind+libui: Add "pledge" functionality to access special features for system programs
All checks were successful
Build and test / build (push) Successful in 1m42s
This segments privileges more, making it so that any app connecting to wsys.sock can't just always access every single advanced feature in wind if they don't need to.
Of course, apps have to restrict themselves, which is why only privileged apps have access to this feature in the first place.
Normal apps' pledges are all empty and can't be changed.

An example: taskbar uses the "ExtendedLayers" pledge to move its window to the background, but relinquishes it afterwards, and doesn't need any other advanced feature for now.

If a pledge-capable app tries to use a pledge-protected function without having pledged anything, it can't. Pledges are mandatory if you want to access certain functionality, unlike the kernel's pledges which make every syscall available if you don't use pledge().
2024-12-13 23:47:53 +01:00
fb3333a086
wind: Remove special window attributes and add different window layers.
All checks were successful
Build and test / build (push) Successful in 1m38s
Two layers are accessible to all apps: global and global_top (for popups and similar windows).
Three other layers are accessible to privileged clients (background, system and lock), for things that need to be on a different level than user apps, like the taskbar, system popups, menus and the lock screen.
2024-12-13 21:53:12 +01:00
ccef3e2069
ports: Add cbench to the ports list
All checks were successful
Build and test / build (push) Successful in 1m41s
This was missed when adding the original cbench port.
2024-12-13 21:39:47 +01:00
ad3cea7e78
gui: Rename "launch" to "execd"
All checks were successful
Build and test / build (push) Successful in 1m42s
2024-12-11 20:34:47 +01:00
865a913502
wind: Fix help message when unprivileged
wind --user=<NAME> is not supported anymore. We'll setuid() and setgid() to wind:wind on our own.
2024-12-11 20:30:40 +01:00
499bf6dd19
gui+system: Add pledges to loginui and startui
All checks were successful
Build and test / build (push) Successful in 1m46s
2024-12-11 19:56:40 +01:00
94e7dde8af
kernel/waitpid: fix a panic-causing extraneous exclamation mark
Big oof moment.

Thankfully kernel panics sometimes just give you the exact source of the problem :P
"-- KERNEL PANIC: Check failed at kernel/src/sys/waitpid.cpp:67, in sys_waitpid: !target->dead() --"
2024-12-11 19:56:24 +01:00
f38c9e68c1
wind: Remove unneeded pledges
wind doesn't spawn child processes anymore, startui does.
2024-12-11 19:45:04 +01:00
3b8aabce0f
kernel: Add debug.cmake include to config.cmake template
All checks were successful
Build and test / build (push) Successful in 1m32s
2024-12-11 19:28:22 +01:00
5f56e4b63a
kernel: Disable UBSAN in debug.cmake
All checks were successful
Build and test / build (push) Successful in 1m42s
UBSAN seems to bloat the kernel too much, so let's make debug.cmake actually usable for debugging by commenting it out.
2024-12-11 19:19:36 +01:00
24b886b0d1
kernel: Log each thread's instruction pointer when dumping scheduler stats 2024-12-11 19:18:25 +01:00
d8e4489079
kernel: Make Thread::ip() and sp() const-friendly 2024-12-11 19:17:04 +01:00
2868fd8122
kernel: Add a way to lookup specific threads 2024-12-11 19:16:45 +01:00
56a2b607b5
kernel: Fix some debug-only log strings after the process rework 2024-12-11 19:16:22 +01:00
ec6ceb4c8d
init: Fix infinite wait loop
All checks were successful
Build and test / build (push) Successful in 1m51s
Since waitpid always sends a SIGCHLD now, we'd handle a SIGCHLD after returning from waitpid, which would trigger another wait, looping forever and not actually handling the wait.
2024-12-11 19:13:12 +01:00
d05d6fad0b
kernel: Interrupt waitpid (even when SIGCHLD is pending) when other signals are also pending
All checks were successful
Build and test / build (push) Successful in 1m36s
This fixes init not receiving the kill signal when running tests.
2024-12-07 13:15:58 +01:00
42afef5ccb
kernel: Leave reaping to the reap thread
Some checks failed
Build and test / build (push) Has been cancelled
This seems to fix previous problems. Apparently reaping a thread somewhat corrupts/replaces the calling thread's address space.

I should've known there's a reason we do it in a separate kernel thread...
2024-12-07 13:05:38 +01:00
853a6d7b38
kernel/x86_64: Dump the process address space ranges on exception 2024-12-07 13:02:25 +01:00
8e30e0e19d
base: Revert loginui.conf change
Some checks failed
Build and test / build (push) Failing after 3h10m29s
Oops, was using this for loginui testing, it should be turned off by default.
2024-12-06 21:38:29 +01:00
dc766e1da7
kernel: Rework VFS access checking + add processes
Some checks failed
Build and test / build (push) Has been cancelled
VFS functions now accept a single Process* pointer instead of credentials and groups.
There is now a distinction between processes and threads
Now to fix all the bugs... waitpid crashes the process with an NX error...
2024-12-06 21:35:59 +01:00
6fc49a0be5
init: Let's not forget to unhook our notifiers
All checks were successful
Build and test / build (push) Successful in 1m42s
2024-12-04 22:54:01 +01:00
7761a8a41f
kernel+launch: Always send SIGCHLD when a child exits
All checks were successful
Build and test / build (push) Successful in 1m44s
POSIX says so. I thought it was only when the parent wasn't actively waiting, to signal it, but it turns out it's always sent.
2024-12-04 22:44:16 +01:00
0ca6c5f814
taskbar: Remove sigchld handler
We are not launching child processes from taskbar anymore, that job is left to /bin/launch.
2024-12-04 22:42:59 +01:00
3032415bc0
kernel: Move "push_mem_on_stack" and "pop_mem_from_stack" to MemoryManager
All checks were successful
Build and test / build (push) Successful in 1m52s
2024-11-23 20:03:04 +01:00
7b2977a036
kernel: Use a mutex to allocate new posix timers for a thread 2024-11-23 20:02:34 +01:00
9e65131452
editor: Avoid showing an error dialog when pressing Ctrl+S
All checks were successful
Build and test / build (push) Successful in 1m52s
2024-10-26 14:00:57 +02:00
d908ccea6b
wind: Move some stuff from String to RefString 2024-10-26 14:00:26 +02:00
e3613d1653
loginui+2048: Replace String with RefString 2024-10-26 13:43:20 +02:00
53f8a583dc
libluna+libos+libui: Move Action to libluna and make it usable in the kernel
Some checks failed
Build and test / build (push) Failing after 1m21s
This commit adds an error-propagating constructor for Action and Function, which makes them usable in the kernel.
2024-10-19 21:25:17 +02:00
c21fc2a297
ports: Add cbench port
Some checks failed
Build and test / build (push) Failing after 1m37s
2024-09-23 19:51:42 +02:00
fd26f40938
editor: Add "Save file as..." and error dialogs
Some checks failed
Build and test / build (push) Failing after 1m32s
2024-09-19 18:27:16 +02:00
fd2fe16538
libui: Add Dialog 2024-09-19 18:26:58 +02:00
38fcd8e3e1
libos: Stop timers in the destructor if needed
Fixes some bug in InputField causing a crash.
2024-09-19 18:26:42 +02:00
05bf792dbd
libui: Make InputField final
Some checks failed
Build and test / build (push) Failing after 1m31s
2024-09-18 21:48:15 +02:00
b95cfac3ec
libui: Fix crashes when closing non-main windows
Some checks failed
Build and test / build (push) Has been cancelled
This fix moves the actual closing of the window to after all the events are processed.
2024-09-18 21:47:31 +02:00
17a31e5ea9
libos: Add more constructor variants for Action/Function 2024-09-18 21:44:46 +02:00
1f0286c9c7
base: Add taskbar entry for the editor
All checks were successful
Build and test / build (push) Successful in 1m51s
2024-09-14 15:40:27 +02:00
ffd1c73b0f
base: Start a welcome message instead of a terminal on login
All checks were successful
Build and test / build (push) Successful in 1m44s
2024-09-14 15:31:42 +02:00
12ab71ee40
libos: Support comments in config files
All checks were successful
Build and test / build (push) Successful in 1m45s
2024-09-14 15:12:36 +02:00
4cf39c14a1
base+gui: Move autologin configuration to /etc/loginui.conf
All checks were successful
Build and test / build (push) Successful in 1m45s
2024-09-14 15:05:05 +02:00
bbe1eca711
utils: Add a hackish "logout" command
All checks were successful
Build and test / build (push) Successful in 1m45s
2024-09-07 17:40:39 +02:00
e7d361ca51
startui: Remove /tmp/launch.sock as root
All checks were successful
Build and test / build (push) Successful in 1m51s
Fixes #47.
This avoids permission errors.
2024-09-07 17:33:38 +02:00
bb6759986e
libos/LocalServer: Clean up socket file on exit
This doesn't work if the process is killed by an unhandled signal.
2024-09-07 17:33:01 +02:00
4cc8a44ec7
all: Update release to 0.7.0 "Pulsar"
All checks were successful
Build and test / build (push) Successful in 1m57s
2024-09-07 17:17:08 +02:00
0a9578c1ec
libui/Font: Use RefString
All checks were successful
Build and test / build (push) Successful in 1m54s
2024-09-07 16:52:48 +02:00
1fc2da4fb0
taskbar: Use os::ConfigFile instead of manually parsing app files 2024-09-07 16:52:31 +02:00
9c4f20790f
CI: Undo artifact stuff
All checks were successful
Build and test / build (push) Successful in 1m55s
Doesn't seem to be really supported on Gitea for now.
2024-09-07 16:35:59 +02:00
0a143e8729
CI: Use different artifact provider
Some checks failed
Build and test / build (push) Failing after 1m52s
2024-09-01 14:17:22 +02:00
d4237d10a0
CI: Fix actions syntax
Some checks failed
Build and test / build (push) Failing after 2m6s
2024-09-01 14:12:45 +02:00
b24aa1821c
CI: Upload built ISOs
Some checks failed
Build and test / build (push) Failing after 0s
2024-09-01 14:11:54 +02:00
7c0ff8c75a
libos+init: Add a standard API for config file access
All checks were successful
Build and test / build (push) Successful in 1m50s
2024-09-01 12:40:37 +02:00
a11aa7a2d0
libluna: Add a reference-counted immutable string type 2024-09-01 12:40:20 +02:00
0abd9153ae
tools+libluna: Make new and delete weak to avoid conflicts with libstdc++
Wasn't causing problems earlier, but when trying to rebuild the toolchain, it failed because of this.
2024-09-01 12:39:55 +02:00
abbfd5825f
kernel: Make StorageCache have a reference to its parent BlockDevice
All checks were successful
Build and test / build (push) Successful in 2m10s
This will make it easier to implement sync later on.
2024-08-09 18:52:56 +02:00
bfb45c7d4a
gui: Add a login UI and support the os::IPC::Notifier API
All checks were successful
Build and test / build (push) Successful in 3m2s
2024-07-31 19:50:20 +02:00
d3fbddb191
taskbar: Use SIGQUIT to restart
Whenever a GUI session ends, SIGHUP is sent to all GUI processes. Previously, taskbar would catch this signal and wrongly restart.

Now, taskbar correctly dies alongside everyone else.
2024-07-31 19:46:02 +02:00
0ab8efd405
libos+init: Add a Notifier API to know when child processes have finished initialization
init now supports the "WaitUntilReady" key, which will wait until the child calls os::IPC::notify_parent().
2024-07-31 19:43:09 +02:00
2aefbdc4ee
libos: Fix Action 2024-07-31 19:32:47 +02:00
15dc71e8e1
libui/InputField: Fix a few bugs and add a clear() method 2024-07-31 19:32:22 +02:00
140910763e
all: Reorder directory structure
All checks were successful
Build and test / build (push) Successful in 1m56s
Why are command-line utilities stored in "apps"?
And why are apps like "editor" or "terminal" top-level directories?
Command-line utilities now go in "utils".
GUI stuff now goes in "gui".
This includes: libui -> gui/libui, wind -> gui/wind, GUI apps -> gui/apps, editor&terminal -> gui/apps...
System services go in "system".
2024-07-21 13:24:46 +02:00
829f455129
apps: Add arch
All checks were successful
Build and test / build (push) Successful in 2m16s
2024-07-21 13:07:51 +02:00
d10cb10404
libluna/SHA: Reuse the m_message buffer to avoid duplicating the data to hash
All checks were successful
Build and test / build (push) Successful in 2m14s
This change is almost insignificant in most cases, but it avoids using 4GB of memory to hash a 2GB file.
2024-07-21 12:52:12 +02:00
c97876bba0
kernel/ATA: Avoid assuming endianness 2024-07-21 12:51:06 +02:00
31c36b9b83
tests: Add tests for SHA256
All checks were successful
Build and test / build (push) Successful in 2m22s
2024-07-20 16:34:31 +02:00
5fe0507ab1
libc+libluna: Add endianness-dependent functions and use them in SHA256
All checks were successful
Build and test / build (push) Successful in 2m18s
2024-07-20 16:26:06 +02:00
e1c287a45b
libluna: Return a new Digest structure instead of a Buffer from SHA256
All checks were successful
Build and test / build (push) Successful in 2m30s
2024-07-20 16:12:43 +02:00
db2f91b1fb
libluna+apps: Add a SHA256 hash implementation
All checks were successful
Build and test / build (push) Successful in 2m26s
2024-07-20 15:50:59 +02:00
7345a952ca
libluna: Implement hash table iteration
All checks were successful
Build and test / build (push) Successful in 1m47s
2024-07-02 20:51:28 +02:00
903dcfa52c
libc: Partially implement freopen() when a null pathname is provided
All checks were successful
Build and test / build (push) Successful in 2m1s
The specification says "It is implementation-defined which changes of mode are permitted (if any)", so we can comply by not permitting any mode changes, at least for now.
2024-07-02 12:44:43 +02:00
2ce2d57eff
kernel: Prevent kernel threads from calling exit_and_signal_parent()
All checks were successful
Build and test / build (push) Successful in 1m53s
Kernel threads are supposed to use kernel_exit() instead, so it makes no sense to have an extra branch for them.
2024-06-23 22:53:30 +02:00
907049c405
kernel: Signal the reap thread when a kernel thread exits via exit_and_signal_parent()
All checks were successful
Build and test / build (push) Successful in 1m54s
This shouldn't happen, but just in case.
2024-05-02 10:58:34 +02:00
450ef2ce27
docs: Add boot_process.md 2024-05-02 10:57:46 +02:00
01dcb954e5
cp: Show an error message when attempting to copy a directory into a file
All checks were successful
Build and test / build (push) Successful in 2m12s
2024-05-01 18:55:34 +02:00
04649fce8a
base: Change ownership of skeleton files when copying them to the home folder 2024-05-01 18:55:18 +02:00
66983ce17c
base: Correct description for the login service 2024-05-01 18:54:53 +02:00
0a46cfc80c
libui: Remove the server->client message "WindowCloseRequest"
Some checks are pending
Build and test / build (push) Waiting to run
This is no longer used as the client manages its own close buttons.
2024-05-01 18:19:34 +02:00
fb52c67f16
kernel/x86_64: Map kernel-side pages as global to avoid TLB flushes
Some checks are pending
Build and test / build (push) Waiting to run
Fixes #34.
2024-05-01 18:14:43 +02:00
ab70a72434
kernel: Fix extra qualification in Thread.h
Some checks failed
Build and test / build (push) Failing after 12m15s
Forgot to build after writing the previous commit, but CI caught it anyway.
2024-05-01 10:54:59 +02:00
1d0f18cab9
kernel: Move stack checking and expansion into an architecture-independent file
Some checks failed
Build and test / build (push) Failing after 1m45s
2024-05-01 10:52:08 +02:00
de6f5c38d8
kernel: Try to grow the stack on stack overflows, up to a maximum of 8MB
All checks were successful
Build and test / build (push) Successful in 1m49s
This helps keep GCC happy when compiling slightly complex programs :)
2024-04-28 16:27:18 +02:00
e0ed4be0db
libos: Change the year in the default ArgumentParser copyright message
Some checks failed
Build and test / build (push) Failing after 12m48s
Almost four months into 2024, I finally remembered that I had to change this.
2024-04-20 17:24:26 +02:00
6293aeea58
shell: Split code into multiple files, add the "echo" builtin, and add support for a .shellrc file
All checks were successful
Build and test / build (push) Successful in 1m46s
2024-04-20 17:17:31 +02:00
646a15d295
Update README
All checks were successful
Build and test / build (push) Successful in 1m38s
2024-04-20 15:57:01 +02:00
b59a787b9e
kernel: Properly initialize the shebang read buffer with zeros
Some checks failed
Build and test / build (push) Failing after 11m23s
Before this patch, a shebang line that was too long could have left the buffer without a null terminator, allowing some other stack contents to pass into the m_interpreter_cmdline.
2024-04-18 21:55:16 +02:00
e2ff0ad273
libc: Propagate errors correctly in shadow functions
All checks were successful
Build and test / build (push) Successful in 2m58s
2024-04-18 21:25:36 +02:00
62cb53069c
libc: Close all pipe file descriptors in popen() after dup2() is called 2024-04-18 21:25:13 +02:00
fe302f5967
libc: Clean up stdio.h a bit 2024-04-18 21:24:34 +02:00
69f3e28f2c
editor: Use window->add_keyboard_shortcut to handle Ctrl+S
Some checks failed
Build and test / build (push) Failing after 13m5s
2024-04-15 19:34:09 +02:00
2f56a52489
libui: Add support for keyboard shortcuts natively 2024-04-15 19:33:32 +02:00
1176e64a7c editor: Fix creation of new files
All checks were successful
Build and test / build (push) Successful in 1m44s
The editor is supposed to create files if they don't exist, however before this commit stat() would fail and exit load_file() before we even got to File::open_or_create().
2024-04-15 17:06:04 +00:00
e7780b04ee editor: Display only the basename of the current file in the window title 2024-04-15 17:06:04 +00:00
6ded7247e0 terminal: Use widget->window() instead of the App's main window 2024-04-15 17:06:04 +00:00
8b3755873b editor: Use TextInput as a base class 2024-04-15 17:06:04 +00:00
489d54c531 libui: Add a TextInput base class to handle most input fields and add an InputField class for single-line inputs 2024-04-15 17:06:04 +00:00
eb3af60497 editor: Refuse to load non-regular file types 2024-04-15 17:06:04 +00:00
aee100753d editor: Remove insert mode and use the arrow keys to navigate, plus Ctrl+S to save 2024-04-15 17:06:04 +00:00
0be6a896bb editor: Add basic loading and saving 2024-04-15 17:06:04 +00:00
7d738433ed editor: Add a basic text editor 2024-04-15 17:06:04 +00:00
701dc30221
base+su+libc: Add support for a shadow file and use it by default
All checks were successful
Build and test / build (push) Successful in 1m39s
2024-04-10 22:37:36 +02:00
6968961d5c
tools: Use the correct architecture in make-package.sh
Some checks are pending
Build and test / build (push) Waiting to run
2024-04-10 21:53:20 +02:00
d8914b3efa
base: Add taskbar entry for 2048
All checks were successful
Build and test / build (push) Successful in 1m32s
2024-04-10 21:44:04 +02:00
82985d691d
taskbar: Make taskbar entries configurable 2024-04-10 21:42:21 +02:00
ff10e5f3b2
Remove the build status badge
Some checks failed
Build and test / build (push) Failing after 14m33s
It links to drone, which we have phased out in favor of Gitea Actions.
2024-04-01 18:42:34 +02:00
71df91b4a0
libc: Add a _POSIX_VERSION define
All checks were successful
Build and test / build (push) Successful in 1m39s
2024-04-01 14:18:46 +02:00
7dc4b17d46
libc: Implement strtoll and strtoull as functions 2024-04-01 14:18:34 +02:00
332976dde9
tools: Make luna-pkg-config executable 2024-04-01 14:18:15 +02:00
5b94217316
ports: Add doomgeneric port
All checks were successful
Build and test / build (push) Successful in 1m34s
2024-03-31 13:40:43 +02:00
7205020bac
ports: Add libwind port 2024-03-31 13:40:01 +02:00
898eb43360
tools: Add new files to diff as well 2024-03-31 13:38:56 +02:00
a863b17746
wind+libui: Ignore alpha bits in the window buffer 2024-03-31 13:38:39 +02:00
5087b6db30
wind: Show which IPC function was called with an invalid window id 2024-03-31 13:38:08 +02:00
7d69ac56e2
apps+libos+shell+wind: Correct a bunch of format strings
All checks were successful
Build and test / build (push) Successful in 1m41s
2024-03-29 14:42:38 +01:00
f9b39c5ff3
libos: Add ways to format output to a File 2024-03-29 14:41:45 +01:00
d70effd1db
libos: Clarify requirements for File::write 2024-03-29 14:25:14 +01:00
59713279a0
kernel: Add a hexdump() method to log binary data for debugging
All checks were successful
Build and test / build (push) Successful in 1m33s
2024-03-29 12:12:56 +01:00
6443ec77f8
kernel/ATA: Add support for regular ATA drives (non-ATAPI)
Don't know why this took so long to figure out, I just had to pass the right value to select().
2024-03-29 12:11:39 +01:00
86372a3893
Update README.md 2024-03-28 22:37:16 +01:00
3dc2c24ec5
apps: Add run
Some checks failed
Build and test / build (push) Failing after 1m43s
This utility lets you run a process detached from the shell, using the magic of the launch server.
2024-03-20 19:58:45 +01:00
06b8a41d2f
launch: Add support for PATH searching 2024-03-20 19:57:43 +01:00
eab44307f0
run-tests: Avoid starting a shell to spawn test processes
All checks were successful
Build and test / build (push) Successful in 2m9s
2024-03-14 12:37:59 +01:00
cdab3dea90
libluna: Assert some unreachable conditions
All checks were successful
Build and test / build (push) Successful in 1m48s
2024-03-07 23:10:35 +01:00
2780ee2ebc
ports: Build gcc without --enable-checking
All checks were successful
Build and test / build (push) Successful in 1m54s
Now that gcc works, we don't need to bloat the binary with asserts.
2024-03-07 22:33:17 +01:00
70c63572b2
2048: Use the arrow keys and the Home key as input
All checks were successful
Build and test / build (push) Successful in 1m53s
2024-03-06 20:34:13 +01:00
fc37634a18
kernel: Add much-needed support for extended keyboard scancodes 2024-03-06 20:33:54 +01:00
f05fea441c
libluna: Add LinkedList tags
All checks were successful
Build and test / build (push) Successful in 1m51s
2024-03-03 14:52:23 +01:00
5975e58b4a
libluna: Add typename to some stuff in TypeTraits
All checks were successful
Build and test / build (push) Successful in 1m52s
G++ on Luna was complaining about this.
2024-02-11 19:26:40 +01:00
d385e01796
ports: Fix mpfr download url
All checks were successful
Build and test / build (push) Successful in 1m48s
2024-02-11 18:26:46 +01:00
4dc060e0b3
libluna: Fix String::from_string_view construction for inline strings
All checks were successful
Build and test / build (push) Successful in 1m41s
Before, this method failed to add a null terminator if the source string did not have one, which was possible.
2024-02-11 17:09:37 +01:00
644614cdd8
libluna: Fix memmove when dest > src
Really? A crucial component of the libc was broken? No wonder some ports did not work very well...
2024-02-11 17:08:36 +01:00
1070c85922
CI: Don't install fakeroot as a dependency
All checks were successful
Build and test / build (push) Successful in 1m43s
We install as root directly.
2024-02-11 13:45:20 +01:00
8d5f598488
tools: Allow building as root for CI
All checks were successful
Build and test / build (push) Successful in 1m45s
2024-02-11 13:39:51 +01:00
8efcf6d852
Run apt as sudo
Some checks failed
Build and test / build (push) Has been cancelled
2024-02-10 11:55:34 +01:00
7165ff7683
Add fakeroot dependency
Some checks failed
Build and test / build (push) Failing after 6s
2024-02-10 11:50:01 +01:00
0847a2cda0
ports: Update README.md
Some checks failed
Build and test / build (push) Failing after 2m25s
This changes a few occurrences of "if using CMake" to the more correct "if the port uses CMake"
2024-02-10 11:37:52 +01:00
42a7c7af5f
Check glibc version
Some checks failed
Build and test / build (push) Failing after 2m1s
2024-02-06 22:46:05 +01:00
49f84c9dda
Set ubuntu version to latest
Some checks failed
Build and test / build (push) Failing after 2m3s
2024-02-06 22:43:28 +01:00
f5c0e724d5
Update ubuntu version to 22.04
Some checks failed
Build and test / build (push) Failing after 2m0s
2024-02-06 22:40:38 +01:00
ac3175cf26
Remove old drone.yml
Some checks failed
Build and test / build (push) Has been cancelled
Now that we use Gitea Actions, this is no longer needed.
2024-02-06 22:38:27 +01:00
a78620a7d2
Update workflow
Some checks failed
Build and test / build (push) Failing after 2m25s
2024-02-06 21:32:27 +01:00
fcd8c1d583
Update workflow
Some checks failed
Build and test / build (push) Failing after 2m20s
2024-02-04 14:40:07 +01:00
e1c2dfb9ba
Update workflow
Some checks failed
Build and test / build (push) Failing after 9s
2024-02-04 14:39:31 +01:00
7fcc0659c8
Update workflow
Some checks failed
Build and test / build (push) Failing after 7s
2024-02-04 14:39:07 +01:00
3fc5f2b836
Update workflow
Some checks failed
Build and test / build (push) Failing after 0s
2024-02-04 14:38:34 +01:00
64965cd322
Update workflow 2024-02-04 14:38:01 +01:00
d0ad103e3d
Update workflow
Some checks failed
Build and test / build (push) Failing after 0s
2024-02-04 14:36:48 +01:00
3728558b13
Update workflow
Some checks failed
Build and test / build (push) Failing after 9s
2024-02-04 14:33:30 +01:00
7cd6e9b12a
Update workflow
Some checks failed
Build and test / build (push) Failing after 7s
2024-02-04 14:30:30 +01:00
e02dee1f41
Update workflow
Some checks failed
Build and test / build (push) Failing after 50s
2024-02-04 14:27:20 +01:00
ab2700ef5d
Update workflow
Some checks failed
Build and test / build (push) Failing after 2s
2024-02-04 14:25:59 +01:00
bb18749d5b
Update build workflow 2024-02-04 14:24:22 +01:00
d4b368b078
Update build workflow 2024-02-04 14:18:51 +01:00
7f2a65f6d6
Add basic actions file
Some checks failed
Build and test / build (push) Has been cancelled
2024-02-04 14:16:01 +01:00
02f8102d38
wind+libui+taskbar: Add a request for setting special window attributes
This lets the taskbar window stay unfocused even when it's clicked.
2024-02-04 13:35:50 +01:00
9bb66716a4
libui: Move WindowType from ipc/Server.h to Window.h as it is no longer used in IPC 2024-02-04 13:16:50 +01:00
b9ccda132a
wind+libui: Rename SetTitlebarRect to SetTitlebarHeight
We only need the height to be customizable.
2024-02-04 13:13:21 +01:00
b8470f753b
startui: Move socket file checking around a bit 2024-02-03 19:35:40 +01:00
909d0ed289
libos+wind+apps: Make IPC code object-oriented and add functionality for properly receiving messages
This functionality previously had to be repeated across all server programs using the IPC API.
2024-02-03 19:16:39 +01:00
6bdf3169d2
kernel: Handle aborted connections instead of crashing 2024-02-03 19:15:19 +01:00
75d0d12b71
apps: Add a background launcher service
This service is used only by taskbar, for now, to launch apps with regular privileges instead of inheriting the special group 'wsys'.
2024-02-01 21:58:44 +01:00
a7ff298852
wind: Add a second unix socket for privileged clients which need to be in a different group 2024-02-01 21:57:40 +01:00
ca5b4de2d8
libui+apps: Change ui::App::init() to take the socket path directly instead of command-line arguments 2024-02-01 21:15:31 +01:00
f8a39ffeec
startui: Change mismatched parameter name 2024-01-31 22:45:11 +01:00
d440559d54
startui: Fix typo 2024-01-31 22:43:40 +01:00
443d8957f3
apps: Add startui
This service starts a complete UI session (wind, components, and init --user), all with their respective privileges.

This lets us move that responsibility away from wind and let it be only a window manager.
2024-01-31 22:42:24 +01:00
ea14dab7d7
wind: Stop using magic numbers for user and group IDs 2024-01-30 20:26:54 +01:00
16223b2f53
init: Add a (user) prefix to logs when not running as system init 2024-01-19 21:21:07 +01:00
9c36ef6e9e
terminal: Stop setting the pty to nonblocking mode when it's not needed 2024-01-19 21:18:01 +01:00
63f785563d
terminal: Use proper lambda functions when registering a fd listener for the pseudoterminal 2024-01-19 21:11:03 +01:00
1cd355a8e8
libos: Add Function<Args...> and use that to make EventLoop callbacks more versatile 2024-01-18 20:52:36 +01:00
d4d748e153
terminal: Remove m_cursor_timer->restart() from tick_cursor()
Since the timer was created as a repeating timer, it is already restarted after the function.
2024-01-13 16:26:37 +01:00
cee677b1f7
libui: Make App::process_events() private
Previously this was public as some applications (mainly terminal) needed to run some code in-between events, but this is no longer needed, due to the EventLoop providing these services (timers and file descriptor notifiers)
2024-01-08 19:13:47 +01:00
e4c9211edc
terminal: Use os::Timer and EventLoop::register_fd_listener 2024-01-08 19:04:04 +01:00
6bf8225f63
libos: Add Timer::reset, restart and stop 2024-01-08 19:01:59 +01:00
1223c6c20b
libos: Add FIXME to EventLoop 2024-01-08 19:01:39 +01:00
fd402083d7
kernel: Fix kernel panic when adding a timer before another one
This was caused because add_to_timer_queue() did not set active_clock when inserting a timer before the end, making disarm() a no-op.
Therefore, the clock would continue to use the timer after it had been freed.
2024-01-06 18:12:25 +01:00
4019cf90cf
kernel: Unify panic messages 2024-01-06 17:44:56 +01:00
1f2f676ea4
Update gitignore rules 2024-01-06 17:31:00 +01:00
075ed83764
Add about icon to git
Apparently, I had skipped this one, I really need to improve these
gitignore rules.
2024-01-06 17:23:14 +01:00
7f6863c093
apps: Use os::Timer instead of os::EventLoop::register_timer 2024-01-05 22:18:12 +01:00
a9c339939a
libos: Move timer handling to a separate class and use POSIX timers 2024-01-05 22:16:50 +01:00
3231a1296d
libc: Add support for POSIX timers 2024-01-05 22:15:06 +01:00
17b44a8ce6
kernel: Reenable stack tracing in kernel-mode exceptions
Stack tracing in user-mode exceptions was moved to when a signal kills the process, but this isn't done for kernel-mode exceptions so there was no stack trace anymore.
2024-01-05 22:14:31 +01:00
41c90aa436
kernel: Add POSIX timer support 2024-01-05 22:12:58 +01:00
f8cc093e17
tools: Add useful script to develop ports 2024-01-04 21:04:58 +01:00
64a941dc18
ports: Use --enable-initfini-array in gcc and binutils ports 2024-01-04 21:04:45 +01:00
2a85a7473a
kernel: Show stacktraces on all signal terminations 2024-01-04 21:04:24 +01:00
e34395915d
libc+tests+tools: Call global constructors in userspace code 2024-01-04 21:02:51 +01:00
d9899f1c3d
Update LICENSE 2024-01-04 11:24:48 +01:00
c24d0da5f0
ports/gcc: Fix --with-build-sysroot and enable asserts 2024-01-04 11:15:14 +01:00
1208d94b37
kernel: Add stack diagnostics to userspace fault reporting 2024-01-04 11:14:19 +01:00
f34dd56375
wind+libui: Implement client side decorations 2023-12-27 12:56:40 +01:00
5188def9e5
stat: Recognize sockets properly
Some checks failed
continuous-integration/drone/push Build is failing
2023-12-04 20:42:31 +01:00
9b01b5a5db
kernel: Correctly register file times for more file systems and file types 2023-12-04 20:42:17 +01:00
b619f717c8
kernel+libc: Implement pause() and sigsuspend()
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-04 20:26:01 +01:00
92ab403687
terminal: Use forkpty()
All checks were successful
continuous-integration/drone/push Build is passing
2023-11-25 12:18:48 +01:00
5bb4321134
libc: Add login_tty() and forkpty() 2023-11-25 12:18:25 +01:00
3a5924be64
kernel: Set the initial foreground process group when acquiring a controlling terminal 2023-11-25 12:18:04 +01:00
99dc819bca
terminal: Stop killing child process manually when exiting
All checks were successful
continuous-integration/drone/push Build is passing
This is already handled by the pty subsystem.
2023-11-22 21:35:26 +01:00
73a7d4f2a1
wind+libui: Run wind as a separate user
All checks were successful
continuous-integration/drone/push Build is passing
2023-11-22 21:31:08 +01:00
efeab5699e
su: Allow disabled passwords 2023-11-22 21:31:08 +01:00
1005305d5a
su: Support supplementary groups 2023-11-22 21:31:08 +01:00
8a90db837b
kernel+libc: Add support for supplementary groups (2/2)
Adds system calls for setting and getting groups, along with libc wrappers.
2023-11-22 21:31:07 +01:00
3ad23eab21
kernel: Add support for supplementary groups (1/2)
Adds support for supplementary groups internally in the kernel.
No userspace support.
2023-11-22 18:49:40 +01:00
e97b61ef16
gol: Use EventLoop timers
All checks were successful
continuous-integration/drone/push Build is passing
2023-11-16 22:02:31 +01:00
d1d53c6891
kernel: Remove signal debug messages 2023-11-16 22:02:17 +01:00
8a57d8a9b7
libos: Use setitimer() for millisecond precision 2023-11-16 21:58:45 +01:00
678121c3ed
kernel+libc: Add setitimer()
All checks were successful
continuous-integration/drone/push Build is passing
2023-11-16 21:48:18 +01:00
c4d2847da1
kernel: Rework the entire time system to use modular clocks
All checks were successful
continuous-integration/drone/push Build is passing
2023-11-15 23:50:04 +01:00
e28e1c682c
kernel: Tweak some timer code
All checks were successful
continuous-integration/drone/push Build is passing
2023-11-04 10:47:41 +01:00
dfebdce689
kernel: Add a timer queue with more versatility than simple alarm()
All checks were successful
continuous-integration/drone/push Build is passing
2023-11-03 19:53:34 +01:00
54ec441000
libluna: Add LinkedList::add_before() to mirror add_after()
Need this for later.
2023-11-03 19:52:36 +01:00
e1d5b7e7b4
kernel: Implement thread stopping and continuing
Some checks failed
continuous-integration/drone/push Build is failing
2023-10-28 15:15:32 +02:00
69771cbd85
kernel: Show symbols correctly when at the beginning of a function
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-25 20:02:15 +02:00
4d5feb0f3b
libos: Add File::seek() and File::tell()
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-24 20:02:09 +02:00
cea1b030ff
kernel: Add locking to BinaryFormat and DeviceRegistry
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-23 22:48:04 +02:00
9c65dba412
kernel: Add a registry for file system implementations 2023-10-23 22:47:49 +02:00
ba4e807f8e
kernel: Fix off-by-one error in symbol lookup and add locking
This resulted in very weird backtraces.
2023-10-23 22:47:20 +02:00
b3cbbea9d6
kernel: Move file descriptors into their own separate file 2023-10-23 20:13:11 +02:00
8476ea0dc9
ports: Port gcc =D
All checks were successful
continuous-integration/drone/push Build is passing
The main compiler (cc1) crashes in some obscure null dereference that I'll have to investigate.

However, it compiles fine, and the preprocessor seems to work...
2023-10-15 13:13:11 +02:00
2134dcc5ec
libc: Add madvise stub 2023-10-15 13:09:56 +02:00
7db6e0163a
libc: Add unused WUNTRACED define for gcc 2023-10-15 13:09:46 +02:00
bd0fb8fe5b
libc: Add pclose definition
The function was already implemented, but no definition in the header...
2023-10-15 13:09:22 +02:00
15d5f00cd3
libc: Add ctermid
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-15 11:09:08 +02:00
56eb0c8130
su: Read password from /dev/tty instead of stdin
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-14 20:47:56 +02:00
c323a812a5
kernel+libc+terminal+wind: Add support for POSIX sessions
All checks were successful
continuous-integration/drone/push Build is passing
Fixes #42.
2023-10-14 20:41:34 +02:00
81131ad3a8
init: Handle SIGCHLD signals 2023-10-14 20:40:18 +02:00
5f0830cd41
kernel: Add /dev/tty
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-14 19:00:10 +02:00
9097400c32
wind: Return more errors to the client when creating windows
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-13 22:33:36 +02:00
3ca31770e7
initrd: Remove unused stray script file
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-13 22:12:18 +02:00
c75dbc0cbb
kernel: Lookup and print symbols for addresses in backtraces 2023-10-13 22:11:52 +02:00
37e046d766
libui: Make Label initialization step-by-step instead of setting everything in the constructor
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-11 22:56:14 +02:00
7812a4a44a
apps+libui: Make app.run() call window->draw() automatically
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-10 22:24:11 +02:00
e18ca9bfe0
libos: Document Action.h 2023-10-10 22:11:12 +02:00
d3a347e432
taskbar: Handle SIGCHLD as part of the event loop
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-09 22:14:34 +02:00
3e5bdc8c80
apps: Add clock
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-09 22:05:30 +02:00
0824ba7e23
libos: Add timers to event loops
Only second precision for now, as alarm() is used to control the timers. Hopefully setitimer() or timer_create() can be added to the kernel soon to benefit from more precision.
2023-10-09 22:00:15 +02:00
0b2a835336
libui+libos: Move Action to libos 2023-10-07 15:31:50 +02:00
945cfab3eb
libos: Add signal handling to event loops
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-07 14:26:35 +02:00
5892a6bf09
libos+libui: Add event loops
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-06 22:06:34 +02:00
f5aed95b8b
kernel: Fix inode link counting in tmpfs
All checks were successful
continuous-integration/drone/push Build is passing
2023-10-04 20:58:40 +02:00
db2963d7bf
apps: Add 2048 prototype
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-28 21:38:42 +02:00
b3dc027ba0
taskbar: Add Game of Life to taskbar
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-27 19:03:49 +02:00
041d15a547
libui+taskbar: Make Buttons use Actions and clean up taskbar code 2023-09-27 18:52:17 +02:00
3d46e56386
libui: Add Margins to layouts 2023-09-27 18:51:54 +02:00
d4e834f734
libui: Add Actions
This allows components like Buttons to take in capturing lambdas
2023-09-27 18:51:38 +02:00
54afd7c2b0
libluna: Add OwnedPtr::leak() 2023-09-27 18:50:56 +02:00
9a9c7e577a
wind+libui+taskbar: Add various window types and never focus the taskbar
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-27 18:14:32 +02:00
f0844c9f69
cp: Support the -R flag and add better verbose messages
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-25 21:31:14 +02:00
eeb69c923c
kernel: Rename Scheduler::new_userspace_thread to clarify that it's only meant for init
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-25 19:34:02 +02:00
5626083aad
init: Add support for WorkingDirectory keys
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-25 19:26:05 +02:00
7ff5096083
kernel: Avoid page faults when reading from a slave pseudoterminal after the master is destroyed
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-23 12:57:03 +02:00
a47321a228
libc: Implement openpty()
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-22 23:02:33 +02:00
ffdcc843eb
kernel+terminal: Move pseudoterminal input processing to kernel-space
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-22 22:45:35 +02:00
441e04076a
kernel: Do not allow sending signals to dying threads
This was causing a kernel panic when closing the terminal by directly exiting the shell (either EOF or the exit command)
2023-09-22 22:40:24 +02:00
36fad85396
kernel+init+preinit+wind: Remove the kernel TTY and support only userspace terminals
All checks were successful
continuous-integration/drone/push Build is passing
Still allow printing text to the console, but without text input or ANSI escape fancy stuff.
2023-09-21 19:31:54 +02:00
b52f96ab64
kernel: Schedule cache clears only on certain checkpoints
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-21 19:14:13 +02:00
14f0c93175
kernel: Allow mapping the framebuffer even if its size is not page-aligned
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-20 22:41:48 +02:00
b4a9ea3857
terminal: Avoid doing too many redraws + support non-canonical mode
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-20 22:01:26 +02:00
9636b5d8da
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-20 21:07:37 +02:00
36bd556406
all: Bump release version to 0.6.0 and start calling it "Andromeda"
All checks were successful
continuous-integration/drone/push Build is passing
I changed my mind, some alpha releases can have unique names now.
2023-09-20 20:56:59 +02:00
b09226b8ba
gol: Use the windowing system
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-09-20 20:17:11 +02:00
52b04bd33b
kernel: Increase the OOM threshold to 4 MiB free
All checks were successful
continuous-integration/drone/pr Build is passing
2023-09-20 19:58:26 +02:00
b42497e05e
kernel: Start clearing caches when free memory is lower than 1MiB
All checks were successful
continuous-integration/drone/pr Build is passing
This is done to avoid returning ENOMEM errors when cache memory can still be reclaimed.
2023-09-20 19:49:13 +02:00
b370a99aa6
libui: Allow specifying the color of Labels, and use that in about 2023-09-20 19:45:19 +02:00
9fd4fc7e91
wind+taskbar: Improve the dark color scheme 2023-09-20 19:45:01 +02:00
bc14b01bf8
terminal: Fix certain keys being incorrectly inputted 2023-09-20 19:43:53 +02:00
0cb21c2e90
terminal: Send signals on ^C and ^\
Some checks failed
continuous-integration/drone/pr Build is failing
2023-09-20 07:06:01 +02:00
3540033dd3
wind: Translate Ctrl-key presses correctly 2023-09-20 07:06:01 +02:00
c5227d585c
kernel: Allow sending signals to process groups from userspace 2023-09-20 07:06:01 +02:00
d93e9f6b4b
kernel: Fix sending signals to threads that are in a long syscall 2023-09-20 07:06:00 +02:00
7631b81681
libui: Allow not filling the window with a background color every time 2023-09-20 07:06:00 +02:00
7f23931028
terminal: Draw directly onto the window canvas 2023-09-20 07:06:00 +02:00
945dc6c732
terminal: Add cursor support 2023-09-20 07:06:00 +02:00
dd3359b09b
libui: Properly request redraws from the server
Before this, the call to update() was always skipped.
2023-09-20 07:06:00 +02:00
9b1e19ef72
terminal: Use pseudoterminals and add keyboard support 2023-09-20 07:06:00 +02:00
75ea81bfbc
libc: Add pseudoterminal-related functions 2023-09-20 07:06:00 +02:00
29a341d8f3
init: Mount /dev/pts on startup 2023-09-20 07:05:59 +02:00
a93626fc41
kernel: Add pseudoterminals and a /dev/pts filesystem 2023-09-20 07:05:59 +02:00
ab738772b9
wind: Stop tracking windows after they're closed 2023-09-20 07:05:59 +02:00
e2a1cb0d34
wind+libui: Add support for keyboard events 2023-09-20 07:05:59 +02:00
1b633212f6
apps: Remove gclient 2023-09-20 07:05:59 +02:00
5a49e97483
taskbar: Add a button to open terminal instead of gclient 2023-09-20 07:05:59 +02:00
a4b5e68e1b
kernel: Allow performing extra actions when opening an inode 2023-09-20 07:05:58 +02:00
835c39bc47
apps: Add basic terminal app 2023-09-20 07:05:58 +02:00
0e8183d2bb
shell: Allow running as interactive even if not running in a TTY 2023-09-20 07:05:58 +02:00
bb5d726fe8
libui: Add option to run event processing in a loop instead of in app.run() 2023-09-20 07:05:58 +02:00
08b56319c7
libui: Reduce redraw calls by doing them only when events are actually handled 2023-09-20 07:05:58 +02:00
a5790d0fb1
apps: Add about 2023-09-20 07:05:58 +02:00
4cf0fac16e
libui: Add a basic Label component 2023-09-20 07:05:58 +02:00
67eac983b5
libui: Clarify that Font is only used for low-level glyph rendering 2023-09-20 07:05:57 +02:00
2643f050eb
libui: Zero-initialize counter variables in Layout 2023-09-20 07:05:57 +02:00
669e2747a7
wind: Move more fallible operations before window creation 2023-09-20 07:05:57 +02:00
06f3affc71
wind: Make sure stdin is always a TTY 2023-09-20 07:05:57 +02:00
5db1c3722c
libui+wind+libos: Move shared memory handling code to os::SharedMemory 2023-09-20 07:05:57 +02:00
17248e4ccc
libui: Add default handlers for events in Widget 2023-09-20 07:05:57 +02:00
5908b07ee2
libui: Propagate Container events only if they are in the child widget's rect 2023-09-20 07:05:57 +02:00
a023811c26
libui+wind: Handle mouse leave events when the mouse leaves a window 2023-09-20 07:05:57 +02:00
5385b1c337
wind: Stop using the removed 'signal' pledge 2023-09-20 07:05:57 +02:00
5bd2b3d81d
libui: Install the built library into the system root 2023-09-20 07:05:56 +02:00
ad001b4ee7
wind: Show memory usage in debug output 2023-09-20 07:05:56 +02:00
88a202ba33
wind: Handle ftruncate() and mmap() errors properly 2023-09-20 07:05:56 +02:00
b656ceedfe
wind: Fix client references being out-of-date in windows when disconnecting other clients
Classic "keeping a pointer to an element inside a vector after the vector is updated" bug, ah yes.
2023-09-20 07:05:56 +02:00
d43d06604d
taskbar: Wait for terminated child windows 2023-09-20 07:05:56 +02:00
6375fb965a
wind: Add debug keybind 2023-09-20 07:05:56 +02:00
7e7f0a96f5
wind+libos+libui: Handle interrupted reads properly 2023-09-20 07:05:55 +02:00
8c4e9dff96
base: Actually add the start icon to source control 2023-09-20 07:05:55 +02:00
345cf5cae3
libui: Add Buttons 2023-09-20 07:05:55 +02:00
d6f63c0a5d
libui: Handle other mouse events 2023-09-20 07:05:55 +02:00
35c7011997
libui: Add aligned items using Containers, ImageWidget 2023-09-20 07:05:55 +02:00
f657ee9ba9
libui: Add VerticalLayout 2023-09-20 07:05:55 +02:00
5703faf50f
wind+libui+taskbar: Add GetScreenRect IPC, non-decorated windows, taskbar 2023-09-20 07:05:54 +02:00
4d068beaaf
libui: Actually fill window backgrounds with the correct color 2023-09-20 07:05:54 +02:00
819baa0cd5
libui: Add basic widget and layout system =D 2023-09-20 07:05:54 +02:00
69bb22095f
ui+wind: Send mouse move events through IPC 2023-09-20 07:05:54 +02:00
062b09e20c
wind+libui: Add protocol for window close requests 2023-09-20 07:05:54 +02:00
2328987d81
libos+libui+wind: Use uppercase for static struct IDs to avoid confusion with fields 2023-09-20 07:05:54 +02:00
820b1ae2ba
libui+gclient: Add basic OOP wrappers around the IPC protocol 2023-09-20 07:05:53 +02:00
0fb47d90a7
wind+gclient: Add SetWindowTitle and support shm buffers 2023-09-20 07:05:53 +02:00
0127068177
gclient: Create two example windows 2023-09-20 07:05:53 +02:00
d3dd257dc1
wind: Handle CreateWindow IPC messages 2023-09-20 07:05:53 +02:00
1eb00eabfa
libui: Add CreateWindow IPC message definitions 2023-09-20 07:05:53 +02:00
9125561cab
libos: Add basic IPC message framework 2023-09-20 07:05:53 +02:00
3d90d7f98e
kernel: Fix poll syscall 2023-09-20 07:05:52 +02:00
e931d11ae1
wind: Monitor data on client connections 2023-09-20 07:05:52 +02:00
6a35cad8d5
kernel: Add POLLHUP and store it when a polled socket's peer disconnects 2023-09-20 07:05:52 +02:00
5e6ce50c70
libui: Add copyright/author text 2023-09-20 07:05:52 +02:00
02b9dc579b
libos: Add copyright/author comments to LocalServer and LocalClient 2023-09-20 07:05:52 +02:00
774177ba1f
wind: Use init --user and pledge() 2023-09-20 07:05:52 +02:00
7d883fe33b
Update .gitignore 2023-09-20 07:05:52 +02:00
1c50d5133f
libos: Remove some shared pointers and change them to owned/live on the stack 2023-09-20 07:05:52 +02:00
6cf5fa3097
wind: Spawn a new client process after startup
Also, create the socket after dropping privileges.
2023-09-20 07:05:52 +02:00
60c3bcb3a9
apps: Add gclient 2023-09-20 07:05:51 +02:00
03096680ae
libos: Add os::LocalClient 2023-09-20 07:05:51 +02:00
639eb30c7b
libui: Change 'into' to 'onto' 2023-09-20 07:05:51 +02:00
0bb96985bf
libui: Document ui::Font 2023-09-20 07:05:51 +02:00
fbb66a9fc3
libui+wind: Move some static variables inside functions 2023-09-20 07:05:51 +02:00
3fefb74710
wind: Generate random windows on keypresses 2023-09-20 07:05:51 +02:00
11e0025a5b
wind: Make sure windows have a minimum size to fit the titlebar 2023-09-20 07:05:51 +02:00
98aaf1f7ff
libui: Properly cut off the last drawn character if necessary 2023-09-20 07:05:51 +02:00
c0ada40e2c
libui: Add Rect::contains(Rect) 2023-09-20 07:05:50 +02:00
35d2bd6931
libui: Render font characters properly with no spacing, matching the width calculations 2023-09-20 07:05:50 +02:00
25ad2b17aa
wind: Render an actual TGA mouse cursor 2023-09-20 07:05:50 +02:00
6d78fc64f9
wind: Add a close button to windows using a TGA icon 2023-09-20 07:05:50 +02:00
dc91d047de
libui: Add support for TGA image loading 2023-09-20 07:05:50 +02:00
916b19825d
libui: Add an interface to fill a Canvas with an array of pixels 2023-09-20 07:05:50 +02:00
f6ef79e759
wind: Add window titlebars using ui::Font 2023-09-20 07:05:50 +02:00
23f7210a87
libui: Add PSF font loading and rendering 2023-09-20 07:05:50 +02:00
c6c32f34f2
libui: Add Color::GRAY 2023-09-20 07:05:50 +02:00
16fa55899e
libui: Rename Rect::absolute to normalized and add a new absolute function 2023-09-20 07:05:50 +02:00
7ab0c6b72b
libluna: Add assignment operators to Buffer 2023-09-20 07:05:49 +02:00
277953065a
wind: Reorder drag sequence 2023-09-20 07:05:49 +02:00
2b3e9b778a
libui: Add Rect::relative 2023-09-20 07:05:49 +02:00
7441e396b3
libui: Remove redundant statement 2023-09-20 07:05:49 +02:00
07dc7064f8
libui: Add getters for separate color values 2023-09-20 07:05:49 +02:00
01da7be57c
libui: Remove unnecessary stuff 2023-09-20 07:05:49 +02:00
b6c85595be
base: Remove startup items not necessary for GUI startup 2023-09-20 07:05:49 +02:00
8859fc3d6a
libui+wind: (Draggable) windows 2023-09-20 07:05:49 +02:00
335911c287
wind: Create a local server object 2023-09-20 07:05:49 +02:00
b6fe96e364
libos: Add a new LocalServer class for local domain sockets 2023-09-20 07:05:49 +02:00
15192837c0
kernel: Support listening sockets in poll() 2023-09-20 07:05:48 +02:00
5b89fccb6a
base: Start wind on startup instead of the shell 2023-09-20 07:05:48 +02:00
36cc84c50d
wind: Add a simple display server skeleton using libui
No client functionality yet, but it's a start.
2023-09-20 07:05:48 +02:00
9df88bac3e
libui: Add a GUI and graphics library 2023-09-20 07:05:48 +02:00
4af337e92d
kernel: Improve the mutex system
Some checks are pending
continuous-integration/drone/push Build is running
2023-09-20 07:05:33 +02:00
3e896b0f62
kernel:Remove unused legacy variable from sys_mmap()
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-12 22:07:17 +02:00
66e3d71dbc
kernel/ATA: Fix sector number calculation for ATA drives
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-07 11:28:46 +02:00
6065b63801
kernel/ext2: Add support for files larger than 4MB
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-06 09:56:24 +02:00
e029679fba
kernel: Fix negative movement in the PS/2 mouse driver
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-05 10:46:05 +02:00
15f4f7c72f
apps: Remove pivot_root
All checks were successful
continuous-integration/drone/push Build is passing
This functionality is intended to be used only by preinit, so it doesn't make sense to make it a command-line utility.
2023-09-04 13:12:55 +02:00
0002c2314c
kernel: Handle tab properly in the terminal 2023-09-04 13:12:08 +02:00
27eacac19c
kernel: Add a blinking cursor to the terminal
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-04 11:44:35 +02:00
c5e11bb6cf
apps+base+libc: Use /usr/bin paths instead of /bin everywhere 2023-09-04 11:44:10 +02:00
3c9b2c49aa
init: Fix wrong log message 2023-09-04 11:43:36 +02:00
1528c772fd
kernel: Store the full command line of a process 2023-09-04 11:43:11 +02:00
39ba4c9087
ls: Add colors to output
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-02 20:01:10 +02:00
c524dc8d58
libluna+kernel: Basic ANSI escape sequences 2023-09-02 19:35:42 +02:00
e76a91d5d0
libc+libluna: Move the scanf implementation from libc to libluna 2023-09-02 15:48:58 +02:00
cb0d5cb6a1
rm: Add the -v flag
All checks were successful
continuous-integration/drone/push Build is passing
2023-09-02 14:46:14 +02:00
06aa7725a1
libos: Stop using syscalls directly and proxy to libc 2023-09-02 14:27:04 +02:00
64f9e9dcde
libluna: Document Check.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-28 12:27:41 +02:00
9c912ddc51
libluna: Document Heap.h 2023-08-28 12:20:42 +02:00
419604a4d2
libluna: Document Buffer
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-28 11:10:04 +02:00
97037b06cb
libluna: Document Ignore.h and ImplPOSIX.cpp 2023-08-27 20:50:53 +02:00
c2f173f584
libc: Call __builtin_trap() in abort() if all else fails 2023-08-27 20:49:18 +02:00
a772d92e6f
libluna: Fix initial allocation for HashTable 2023-08-27 20:48:50 +02:00
6f3ed70363
kernel+libluna: Avoid scrubbing when the memory is going to be overwritten anyway
This is the case for objects with constructors and temporary memory which is filled afterwards.
2023-08-27 20:48:33 +02:00
d48142f163
libluna: Document HashMap and HashTable 2023-08-26 20:50:12 +02:00
cbea66c533
libos+libluna: Fix misspellings of "succeeded" 2023-08-26 20:49:57 +02:00
c6d817a0fd
libluna: Document Hash.h 2023-08-26 20:31:16 +02:00
55c362eecf
libluna: Document Format
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-26 12:59:22 +02:00
9fd8b10b3f
libluna: Document CString, CType and DebugLog 2023-08-26 12:43:44 +02:00
516d6bc65e
libluna: Document CircularQueue, CPath and CRC32 2023-08-26 12:33:12 +02:00
4becb2e427
init: Log requested exits
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-24 15:28:20 +02:00
3e174337ab
init: Hostname validation 2023-08-24 15:28:08 +02:00
0f377e7289
libluna: Fix off-by-one size calculation in Base64::decode_string()
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-24 12:06:01 +02:00
798a6d63aa
libluna: Document Bitset.h 2023-08-23 14:45:53 +02:00
3f1e6fc2ff
libluna+kernel: Move luna/Syscall.h to the kernel API directory
Some checks failed
continuous-integration/drone/push Build is failing
A kernel-specific header has nothing to do in libluna.
2023-08-23 14:35:21 +02:00
b8ae61b7c7
libluna: Document Bitmap
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-23 13:50:45 +02:00
1449e966ab
libluna: Document Base64.h 2023-08-23 13:34:14 +02:00
24f9dd22ec
libluna: Document Attributes.h and Badge.h 2023-08-23 13:24:28 +02:00
b8e70996c3
libluna: Document Atomic.h 2023-08-23 13:04:47 +02:00
6058a69182
libluna: Document Alloc.h 2023-08-23 11:08:18 +02:00
e247310ded
libluna: Document Alignment.h 2023-08-23 11:04:05 +02:00
a35ca0b367
libluna+kernel: Add Bitset and use it for signals
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-23 10:51:02 +02:00
d144a818d8
kernel: Completely prevent sending signals to kernel threads
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-22 15:25:05 +02:00
33c1a9c92b
init: Add a configurable service directory
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-22 15:23:06 +02:00
65834ff491
edit: Make it more user-friendly 2023-08-22 15:17:13 +02:00
5c2718545f
base+tools: Add a welcome file and store the license inside the OS 2023-08-22 15:08:07 +02:00
e5905a33e1
init: Stop using the removed 'signal' pledge
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-22 13:36:33 +02:00
993e94cc76
kernel: Remove the 'signal' promise and make signal functions require stdio instead
Some checks failed
continuous-integration/drone/push Build is failing
This follows OpenBSD and makes it so stdio is sufficient for an abort() call.
2023-08-22 13:34:30 +02:00
746834e2d9
kernel: Silently ignore TTY writes in graphical mode
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-22 13:31:31 +02:00
ce3542e2bd
apps+base: Remove many legacy test apps
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-22 13:29:52 +02:00
e72bc55c6f tools: Maybe, this finally works for CI...
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-22 10:19:17 +00:00
2abb43d709
kernel+libos: Call Vector::try_reserve where it is appropriate
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-22 11:54:00 +02:00
70a232cfcd
libluna: Make Vector grow exponentially 2023-08-22 11:53:42 +02:00
30ff704342
libluna+libos: Install built libraries into the system root
Some checks failed
continuous-integration/drone/push Build is failing
This is less important for libluna, as it is built into libc, but is needed to link programs compiled inside Luna with libos.
2023-08-21 14:06:32 +02:00
6e69d37d62
tools: Fix building ports from git repository
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-19 19:54:37 +02:00
f2a5c9ad3f
apps: Add free
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-17 20:15:39 +02:00
95a33c484e
kernel+libc: Add a memstat() syscall
We can finally show memory usage in userspace.

This could have been done using sysfs, but I'm lazy and don't want to implement that. Maybe in the next release?
2023-08-17 20:15:32 +02:00
4a654bf093
kernel: Handle OOMs better and without deadlocking
Use a separate task to do it.

Also fix a bug where the init thread would get no kernel stack ever since 5f698b477.
2023-08-17 20:14:33 +02:00
d43590e68c
kernel: Improve Your Disk IO performance by 500% with this One Trick!
Some checks failed
continuous-integration/drone/push Build is failing
The trick being caching lol.
2023-08-16 14:54:13 +02:00
c1f4997448
all: Start calling this release 0.5.0
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-16 09:57:38 +02:00
7b88b9cea3
kernel/ext2: Replace a manually allocated buffer with Buffer
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-16 09:15:29 +02:00
54cc80f649
kernel/ATA: Replace a manually allocated buffer with Buffer
This also lets us keep it empty unless it is used, in which case we resize it (if it wasn't already resized).
2023-08-16 09:15:00 +02:00
b8f81502b8
kernel: Fix some debug messages that are not shown by default 2023-08-16 09:03:25 +02:00
e8e05159c1
libluna+kernel: Make CRC32 a class 2023-08-15 19:27:09 +02:00
49a6c39c38
libc: Implement popen() and pclose() 2023-08-15 19:21:25 +02:00
706752d6b9
kernel: Return SIGPIPE/EPIPE when writing to a pipe with no more readers 2023-08-15 19:08:37 +02:00
1e68ac7312
Finally a working toolchain?
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-15 15:40:44 +02:00
6761b3fcaf
tools: Finally a proper autoconf build?
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-14 11:54:11 +02:00
71d1084be2 tools: Place autoconf in the correct path
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-14 09:34:36 +00:00
f65deb727a
tools: Fix filename in setup-autoconf.sh
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-14 11:27:47 +02:00
d07f592306
tools: Fix message printing in setup-autoconf.sh
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-14 11:26:18 +02:00
cad0bd8c48
tools: Build autoconf if needed and use it to patch libstdc++
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-14 11:18:53 +02:00
db3151d93b
init: Add some missing pledges
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-14 11:08:19 +02:00
ba3e32917e
init: Support starting services as a separate user
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-14 10:46:45 +02:00
cfb60fad25
init: Use pledge and support init --user 2023-08-14 10:46:28 +02:00
9954fc1658
libos: Add a pledge wrapper 2023-08-14 10:45:00 +02:00
a98df9e743
kernel: Return EACCES when trying to apply execpromises to a setuid program
Closes #41.
2023-08-14 09:50:52 +02:00
e2a77bb3da
kernel+libc: Add pledge support
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-12 21:38:25 +02:00
0ae409ae22
ports: Some enhancements in make-package.sh
Some checks failed
continuous-integration/drone/push Build is failing
2023-08-11 18:25:07 +02:00
181b4c151b
tools: Build libstdc++ 2023-08-11 18:24:38 +02:00
0c64b6e040
libc: Add some stub network-related header files 2023-08-11 18:09:45 +02:00
fb3c31907d
fix 2023-08-11 18:09:28 +02:00
52064e0317
libc+kernel: Add alarm() and getpagesize() 2023-08-11 18:09:12 +02:00
ec3c1132d2
libc: Fix constness of some socket functions 2023-08-11 18:00:15 +02:00
5ea73197ad
libluna: Add a bunch more errno definitions 2023-08-11 17:59:41 +02:00
5a1adcb2a6
libc: Add putenv 2023-08-11 17:59:04 +02:00
c4f6191e24
libc: Implement some simple stuff needed for gcc 2023-08-08 22:06:11 +02:00
39e4fbd112
libc: Provide a bunch of math functions wrapped around compiler builtins 2023-08-08 20:38:38 +02:00
32fd6889b9
ports: Add pkg-config wrapper
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 20:28:11 +02:00
c6a5a81a7a
ports: Port required libraries to build GCC
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 19:51:45 +02:00
3f55a70f6e
ports: Auto-strip binaries, remove libtool .la files, add dependencies 2023-08-08 19:46:04 +02:00
b1e164f360
libc. Add basic wchar.h 2023-08-08 19:43:23 +02:00
ed8b210639
kernel: Detect some other cases of non-DMA support
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 18:23:13 +02:00
16590dbb02
ports: Avoid using two separate directories for port packages
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 17:43:27 +02:00
919c71ff85
README: More features
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 16:19:38 +02:00
1caa2c0888
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 16:04:10 +02:00
8748364b7e
ports: Add a binutils port =D
All checks were successful
continuous-integration/drone/push Build is passing
I can't believe the fact that there is a working gas and ld on Luna. At least, for a hello world program anyway :)

objdump seems to have some problems with stack size in some cases, but apart from that, no crashes.

And that can easily be solved with either more stack preallocation or stack resizing in the kernel on page faults.
2023-08-08 16:00:31 +02:00
49662b6069
tools: Calculate the needed fs size dynamically 2023-08-08 15:43:20 +02:00
d96ff92461
libc: Add borrowed strtod implementation 2023-08-08 15:17:25 +02:00
bfb76b5625
kernel: Properly expose block device sizes with the new metadata API 2023-08-08 15:17:08 +02:00
8c13513bf4
libc: Add strcoll()
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 14:40:14 +02:00
37e9b25b62
apps: Add touch
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 14:34:58 +02:00
a92077d311
kernel+libc: Add all variants of utime
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 14:14:35 +02:00
1481a4736a
tmpfs: Update mtime on writes
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 13:36:25 +02:00
4195e7f206
kernel+libc+stat: Add support for file times
All checks were successful
continuous-integration/drone/push Build is passing
The modification time is not updated though.
2023-08-08 13:33:40 +02:00
159c05c064
libluna: Add max() and min()
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 12:39:03 +02:00
b63a8ff245
libluna: Move get_blocks_from_size to a new header and call it ceil_div instead
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 11:58:33 +02:00
917203ef11
kernel: Run the init function in a separate block to free everything before kernel_exit is called
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-08 10:44:18 +02:00
826be882a9
kernel: Interrupt syscalls before exiting because of a signal
Closes #40.
2023-08-08 10:41:46 +02:00
198935eb30
libc: Reset the read buffer even when read() returns an error
This fixes the same data being read multiple times if an error was returned
2023-08-08 10:39:15 +02:00
7c254e5e15
kernel: Properly check memory bounds in strdup_from_user()
All checks were successful
continuous-integration/drone/push Build is passing
Missed this one in 097353e779.
2023-08-08 10:27:19 +02:00
2e63b93e48
libos: Remove debug statements from Process::spawn()
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-07 22:53:37 +02:00
77ebdda2e0
libos: Add Process::spawn()
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-07 22:49:12 +02:00
097353e779
kernel: Properly check memory bounds while touching user memory
Before this patch, one byte of each page was being accessed without checking the page's permissions.
2023-08-07 22:49:00 +02:00
10c892d606
kernel: Allow null envp in execve()
As far as I know, this is not standard, but I'm doing this as a convenience for programs using exec() right after clearenv().
2023-08-07 22:48:21 +02:00
f45734c61d
kernel/ATA: Stop storing ATA::Drive in a separate shared pointer
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-07 19:22:57 +02:00
bc20e1a31b
kernel: Store FD_CLOEXEC in the file descriptor itself
All checks were successful
continuous-integration/drone/push Build is passing
Closes #39.
2023-08-03 17:47:18 +02:00
b01aa72f17
libc+init+shmem-test: Add POSIX shared memory objects
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-03 10:32:52 +02:00
d41fb85466
libluna/SharedPtr: Count references with separately created objects properly 2023-08-03 10:32:22 +02:00
5aa042a5f2
kernel: Add constructors to SharedMemory 2023-08-03 10:31:58 +02:00
f150425222
kernel: Create a new shared memory object if the old one was lost 2023-08-03 10:31:29 +02:00
842b212685
kernel: Set a SharedMemory object's prot value 2023-08-03 10:30:43 +02:00
641b65da0f
kernel: Take devices into account in SharedMemory::free() 2023-08-03 09:33:10 +02:00
bfcca3a220
gol: Use memory-mapped IO
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-03 09:26:35 +02:00
b5d146b492
kernel/mmap: Fix some parameters 2023-08-03 09:26:21 +02:00
b447c1a261
kernel: Set the shmem->inode field in query_shared_memory 2023-08-03 09:25:56 +02:00
f8e86b3b01
fix 2023-08-03 09:25:38 +02:00
d8f6af99b8
kernel: Let devices use shared memory 2023-08-03 09:25:23 +02:00
c5e24e478f
kernel+libc: Add truncate and ftruncate
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-03 08:47:37 +02:00
53d9f5c6fc
libc: Add msync wrapper
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-02 22:44:54 +02:00
84c1ac4cee
kernel: Add msync
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-02 22:39:07 +02:00
7293d47bf0
apps: Add shmem-test
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-02 22:20:05 +02:00
f66b0497cf
libc: Add support for mmap()'s new syscall format 2023-08-02 22:20:05 +02:00
2572695c8d
kernel: Support mapping shared memory using mmap() 2023-08-02 22:20:05 +02:00
9443551d71
kernel: Add shared memory 2023-08-02 22:20:05 +02:00
b4527786d4
kernel/MMU: Don't copy pages on clone and allow manipulating other page directories 2023-08-02 22:17:32 +02:00
3aaf1c5d84
apps: Rename mouse to input, read keyboard packets as well
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-02 17:20:26 +02:00
4794d0dfef
kernel: Add a keyboard device for graphical session 2023-08-02 17:20:13 +02:00
9c1e275f34
kernel: Make /dev/mouse read-write only for root 2023-08-02 17:19:37 +02:00
6593f9241b
libc: Add wrapper for poll() 2023-08-02 17:19:16 +02:00
df4227eab8
kernel: Make the poll() system call actually work 2023-08-02 17:18:38 +02:00
f8cb6e03df
kernel: Allow turning off the TTY by setting it to graphical mode
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-02 15:16:10 +02:00
207d901de8
kernel+libc: Add the poll() syscall
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-02 14:48:20 +02:00
df77fc8de8
libluna: Remove make_array() and destroy_array()
Placement new on arrays is a bit unreliable and could cause out-of-bounds data accesses.
2023-08-02 14:47:58 +02:00
b1fb6dee8a
login: Create a new process group to log in 2023-08-02 14:47:13 +02:00
aac8280e8a
libc+libos: Properly propagate errors through fgetc() and File::getchar()
This restores proper ^C behavior in the shell.
2023-08-02 14:46:47 +02:00
d0ceec6952
mouse: Show textual description of buttons
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-02 13:58:17 +02:00
7983d63b8e
libos: Add documentation for os::File::BufferingMode
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-02 13:15:51 +02:00
2198dedb96
apps: Add mouse
All checks were successful
continuous-integration/drone/push Build is passing
A simple mouse packet reader.
2023-08-02 11:56:12 +02:00
cd9219df52
tools: Install kernel API headers into /usr/include/moon 2023-08-02 11:56:00 +02:00
e8f3dd4cf9
kernel: Add a PS/2 mouse driver 2023-08-02 11:55:45 +02:00
6c26236167
libluna: Add CircularQueue::is_empty() 2023-08-02 11:55:08 +02:00
b17793134e
libos: Let users change the buffering mode of a File 2023-08-02 11:54:47 +02:00
dc35c42371
kernel/VFS: Rework the metadata system so that there is a single metadata struct
All checks were successful
continuous-integration/drone/push Build is passing
2023-08-01 17:20:28 +02:00
4c87d72b44
kernel/binfmt: Add documentation + support script interpreters being scripts themselves
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-31 20:41:18 +02:00
d01087362e
libc: Set the close-on-exec flag for directories opened using opendir()
This is apparently mandated by POSIX.
2023-07-31 10:58:06 +02:00
3598dacbed
init: Remove support for 'Script' parameters
All checks were successful
continuous-integration/drone/push Build is passing
This can now be changed to good old 'Command', putting a shebang into the script,
thanks to the new shebang support in the kernel.
2023-07-30 18:47:38 +02:00
3638d3da46
kernel: Add binary format for shebang scripts 2023-07-30 18:46:19 +02:00
1c76675e40
kernel: Add a framework to add more executable formats, possibly from userspace
This lets us implement shebangs and possibly an interface similar to Linux's binfmt_misc.
2023-07-30 18:25:44 +02:00
6e269c6bc4
preinit: Search for init in several directories
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-30 13:08:53 +02:00
43fa128e29
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-30 11:55:20 +02:00
8475a3aad9
socket-client: Send a user-provided message to the server
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-07-30 11:46:53 +02:00
187f0ff83e
kernel: Rename Inode::blocking() to Inode::will_block_if_read()
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-30 11:41:53 +02:00
0c873923e8
kernel: Make OpenFileDescription shareable
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-30 11:33:46 +02:00
63745565db
apps: Add socket client
Some checks failed
continuous-integration/drone/pr Build is failing
2023-07-30 11:33:06 +02:00
7b24a4d1c6
libc: Add wrappers for listen(), connect(), and accept() 2023-07-30 11:33:06 +02:00
8d3b3aaf05
libluna: Add a few more network-related errno codes 2023-07-30 11:33:06 +02:00
bb3127c212
kernel: Implement listen(), connect() and accept() 2023-07-30 11:33:06 +02:00
cca806f088
libluna: Add a variant of CircularQueue that dynamically allocates its buffer at runtime
This is needed to implement the backlog queue for listening sockets.
2023-07-30 11:33:06 +02:00
7a7ae086f5
kernel: Use a did_close callback for UnixSockets 2023-07-30 11:33:06 +02:00
fb08594a18
kernel: Separate FileDescriptors and OpenFileDescription
Also, add a did_close() callback for OpenFileDescriptions losing all their references.
2023-07-30 11:33:06 +02:00
9303c44269
apps: Add socket-test 2023-07-30 11:33:06 +02:00
a12b018b03
kernel+libc: Add basic Unix sockets (creation and binding) 2023-07-30 11:33:06 +02:00
c4e30c3029
kernel: Add functionality to allow external inodes (such as sockets) to acquire an inode number from a file system
This is only implemented in tmpfs.
2023-07-30 11:33:06 +02:00
c1d08b904e
kernel+libluna: Add Buffer::dequeue_data() 2023-07-30 11:33:05 +02:00
200bb6c240
kernel+libc+libos: Add inode type for sockets 2023-07-30 11:33:05 +02:00
6b0bc66fd2
libluna: Add new socket-related errno codes 2023-07-30 11:33:05 +02:00
4ed7ec5e93
libluna: Store SharedPtr's ref count in the object itself
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-30 11:32:46 +02:00
28cc4b2306
kernel: Add default action for SIGWINCH
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-27 14:00:30 +02:00
11df5a2ec3
kernel: Use pid_t internally for process IDs
All checks were successful
continuous-integration/drone/push Build is passing
This removes a bunch of casts between pid_t and u64, and makes more sense since pid_t is literally the data type for process IDs.
2023-07-26 21:32:00 +02:00
5aad7d3154
kernel/x86_64: Fail on invalid interrupts instead of calling FIXME_UNHANDLED_INTERRUPT
All checks were successful
continuous-integration/drone/push Build is passing
A FIXME is something that should be changed later,
this is a check for something that should never happen.
2023-07-25 18:23:33 +02:00
58fa297068
libluna: Wrap around when iterating through a HashTable's buckets array
All checks were successful
continuous-integration/drone/push Build is passing
Why am I so dumb?
2023-07-25 18:19:45 +02:00
28dd8194af
kernel: Include waited-for grandchildren in RUSAGE_CHILDREN's times
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-25 17:50:15 +02:00
b88da4811f
kernel: Remove debug message in readlink
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-25 17:30:56 +02:00
7f990b161b
libluna: Fix comparison of StringViews without null termination
All checks were successful
continuous-integration/drone/push Build is passing
This regressed in de7e58c274, and made value arguments pretty much unusable.

This really needs a test...
2023-07-25 17:25:18 +02:00
9bb3fed611
libluna: Use the right unsigned integer type for wcscmp()'s return type 2023-07-25 17:23:27 +02:00
105ed79f8f
kernel: Reenable userspace stack tracing, but hidden behind a config flag
All checks were successful
continuous-integration/drone/push Build is passing
Sometimes this is needed for userspace program debugging (such as ports),
but sometimes it can crash, so we leave it off by default.
2023-07-25 17:02:09 +02:00
905e71527e
libc: Actually implement sigsetjmp() and siglongjmp() 2023-07-24 19:39:22 +02:00
c6d91c89cd
stat: Change program description
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-24 19:17:36 +02:00
2e2b87b714
ports+tools: Add bc port
All checks were successful
continuous-integration/drone/push Build is passing
It segfaults when writing "about", but oh well...
2023-07-24 19:14:22 +02:00
b12f42cfe2
libc: Add SIGWINCH
Not used for anything at the moment, I guess if a user program wants to send it...

Required by bc.
2023-07-24 19:11:06 +02:00
c70790bf62
ports: Add some defaults for CMake projects as well
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-24 18:50:51 +02:00
a990cc145e
ports: Add initial documentation to the port system
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-24 18:29:44 +02:00
b0d7870ec6
ports: Add minitar (with examples!)
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-24 17:20:54 +02:00
9a00b29304
ports: Basic ports system + nasm port
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-24 17:07:49 +02:00
033aff4f6c
all: Error out on bidirectional characters (CVE-2021-42574)
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-24 15:06:48 +02:00
c5af1bcef9
libc: Fix typo in fopen description
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-24 11:57:47 +02:00
b3c478f19e
init: Make the log stream line-buffered
All checks were successful
continuous-integration/drone/push Build is passing
Looks like log output stopped showing after buffering was implemented, since the log was not flushed properly.
2023-07-24 11:54:49 +02:00
ad3f3bf4db
kernel: Log the release name and build date in the boot log 2023-07-24 11:48:01 +02:00
01359af288
tools: Make the Ext2 partition bigger (32M)
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-22 16:11:34 +02:00
eeb9e16a74
libos: Make os::File a wrapper around stdio's FILE
All checks were successful
continuous-integration/drone/push Build is passing
This way, os::File benefits from the same buffering as stdio.h does.
2023-07-22 12:40:02 +02:00
358493a7bc
kernel: Add a system for release names in uname(), call alpha releases "Mercury"
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-22 12:21:01 +02:00
5110d740b8
all: Update the version number to 0.4.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-22 12:11:02 +02:00
759fb4fe0e
tools: Make replace-stdint.sh replace types only if they're followed by a space
All checks were successful
continuous-integration/drone/push Build is passing
Otherwise, size_to_read -> usizeo_read.
2023-07-22 11:59:41 +02:00
098109f16b
tools: Make sure formatting scripts cover all sources 2023-07-22 11:59:02 +02:00
9ef09cfc88
libc+libluna: Add case-insensitive string comparison functions 2023-07-22 11:58:28 +02:00
c17e1a5802
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-22 11:45:35 +02:00
085d2895e8
libc: Implement setbuf(), setbuffer(), and setlinebuf()
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
These are all simple wrappers around setvbuf().
2023-07-22 11:36:20 +02:00
77022abafd
libc: Implement ungetc
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-22 11:25:20 +02:00
19b4aa9f81
libc: Flush buffers before dealing with file positions 2023-07-22 11:19:48 +02:00
420270ebd4
libc: Implement read buffering =D 2023-07-22 11:17:51 +02:00
d60ad184f1
libc: A bit of nice refactoring 2023-07-22 10:58:34 +02:00
a3ed950be8
libc: Basic write buffers
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-22 00:04:27 +02:00
cfb0ead2d9
libc: Flush all open streams on exit
This does nothing for now, but prepares for buffering.
2023-07-21 22:56:03 +02:00
5458286309
libos: Add Process::exit()
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 21:21:08 +02:00
c72c6312d4
sh: Use input_file instead of hardcoding stdin everywhere in tcsetpgrp()
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 21:08:27 +02:00
7a4d3ba495
sh: Add a few more shell builtins
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 21:06:10 +02:00
16b385fc7b
libluna: Some fixes so that HashTable collisions work properly 2023-07-21 21:04:25 +02:00
4439ef8ec6
sh: Add a system to easily add flexible shell builtins
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 20:44:01 +02:00
ff9e01641e
apps: Add a Game of Life implementation
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 15:51:21 +02:00
36a74fd8d6
kernel/x86_64: Provide an alternate kernel stack for exceptions
All checks were successful
continuous-integration/drone/push Build is passing
This avoids stack-related triple faults, hopefully.

Closes #33.
2023-07-21 15:14:52 +02:00
310b325af8
kernel: Avoid some more -Wconversion errors in TextConsole 2023-07-21 15:14:05 +02:00
0d924f89d3
tools: Avoid making the tests interfere with the main build directory
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 14:49:59 +02:00
de7e58c274
StringView: Fix equality operator
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 14:26:54 +02:00
c24a261233
tools: Do not use KVM when it's not supported
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 14:17:14 +02:00
edeb420d0d
Update drone.yml
Some checks failed
continuous-integration/drone/push Build is failing
2023-07-21 14:11:44 +02:00
cd6bf745a7
tests+kernel+init: Run tests automatically in a headless way
Some checks failed
continuous-integration/drone/push Build is failing
2023-07-21 14:09:37 +02:00
bcfee628cb
kernel: Remove outdated FIXME
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-15 13:19:47 +02:00
0d41e1f7b6
kernel/ext2: Change outdated FIXME
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-15 13:17:58 +02:00
f9003d7a58
kernel: Mask away unsafe bits in rflags when restoring state after a signal
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-15 11:54:48 +02:00
89786d8be2
kernel: Save/restore the SSE/FPU state when executing signal handlers 2023-07-15 11:53:50 +02:00
de6fe7f7c2
kernel+libc+sh: Make the TTY device actually follow termios rules
All checks were successful
continuous-integration/drone/push Build is passing
Like, so much more termios compatibility!
2023-07-13 20:33:20 +02:00
efd5bae7a5
kernel: Implement querying the terminal window size
Some checks failed
continuous-integration/drone/push Build is failing
2023-07-12 22:09:28 +02:00
78ea5dc352
base: Rename selene-home.sh to mount-home.sh
All checks were successful
continuous-integration/drone/push Build is passing
This makes its purpose clearer.
2023-07-12 19:47:45 +02:00
6c3ab3b27d
init+base: Allow 'Description' fields in service files 2023-07-12 19:46:53 +02:00
95cce6d592
base: Rename /etc/init/00-selene to 00-home
All checks were successful
continuous-integration/drone/push Build is passing
This makes its purpose a little bit clearer.
2023-07-12 19:40:42 +02:00
192621eac5
base: Mount the user's home directory before showing the MOTD
All checks were successful
continuous-integration/drone/push Build is passing
This way, the MOTD is shown just before login and there's less noticeable delay between the two.
2023-07-12 19:39:41 +02:00
acf4fef6f5
sysfuzz: Skip invoking sigreturn
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-12 19:37:22 +02:00
546d900454
libc+apps: Start implementing POSIX-compliant termios.h wrappers around tty ioctls
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-12 19:23:06 +02:00
2951d6d112
libc+tests: Check for manual modifications of environ
All checks were successful
continuous-integration/drone/push Build is passing
Closes #31.
2023-07-12 16:25:06 +02:00
5f698b4774
kernel: Don't create a new kernel stack on exec()
All checks were successful
continuous-integration/drone/push Build is passing
The old one was not getting freed, creating a memory leak every exec(),
which can get huge over time.
Plus, there was no need for a new stack.
And we couldn't just free the old one, since sys_execve() runs on the old stack...
2023-07-12 16:06:56 +02:00
f629e17ff4
kernel/x86_64: Only show kernel addresses in backtraces
This avoids walking off into userspace memory where we don't know what could happen.
2023-07-12 16:04:45 +02:00
1f6a0db188
su: Handle more signals gracefully
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-12 13:52:49 +02:00
81e1fdf81e
kernel+libc+login+sh+su: Implement foreground and background process groups in the default console
All checks were successful
continuous-integration/drone/push Build is passing
Also, the console sends SIGINT to the foreground process group when ^C is pressed!
2023-07-12 13:49:37 +02:00
9f45026cc2
kernel+sh: Implement interruptible syscalls 2023-07-12 13:48:43 +02:00
71ff763dd9
kernel+libc: Add the SIGTTIN and SIGTTOU signals 2023-07-12 13:45:36 +02:00
b64093dee5
kernel+libc: Implement getpgid() 2023-07-12 13:44:25 +02:00
d27ffce5db
kernel: Move the signal handling logic to after a syscall sets its return value
When a signal was caught after a syscall, it was doing so without preserving the return value of the syscall.
2023-07-12 13:34:30 +02:00
1091798195
libc: Add stub memory.h header for legacy programs
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-12 11:24:54 +02:00
9cf35f761f
libc: Fix another conversion error
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-11 12:45:55 +02:00
a51fb6a428
libc: Fix conversion error in isatty()
Some checks failed
continuous-integration/drone/push Build is failing
2023-07-11 12:45:08 +02:00
69f9701097
kernel+libc: Implement isatty()
Some checks failed
continuous-integration/drone/push Build is failing
2023-07-11 12:05:09 +02:00
7328cfe734
kernel: Add basic process groups
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-11 11:51:07 +02:00
6546f490b6
Update README.md 2023-07-11 11:50:57 +02:00
f7e8fd9cb8
libc: Add octal specifiers to inttypes.h 2023-07-11 11:49:27 +02:00
0fed45d1c6
libc: Implement _exit()
Apparently, I implemented _Exit in stdlib.h but forgot to add _exit to unistd.h...
2023-07-11 11:49:10 +02:00
82411789e8
libos+apps: Add kill
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-10 22:17:05 +02:00
86d14e0d0e
kernel+libc: Add the SA_NODEFER and SA_RESETHAND flags for sigaction()
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-07-10 21:54:04 +02:00
237184a8bf
libc+sh: Implement strsignal and use it in the shell
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-10 21:39:22 +02:00
e0b5acb2ab
libc: Make struct sigaction C-compatible
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-10 21:19:43 +02:00
66365e15a7
libc: Block and ignore appropriate signals in system()
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-10 21:17:56 +02:00
4a5947e10e
libc: Implement signal() 2023-07-10 21:17:25 +02:00
fe9827bbeb
kernel: Fix fallthrough in switch statement
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-10 21:09:12 +02:00
3df40beaf2
libc: Rewrite abort() using the new signals
Some checks failed
continuous-integration/drone/pr Build is failing
2023-07-10 21:08:23 +02:00
8066e8f1d8
kernel+libc: Implement sigprocmask() and friends
Some checks failed
continuous-integration/drone/pr Build is failing
2023-07-10 21:01:59 +02:00
015419b8f5
kernel: Generate signals when children exit / when faults occur
Userspace can now catch segfaults!
2023-07-10 20:49:22 +02:00
60d68b74e1
kernel: Define a good set of default signals
Most of these have POSIX-defined numbers.
2023-07-10 20:30:37 +02:00
cde467ee46
kernel: Support returning termination signals from waitpid
All checks were successful
continuous-integration/drone/pr Build is passing
2023-07-10 20:16:06 +02:00
fc3fdc2b87
kernel: Add default actions for signals 2023-07-10 19:59:01 +02:00
bdcb690a7a
kernel: Avoid processing unregistered signals for init 2023-07-10 19:48:46 +02:00
15d6aae701
kernel+libc: Implement basic signals 2023-07-10 19:46:57 +02:00
15199a2366
libluna+libc: Implement memchr() and strstr()
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-10 15:30:05 +02:00
56f3d26969
kernel+libluna: Fix the CRC32 algorithm and use it to verify the GPT header
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-10 14:54:55 +02:00
16b0531d42
kernel+apps+base+tools: Use Ext2 for the root partition file system
All checks were successful
continuous-integration/drone/push Build is passing
init is now split into two parts: preinit, which lives in the initrd and prepares the root file system for init,
and the actual /usr/bin/init, which lives in the root partition and starts services and reaps zombies.

The kernel now looks for /bin/preinit instead of /bin/init as the executable for the init process.

All configuration files in initrd/etc have been moved to base/etc. (The plan is to have only moon and preinit in the initrd.)

Since the current Ext2 implementation is read-only (and it's on a CDROM so it would be read-only anyways),
/home/selene is a tmpfs (as well as /tmp), to allow for a writable home directory.

The system is slower now, but that's to expect since the Ext2 code doesn't use caching and the ATA code still uses PIO.
2023-07-10 13:05:06 +02:00
40413eee18
kernel: Panic when PID 1 exits/crashes 2023-07-10 13:04:47 +02:00
e3552d9df0
kernel: Log hostname changes 2023-07-10 13:04:40 +02:00
a1b92fcc3f
kernel: Add the MOUNT_DEBUG flag 2023-07-10 13:04:34 +02:00
0b488c1232
kernel: Actually use config.cmake
Looks like file(EXISTS) needs a full path.
2023-07-10 13:04:26 +02:00
b920ffee42
kernel: Don't use an active directory for the idle thread
Just take the currently used directory.
2023-07-10 13:04:18 +02:00
503dc72686
kernel: Set kernel threads' initial active directories to avoid taking the first directory they use
This ends up being init's directory, which is fine when init's directory doesn't change...
but a little less fine when the init process calls exec()...
which is what it does in the new configuration I'm testing...
2023-07-10 13:04:00 +02:00
7908c5a63e
kernel/ATA: Do not discard the controller if at least one channel initialized properly
This was causing problems in VirtualBox.
2023-07-10 13:01:43 +02:00
ae0cd155c3
kernel: Fix AddressSpace's move assignment operator
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-09 20:43:03 +02:00
c599251d2a
kernel: Rename UserVM to AddressSpace
All checks were successful
continuous-integration/drone/push Build is passing
This is a more appropriate name now that it does more stuff than allocate virtual memory.

To be fair, the name was a bit awkward anyway. Should have been UserVMAllocator I guess.
2023-07-09 20:38:04 +02:00
5e564e9ae3
kernel: Move Thread::self_directory to UserVM
Since this is only used by user threads, UserVM is a convenient/related place to store the PageDirectory in a RAII manner.
2023-07-09 20:32:42 +02:00
5c9503ac71
libos+cp: Add prompt functionality
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-08 18:30:39 +02:00
6d9ba8deb4
libos+apps: Make the vector argument more flexible
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-08 16:44:02 +02:00
af26dce038
kernel: Zero physical frames instead of virtual pages
All checks were successful
continuous-integration/drone/push Build is passing
The memset() happens a bit earlier, and we don't have to remap the
mapped virtual memory.
2023-07-04 00:49:26 +02:00
3b1219ecf2
kernel/ext2: Make the inner extended superblock struct packed as well
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-02 19:50:27 +02:00
bd757d204e
kernel+libos+libluna: Avoid copying and reallocation when creating Strings
All checks were successful
continuous-integration/drone/push Build is passing
This is done by reusing the existing buffers in Vector and Buffer instances.
2023-07-02 19:30:25 +02:00
498e20561f
libluna: Add release_data() overloads to Buffer and Vector
This can be used to transfer the underlying data to a String object without copying.
2023-07-02 19:29:04 +02:00
d363d5e915
kernel/ext2: Make sure we don't crash when accessing the last inode
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-02 17:30:14 +02:00
f0a7098470
apps: Add cp
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-02 16:38:24 +02:00
6db0a2649c
libluna: Add a variant of PathParser::join() for relative paths 2023-07-02 16:38:12 +02:00
dd914b16d1
kernel: Stop showing memory stats at boot
All checks were successful
continuous-integration/drone/push Build is passing
No userspace interface yet, but this can be shown using Shift+Ctrl+M.
2023-07-02 16:02:38 +02:00
f8dc7c62e2
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-01 17:40:44 +02:00
21d093b1fa
initrd: Rename test-ext2fs to mount-ext2fs
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-06-25 20:54:37 +02:00
e9e7b22323
kernel: Separate a thread's page directory into two
All checks were successful
continuous-integration/drone/pr Build is passing
The self directory, and the active directory. The active directory is the one the thread is currently using,
and the self directory is the one the thread owns.

This lets us keep track of both, which fixes ext2 executables crashing the system.
2023-06-25 20:35:40 +02:00
5f4103251a
kernel: Preserve the new page directory while exec() is running 2023-06-25 20:35:40 +02:00
491416ddaf
tools: Bump up the ext2 filesystem size 2023-06-25 20:35:39 +02:00
da689dd1a7
kernel/ext2: Allow reading up to 4 MB of data from files
This is done by scanning the singly indirect pointer of the inode.
2023-06-25 20:35:39 +02:00
41f578aa18
kernel/ext2: Add support for symbolic links 2023-06-25 20:35:38 +02:00
34e1ef36b1
kernel: Make pivot_root() reset the parent entry of the new root directory
Otherwise it would just be pointing to the old parent fs, and we don't want that.
2023-06-25 20:35:38 +02:00
a62265b504
kernel/ext2: Implement directory traversal 2023-06-25 20:35:37 +02:00
d7486326bf
tools: Generate the Ext2 filesystem using genext2fs instead
mkbootimg's filenames have some kind of bug...
2023-06-25 20:35:37 +02:00
4fe6c506ec
kernel/ext2: Implement Inode::read() 2023-06-25 20:35:37 +02:00
77686b26f8
kernel/Ext2: Read the root inode metadata from the disk 2023-06-25 20:35:36 +02:00
2aa7056e11
mount: Put the source argument first 2023-06-25 20:35:36 +02:00
a9460469d9
kernel+libc+apps: Add a source parameter to the mount() system call 2023-06-25 20:35:35 +02:00
707f64acb5
kernel: Add an Ext2 filesystem skeleton 2023-06-25 20:35:35 +02:00
ddf63471a8
kernel: Add missing debug flag to debug.cmake
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-25 20:35:15 +02:00
3b6f5b28fc
kernel: Make the configurable filename restrictions actually compile
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-22 20:24:33 +02:00
fdf2bb2501
kernel: Make the filename restrictions configurable
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-22 20:22:43 +02:00
3d157b760c
kernel: Make the stack and loaded program code regions persistent
All checks were successful
continuous-integration/drone/push Build is passing
This way, they can't be modified by mmap() or munmap().
2023-06-19 12:44:49 +02:00
54a1998d42
kernel: Also move children's parent to PID 1 in the common thread exit function
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-19 12:35:31 +02:00
e60b2a3d2f
kernel: Move thread exit code into a separate common function
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-19 12:33:25 +02:00
f052d8630d
libos: Use Vector::shallow_copy() in ArgumentParser
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-19 12:23:56 +02:00
8542cf7cbf
libluna: Fix Vector::shallow_copy() 2023-06-19 12:23:39 +02:00
d50ea76bdc
libc: Make tmpfile() create files in /tmp's filesystem
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-19 11:52:38 +02:00
2edb0a3f3a
all: Update minor version number to 0.3.0 pre-release
All checks were successful
continuous-integration/drone/push Build is passing
Not a release yet, but we can give it the version number for it.
2023-06-19 11:41:10 +02:00
b4a6e4d56d
libluna/PathParser: Make dirname() and basename() static functions
All checks were successful
continuous-integration/drone/push Build is passing
This avoids creating a PathParser to use them, which allocates memory that won't be used.
2023-06-19 11:21:58 +02:00
f22689fcf5
libc: Add stubs for fflush() and ungetc()
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-19 10:48:02 +02:00
6bfc7483bc
libc: Add a definition for FILENAME_MAX 2023-06-19 10:47:43 +02:00
acfad51ac0
libc: Add freopen() 2023-06-19 10:46:08 +02:00
7efc3a6ea1
kernel: Show stack traces on page faults + crash the process instead of the whole system on GPFs 2023-06-19 10:45:08 +02:00
0b553cadc0
libluna: Do not fault if vstring_format() is called with buf=nullptr
Instead, just discard the output and return the number of bytes formatted, as mandated by the C standard.
2023-06-19 10:44:33 +02:00
ae01a31104
kernel: Make sure the stack is 16-byte aligned on program startup
This is required by the System V ABI and fixes some movaps-related GPFs in ndisasm.
2023-06-19 10:41:32 +02:00
795b0ca8d4
libc/scanf: Some refactoring
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-19 01:05:32 +02:00
21cc7e3729
libluna: Rename parse_length() to parse_type() in Format.cpp
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-19 01:00:05 +02:00
55d147841f
libc+tests: Add type modifiers and integer conversion specifiers to scanf() 2023-06-19 00:59:42 +02:00
a2c081f219
libluna: Allow passing a base to scan_(un)signed_integer() 2023-06-19 00:58:02 +02:00
8c2348c425
libc/scanf: Skip whitespace before %%
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-18 23:51:44 +02:00
25e9187826
libc+tests: Add basic support for the scanf family of functions
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-18 23:44:30 +02:00
36e6787415
kernel: Make sure addresses allocated by mmap() are ALWAYS page-aligned
All checks were successful
continuous-integration/drone/push Build is passing
Fixes a kernel crash. Thanks a lot, sysfuzz!
2023-06-18 20:29:32 +02:00
04322d9ff7
kernel: Add a customizable configuration file system
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-18 20:18:19 +02:00
b7bdec9ece
kernel: Add a bunch more config definitions and hide debug messages behind them 2023-06-18 20:18:00 +02:00
ec34937f14
tests: Add tests for libluna/CPath.h 2023-06-18 20:15:18 +02:00
08997007f2
libluna: Stop checking initialization status on every bitmap method call
All checks were successful
continuous-integration/drone/push Build is passing
Since our asserts (expect()) are enabled on release as well, this is kinda expensive.

It's up to the caller, if they receive a null pointer dereference it's
their fault for not initializing their bitmap :)

We do still assert out-of-range indexing and stuff like that.
2023-06-18 19:28:28 +02:00
148c1c7341
libluna: Add the clear_data() method to Vector and use it to optimize Base64::decode
All checks were successful
continuous-integration/drone/push Build is passing
This method clears the Vector's data without deallocating the
backing buffer, so that it can be reused without reallocation.
2023-06-18 19:24:26 +02:00
d45e9e2a8c
libluna: Simplify the API for Utf8StateDecoder by splitting it into multiple methods
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-18 18:38:01 +02:00
27d9cd0e87
kernel: Move TmpFS::*Inode into a separate file
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-18 11:33:40 +02:00
3a3473b9c2
kernel: Use memcpy() when cloning UserVM
All checks were successful
continuous-integration/drone/push Build is passing
This way, any future fields in VMRegion get copied automatically.
2023-06-18 01:54:29 +02:00
67ed18629d
kernel: Update the VM allocator for userspace to use a linked list
All checks were successful
continuous-integration/drone/push Build is passing
This can cover the entire address space at once in a more memory-efficient way.

Stress-tested using 'base64 /bin/ls' which allocates enough contiguous
virtual memory to store the entirety of /bin/ls :)

A couple of bugs and fixes later, here we are!
2023-06-18 01:48:48 +02:00
2f08e0f5b0
libos: Make long value arguments use '=' and make value arguments' values always required
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-17 20:58:54 +02:00
266fa4a0d4
kernel: Start counting partition numbers at 1
All checks were successful
continuous-integration/drone/push Build is passing
This makes more sense for the end user.
2023-06-17 19:50:58 +02:00
8ace83f2ae
tools: Create an ext2 partition with the sysroot data in the disk image
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-17 19:49:04 +02:00
7cace9a0d7
kernel: Provide more meaningful panic messages for critical failures 2023-06-17 19:43:25 +02:00
e79d4297ea
kernel: Make the root inode be a mountpoint as well + add pivot_root()
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-17 17:27:22 +02:00
a6330eaffc
libluna: Add a #pragma once to Types.h 2023-06-17 12:04:47 +02:00
b7a82fd895
kernel: Do not error out on zero-length reads/writes to bad addresses 2023-06-17 12:04:34 +02:00
592558d7ad
kernel: Add GUID partition table support 2023-06-17 12:03:37 +02:00
2be4880278
kernel: Name the scoped lock in ATADevice::read()
All checks were successful
continuous-integration/drone/push Build is passing
Is that supposed to work without a name? Looks like it did!
2023-06-17 09:46:28 +02:00
7a78609a85
kernel: Preserve kernel threads' page directories when they differ from the regular kernel page directory
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-17 00:49:31 +02:00
c2cdb861c9
kernel/ATA: Fix buffer overflow in ATADevice::read() with small sizes and unaligned offsets 2023-06-17 00:48:53 +02:00
27b26f389c
kernel: Lock ATADevice::read_lba() using ATA::Channel's KMutex
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-17 00:22:38 +02:00
4f86cd9f08
libluna: Add a so very basic HashMap
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-17 00:07:43 +02:00
32d2e0e6b7
kernel: Remove register_special_device()'s name parameter
All checks were successful
continuous-integration/drone/push Build is passing
This is now duplicate information that can be queried using device->device_path().
2023-06-16 21:46:51 +02:00
ba46399bbd
kernel/ATA: Remove debug messages
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2023-06-16 21:34:36 +02:00
738b218a49
kernel/ATA+MBR: Dynamically generate device names + create devices for MBR partitions
All checks were successful
continuous-integration/drone/pr Build is passing
2023-06-16 21:30:50 +02:00
72b8ebe02c
kernel: Make the MBR code read from a device instead of an inode
Some checks failed
continuous-integration/drone/pr Build is failing
2023-06-16 21:10:33 +02:00
72e798cedb
kernel: Do not automatically read the MBR partition table from /dev/cdrom
Since ff952cfe16 made /dev mounted from userspace, /dev/cdrom does not exist when ATA drives are scanned.
2023-06-16 21:10:33 +02:00
7593947c33
kernel/ATA: Route interrupts to the correct drive 2023-06-16 21:10:33 +02:00
93922932fa
kernel: Start reading the MBR partition table from the ATAPI drive 2023-06-16 21:10:33 +02:00
a3beaa4d53
ATA: Mark the CDROM as a block device 2023-06-16 21:10:33 +02:00
bb0db450b3
kernel/ATA: Pass extra information to DeviceRegistry
This is needed since merging e7d482e from main.
2023-06-16 21:10:33 +02:00
a0fa1f2cfd
kernel+init: Create a device node in /dev to access the CDROM from userspace!
Still using PIO, though.
2023-06-16 21:10:33 +02:00
2fa11a5ae3
kernel/ATA: Read the CDROM's first sector using ATAPI PIO!!
Sadly, for some reason, DMA is not working right now.
This is a problem, as PIO is inconvenient. But hey, it works for now!
2023-06-16 21:10:32 +02:00
cc8450751c
kernel/x86_64: Implement writing to PCI fields 2023-06-16 21:10:32 +02:00
3762d3f959
kernel/PCI: Add bit enum for the Command field 2023-06-16 21:10:32 +02:00
a99c5e325d
kernel: Actually register interrupt handlers properly 2023-06-16 21:10:32 +02:00
82db0e39ea
kernel/ATA: Calculate block sizes for ATA devices as well 2023-06-16 21:10:32 +02:00
46c45068e0
kernel/ATA: Send a READ CAPACITY packet to an ATA drive on initialization 2023-06-16 21:10:32 +02:00
cfcde5af55
kernel/ATA: Read the PCI Busmaster registers and start preparing for DMA 2023-06-16 21:10:31 +02:00
268252c89e
kernel/ATA: Read the Busmaster base port and verify it 2023-06-16 21:10:31 +02:00
5d16754632
kernel: Handle device BARs properly 2023-06-16 21:10:31 +02:00
6307b01689
kernel/ATA: Read ATA strings properly instead of backwards
Now we can see the model string. What does it say...

"QEMU DVD-ROM". Let's go!
2023-06-16 21:10:31 +02:00
e118c9ea0d
kernel/ATA: Implement enough to send an IDENTIFY command and read the model number :) 2023-06-16 21:10:31 +02:00
ee691bbb0f
kernel/ATA: Handle drive IRQs in compatibility mode 2023-06-16 21:10:31 +02:00
739950e8f0
kernel/CPU: Allow passing arbitrary data to interrupt handlers 2023-06-16 21:10:31 +02:00
3a84127fd6
kernel/ATA: Start reading/writing registers and detecting drives 2023-06-16 21:10:30 +02:00
e8507d23ee
kernel: Warn if no ATA controller is found 2023-06-16 21:10:30 +02:00
d9a1e8a980
kernel: Add a KMutex class and use that for ATA::Controller locking 2023-06-16 21:10:30 +02:00
7efc6dc985
kernel/x86_64: Add basic ATA controller and channel identification 2023-06-16 21:10:30 +02:00
beeafb73e6
kernel/PCI: Add more PCI field types 2023-06-16 21:10:30 +02:00
f0caf010bf
kernel/x86_64: Add a way to register IRQ handlers from other kernel subsystems 2023-06-16 21:10:26 +02:00
d589834eb7
libluna: Add HashTable
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-15 15:50:04 +02:00
da1439126a
libos: Correct wrong manpage section for execve()
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-09 23:35:23 +02:00
e4e501ecfe
libos: Add Process::wait()
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-09 23:12:31 +02:00
a1bf4dafbe
libluna: Remove implicit vector copying and add an explicit way to do it
All checks were successful
continuous-integration/drone/push Build is passing
Closes #28.
2023-06-09 22:54:22 +02:00
bc07cc94cb
libos: Document it entirely using Doxygen comments =D
All checks were successful
continuous-integration/drone/push Build is passing
Also, add copyright information to individual files. This is going to be a hassle to do for EVERY file.
2023-06-09 22:45:06 +02:00
5f5b58a2c0
apps: Add a syscall fuzzer
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-08 19:58:00 +02:00
d0b65674e6
kernel: Fix 0-delay sleeps blocking the thread forever 2023-06-08 19:57:38 +02:00
85896214ba
libos: Make File::read_all() read chunked blocks instead of one character at a time
All checks were successful
continuous-integration/drone/push Build is passing
This results in a speedup of 0.23s -> 0.13s for Base64 encoding of /bin/ls.
2023-06-04 00:23:06 +02:00
3283991ec6
kernel: Keep the old Timer::ticks_ms() API.
All checks were successful
continuous-integration/drone/push Build is passing
Removing this API broke the ATA branch.
2023-06-03 21:02:18 +02:00
e10cc2d954
libc: Add the internal TRY_OR_SET_ERRNO macro
All checks were successful
continuous-integration/drone/push Build is passing
Similar mechanism to TRY(), but propagating C-like errors instead of Results on failure.
2023-06-03 20:20:01 +02:00
6b4d41529e
libc: Fix execvp() calling the shell after an ENOEXEC
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-03 17:00:24 +02:00
6ad7491300
sh: Skip comments (and shebangs!) 2023-06-03 16:59:18 +02:00
8bcec00a9d
kernel: Change the timer subsystem to use timespecs natively
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-03 13:15:10 +02:00
d2334a67dd
apps: Add mktemp
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-03 12:15:57 +02:00
fd62de6474
libluna: Do not sort empty arrays; avoids a segfault
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-03 11:55:46 +02:00
1090815c8d
kernel: Honor the sticky bit 2023-06-03 11:55:10 +02:00
89d7866abb
libos: Show the sticky bit on symbolic modes 2023-06-03 11:35:13 +02:00
0540879959
init+initrd: Create /tmp and mount it on boot 2023-06-03 11:34:53 +02:00
cc72a1655d
libc+libluna: Move libluna hooks out of libc and into a central place in libluna
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-03 11:18:52 +02:00
ff952cfe16
kernel+init: Let userspace control devfs mountpoints
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-02 21:45:31 +02:00
dcb8ab569a
libc: Add basic sys/param.h for programs that want it
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-31 22:15:22 +02:00
d467f6257d
libc: Define EXIT_* macros and strto(u)ll in stdlib.h 2023-05-31 22:15:05 +02:00
5c68d50070
libc: Add a very bare-bones locale.h 2023-05-31 22:12:50 +02:00
d40654a00c
libos+ls: Allow calling ArgumentParser::short_usage() directly
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-28 21:57:04 +02:00
51a5727c8d
libluna: Fix a crash in quicksort
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-28 21:51:50 +02:00
069f1c0f97
ls: Sort displayed entries 2023-05-28 21:51:50 +02:00
e864ef2d36
libos: Add a way to also list entry sizes, modes and mtimes 2023-05-28 21:51:50 +02:00
11a4f8cc90
kernel: Wake the parent process when a child exits because of a page fault 2023-05-28 21:50:13 +02:00
30e4ef970e
all: Minor version bump up to 0.2.0
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 19:32:59 +02:00
d572d56460
libc: Add dummy time fields to struct stat
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 12:22:06 +02:00
18115ca04a
libc: Add alloca.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 12:11:51 +02:00
8d90d146b2
libc: Fix including sys/time.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 12:06:00 +02:00
88d1da59e8
kernel+libc: Add access()
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 12:04:27 +02:00
bd8aaa917f
kernel+libc+ln: Add support for userspace hard link creation
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 11:32:40 +02:00
a98e9e8009
kernel: Add /dev/full
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 10:42:45 +02:00
b0506bf88f
kernel: Add umask
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-26 22:27:49 +02:00
d89a823924
kernel: Return EACCES when trying to chdir to an unaccessible directory 2023-05-26 20:49:13 +02:00
cba0a23db9
kernel: Make the framebuffer a block device
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-26 20:36:35 +02:00
7cdb967730
kernel: compilation fix
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-26 20:30:39 +02:00
62e14e7580
kernel+libos+apps: Support block devices and disallow seeking character devices or pipes
Some checks failed
continuous-integration/drone/push Build is failing
2023-05-26 20:27:47 +02:00
38fae0c97b
ls: Show file modes visually
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-26 18:22:50 +02:00
4dcee8f828
sh: Print "exit" on EOF only when the shell is in interactive mode
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-26 17:29:41 +02:00
84c1871d30
libc: Check if a shell is available if system()'s command argument is NULL 2023-05-26 17:27:37 +02:00
3a51807fa6
kernel+stat: Handle pipes correctly in stat()
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-23 20:54:25 +02:00
9cdfdbc6f9
kernel: Handle unnamed pipes in stat()
Some checks failed
continuous-integration/drone/push Build is failing
2023-05-23 20:49:26 +02:00
1094042a7d
kernel: Implement st_dev and st_rdev
Some checks failed
continuous-integration/drone/push Build is failing
2023-05-23 20:45:24 +02:00
1a6ad11462
kernel+libc+libos+ls: Add readlink()
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-23 15:42:38 +02:00
b61307e5cb
ls: Add -1 and --directory
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-23 14:53:38 +02:00
04d074538f
ls: Don't do caching now that password/group file reading is more reasonable
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-20 22:10:01 +02:00
2c798b8bf0
Update README to match repository description
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-20 22:00:52 +02:00
597aada09e
ls+stat: Handle symbolic links properly
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-20 21:49:25 +02:00
4ec1af5e51
apps: Add ln 2023-05-20 21:49:25 +02:00
7a8ef52408
libos: Support not following symlinks 2023-05-20 21:49:25 +02:00
cb205c851c
libc: Add symlink(), symlinkat(), and lstat() 2023-05-20 21:49:25 +02:00
67a9d130e2
kernel: Add initial support for symbolic links :D 2023-05-20 21:49:24 +02:00
b75bd4cd14
libluna: Add PathParser::has_next() 2023-05-20 16:39:18 +02:00
9bb5371e8c
libluna+libc: Add strtok_r() 2023-05-20 16:37:07 +02:00
47d505dcbb
libc: Add getline() and getdelim()
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-20 15:36:30 +02:00
5117b410db
apps: Add time
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-20 12:48:25 +02:00
6de90b3c93
libc: Add getrusage() 2023-05-20 12:48:17 +02:00
01111442d3
kernel: Add the getrusage() system call 2023-05-20 12:48:07 +02:00
1fa8aeecce
libos: Allow Process::exec to take a slice of StringViews instead of Strings as arguments 2023-05-20 12:47:10 +02:00
30d1dad149
libluna: Let String::join take a vector of StringViews instead of Strings 2023-05-20 12:46:33 +02:00
1db60b5a82
sh: Print a message on exit
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-20 12:07:56 +02:00
a7c6163e7c
libc: Add gettimeofday() 2023-05-20 12:05:22 +02:00
dc169124cc
libc: Add fchown, fchmod, and some POSIX feature test macros
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-19 19:59:20 +02:00
3db0c4fed2
apps: Add ps
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-18 21:59:38 +02:00
1506331872
kernel+libc: Add the pstat() system call
Luna-specific, but I like it.
2023-05-18 21:48:47 +02:00
0dbfbe6395
libc+apps: Avoid calling endpwent() and endgrent() after every call to get{pw,gr}{nam,uid,gid} 2023-05-18 21:47:46 +02:00
84bed3ceb3
kernel+libc: Remove mknod()
All checks were successful
continuous-integration/drone/push Build is passing
Now that we automatically create files in /dev, mknod() is not needed anymore.
2023-05-18 19:42:14 +02:00
d7c563aebd
kernel: Add reference counting for mounts
All checks were successful
continuous-integration/drone/push Build is passing
This will make sure we cannot unmount a file system while there is another one mounted inside it.
2023-05-18 16:22:31 +02:00
3a73d49aa1
kernel: Remove a mount from the mountpoint list after unmounting it 2023-05-18 16:18:09 +02:00
8f6bd29da3
kernel: Make file system reference counting work for current directories
All checks were successful
continuous-integration/drone/push Build is passing
Also, make pipes usable again.
2023-05-17 20:37:01 +02:00
1f4c4928cc
kernel+libc+apps: Add mount and umount syscalls, libc wrappers, and utilities
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-17 20:30:15 +02:00
29174ca228
kernel/VFS: Add a way to unmount file systems 2023-05-17 19:52:26 +02:00
e7d482e78a
kernel+init: Add a VFS mount system and auto-populate the devfs 2023-05-17 19:40:37 +02:00
4d106b6b8c
libos: Add error handling to vector argument usage
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-13 13:22:49 +02:00
65d3195caa
libos: Allow ArgumentParser users to specify they want leftover arguments
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-13 13:22:10 +02:00
dc7e503342
tests: Test character formatting
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-13 12:50:10 +02:00
e481ce45d0
tests: Add way more tests to TestFormat now that formatting is fixed 2023-05-13 12:45:14 +02:00
e098a3269a
libluna: Treat a negative precision as if precision was omitted 2023-05-13 12:40:03 +02:00
38541e22e9
libluna: Fix flag shenanigans in cstyle_format
Finally, zero-pad and left-align work properly!
2023-05-13 12:39:31 +02:00
5911b052dc
libluna: Add more options to to_dynamic_unit()
All checks were successful
continuous-integration/drone/push Build is passing
Also, make the output look more like how it is on linux.
2023-05-13 12:01:09 +02:00
a5ad8e16de
ls: Add the --human-readable flag 2023-05-13 11:15:28 +02:00
300d68088b
libos: Add FileSystem::stat()
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-12 23:47:20 +02:00
64d0f30bd9
kernel: Disallow write-related flags when opening a directory, not only when the directory flag is set
All checks were successful
continuous-integration/drone/push Build is passing
Also return EISDIR instead of EINVAL as that is what Dr. POSIX mandates.
2023-05-11 21:29:49 +02:00
1035b91a3d
su: Do not change directory/set variables by default, instead add a --login option
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-11 20:11:09 +02:00
a935039e78
sh: Prioritize /etc/passwd over the USER environment variable 2023-05-11 20:10:10 +02:00
18130847c1
libc: Fix some environment-related bugs 2023-05-11 20:09:46 +02:00
411c6c40cd
kernel: Add the fchmodat() and fchownat() system calls
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-11 19:49:03 +02:00
4a3a92e9d4
libc: Move chmod from unistd.h to sys/stat.h
All checks were successful
continuous-integration/drone/push Build is passing
Apparently that's where it's supposed to be.
2023-05-11 19:40:34 +02:00
4a764bc315
tests+libluna: Start testing Format.cpp
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-11 16:56:28 +02:00
e203772488
README: Update broken link to ELF loader
All checks were successful
continuous-integration/drone/push Build is passing
The ELF loader was moved into the thread/ subdirectory in 0c1d33f2ec.
2023-05-10 22:58:37 +02:00
efc6d03f23
kernel+libc: Add support for unnamed pipes
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-10 22:48:31 +02:00
1a2fce5316
kernel+libc: Add the O_TMPFILE open flag and the tmpfile() function
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-09 22:04:34 +02:00
4753e80583
kernel: Make DeviceRegistry store the created devices instead of creating them when requested
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-09 18:31:27 +02:00
35b1b36599
tools+tests: Add a system to run all tests at once automatically
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-07 23:04:24 +02:00
916a73ca95
kernel: Rework the timer subsystem to count in microseconds
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-07 21:51:36 +02:00
9bab4c62a1
kernel: Compilation fixes
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-07 21:42:03 +02:00
72dadc6706
kernel: Define a constant to check for default memory access
Some checks failed
continuous-integration/drone/push Build is failing
2023-05-07 21:38:38 +02:00
b25e212880
kernel: Make a generic function for checking memory flags
Some checks failed
continuous-integration/drone/push Build is failing
2023-05-07 21:37:01 +02:00
88180b34bd
initrd: Show default credentials in the motd
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-06 22:12:06 +02:00
b08ebdc3cb
libos: Show "Options:" label even if --help and --version are the only
options
2023-05-06 22:05:08 +02:00
cd86d1d6d0
apps+initrd: Add a login utility and make it run at startup 2023-05-06 22:03:50 +02:00
b742a08cbe
su: Set the USER and SHELL variables
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-06 12:19:54 +02:00
77560bbc3e
kernel+tools: Allow loading files with different owners + add a more dynamic install script
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-06 12:11:35 +02:00
d7fee26aa2
initrd+libc: Add /etc/group and grp.h 2023-05-06 12:01:47 +02:00
9184bbfef6
kernel: Disallow passing O_WRONLY and O_DIRECTORY at the same time
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-05 18:53:50 +02:00
349ba0acb1
libc: Add syscall wrappers for unlinkat() and openat()
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-05 18:50:35 +02:00
d9d8f7cdc7
kernel: Remove unused headers from main.cpp
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-04 23:59:46 +02:00
293a992133
kernel: Add a kernel_wait_for_event() function to avoid weird calls to kernel_wait in kthreads
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-04 23:43:00 +02:00
4a7f68b989
kernel: Add a convenience wake_up() function 2023-05-04 23:35:54 +02:00
3a1c22bb93
kernel: Add keyboard combinations for debug information dumps
Ctrl+Alt+E: Dump threads
Ctrl+Alt+M: Dump memory usage
Ctrl+Alt+H: Dump heap state
2023-05-04 23:32:48 +02:00
3ed9e578c7
kernel/x86_64: Wake the IO thread up only when there is an IO event, instead of polling every 10 ms 2023-05-04 23:07:09 +02:00
96f3d29d37
kernel: Tell the reap thread to run when it's needed, instead of checking every 200 ms 2023-05-04 23:06:00 +02:00
42eb0a1d74
kernel: Freeze waitpid()'s calling thread until a child tells us it's done, instead of polling it every 10 ms 2023-05-04 23:03:31 +02:00
4616997f5b
kernel: Store a thread's parent directly instead of its parent's PID 2023-05-04 22:58:04 +02:00
58eb2d7703
libc: Print failed assertions to stderr instead of stdout
All checks were successful
continuous-integration/drone/push Build is passing
This removes two FIXMEs from the time there was no stderr.
2023-05-04 16:37:13 +02:00
44e4ca804a
kernel: Make sure argument vectors passed to execve() are not too big 2023-05-04 16:36:24 +02:00
3eb78aa5f3
libos+init: Add a new Path class to handle both file descriptors and file paths
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-03 17:37:26 +02:00
abaf24d0da
kernel/CPU: Move some stuff to StringView 2023-05-03 17:35:46 +02:00
1215c38d75
libc: Add mkdtemp() and mkstemp()
All checks were successful
continuous-integration/drone/push Build is passing
No mktemp() though, as it has race conditions and was removed in POSIX.1-2008.
2023-05-03 16:43:30 +02:00
a0b45a51de
libc: Add rand() + srand()
All checks were successful
continuous-integration/drone/push Build is passing
Very basic random number generator, but that's what rand() is.
If you want secure numbers then use arc4random() or something idk
2023-05-02 21:20:24 +02:00
d9b7e8edc0
init: Read and launch service files in order using sort()
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-02 20:56:28 +02:00
3628464284
libc: Fix some naming inconsistencies 2023-05-02 20:56:28 +02:00
d1801d484c
libc: Add qsort() 2023-05-02 20:56:27 +02:00
dcd93cce3a
libluna: Add a sort() function 2023-05-02 20:56:27 +02:00
6beea7f817
ls: Avoid printing an empty line when a directory is empty
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-02 11:00:28 +02:00
0fad179485
apps+libc+libos: Remove _LUNA_SYSTEM_ERROR_EXTENSIONS and reorder headers
All checks were successful
continuous-integration/drone/push Build is passing
libluna/libos headers can now go after errno.h, so there's no reason to keep them separate.
2023-05-02 10:51:53 +02:00
052ae4902e
libluna: Remove EFIXME and make others declare error_string() and error_name()
Closes #26.
2023-05-02 10:51:53 +02:00
7058ec945a
libluna: Use a String for name and handle prefix correctly in TarStream 2023-05-02 10:51:53 +02:00
6982a8c07e
libluna: Make String::from_string_view handle non-null-terminated strings properly 2023-05-02 10:51:52 +02:00
1444cbb3df
libluna: Allow constructing a StringView from a string that might not be null-terminated 2023-05-02 10:51:52 +02:00
1d6a39c924
libluna: Make String::split() inline
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-01 20:05:10 +02:00
376247ba8a
libluna: Add String::from_string_view()
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-01 20:03:16 +02:00
53ec448e33
ls: Add the -l flag 2023-05-01 20:01:05 +02:00
2572d5b238
libc: Add wrapper for the fstatat() system call 2023-05-01 20:00:43 +02:00
458e0a87cc
libc: Fix S_IS* macros 2023-05-01 20:00:10 +02:00
48df90e636
libos+apps: Use os::*print* instead of (f)printf
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-01 19:32:00 +02:00
a2303665fc
libos: Add os:: print(), println(), eprint(), and eprintln() 2023-05-01 19:31:15 +02:00
df590f4e26
libluna: Add String::join() 2023-05-01 19:29:17 +02:00
7fbc644753
libc: Add clearenv
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-01 19:06:31 +02:00
967758d464
libc: Implement setenv() and unsetenv()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-30 14:46:34 +02:00
ac4bbd135b
libos: Add Directory::list()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-28 22:41:44 +02:00
6c5d6aaf00
libos: Make remove_tree_at use os::Directory
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-28 21:16:44 +02:00
3e277b5d6f
libos: Introduce os::Directory 2023-04-28 21:16:43 +02:00
8adfb6fdb9
libluna: Leave String in a valid state when moved 2023-04-28 21:16:43 +02:00
ae7c841fff
tests: Make building tests optional, although with no option to toggle them on for now
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-28 20:02:49 +02:00
b34f2149ee
tests: Test libluna's UTF-8 suite 2023-04-28 20:01:45 +02:00
c5a867d81c
libluna: Add wcscmp 2023-04-28 20:00:26 +02:00
15dcd6ad15
libluna: Check the whole string in Utf8StringDecoder::code_points() 2023-04-28 20:00:14 +02:00
b4a5aff071
libluna: Fix UTF-8 encoding 2023-04-28 19:59:40 +02:00
80914f0bb9
ArgumentParser: Add support for version information
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-28 16:33:05 +02:00
0c1d33f2ec
kernel: Move some files into subdirectories
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-28 15:55:06 +02:00
52ce4b28aa
Scheduler: Remove redundant check in for_each_child
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-28 15:22:16 +02:00
7b4cfd52cd
Scheduler: Don't search threads spawned before the current thread to find children
All checks were successful
continuous-integration/drone/push Build is passing
Children will always be spawned later (and thus have a higher PID) than their parent.
2023-04-28 15:19:01 +02:00
bcdec62f51
kernel: Allow returning early from Scheduler::for_each_child 2023-04-28 15:13:53 +02:00
f3ffdd32d4
libluna: Add support for range-based iteration to LinkedList 2023-04-28 15:12:21 +02:00
77dcfab5ef
kernel: Run the initialization process in a thread
All checks were successful
continuous-integration/drone/push Build is passing
This way we can give it more stack and also reclaim it later!
2023-04-28 13:23:07 +02:00
b1e400d795
libluna: Allow callers to optimize heap allocations by telling us they won't resize the returned memory
All checks were successful
continuous-integration/drone/push Build is passing
strdup() now does this. If someone resizes strdup()-ed memory, nothing bad will happen, they will just take a small performance hit the first time.

But I think realloc-ing strdup()-ed memory is rare, that's why I did this.
2023-04-27 17:36:25 +02:00
f0fc3ec7ca
Remove old note from README
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-26 22:49:43 +02:00
7c8f195088
base64: Rename --allow-garbage to --ignore-garbage
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-26 22:37:55 +02:00
e1ac9473a2
libluna: If allowing garbage chars while decoding Base64, skip them after the padding instead of erroring out 2023-04-26 22:32:24 +02:00
fb22e14524
tests: Add tests for Base64
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-26 21:17:09 +02:00
9d33e22ae0
apps: Add base64 2023-04-26 20:58:04 +02:00
b48d1024a8
libluna: Add Base64 encoding and decoding code 2023-04-26 20:57:48 +02:00
24f4ce9669
kernel: Only allow Ctrl+D on an empty line 2023-04-26 20:42:26 +02:00
099f6131d1
kernel: Avoid printing control characters that we don't have a special meaning for 2023-04-26 20:42:08 +02:00
36bc217056
libluna: Allow constructing a Slice from another one with a different pointer type 2023-04-26 20:41:24 +02:00
cb28e2a385
libos: Add a convenience function for opening a file or standard input 2023-04-26 20:41:03 +02:00
fb09eb97ce
libos: Add File::read_all() and File::read_all_as_string() 2023-04-26 20:34:09 +02:00
5b69ce554c
init: Add a few more configuration options for services
All checks were successful
continuous-integration/drone/push Build is passing
Notably, redirecting a service's standard streams and waiting for a service to finish before continuing boot.
2023-04-25 21:00:12 +02:00
97e9fceaa4
kernel+libc: Add dup2()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-25 20:37:30 +02:00
188a97cf54
libc: Add execlp
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-25 20:25:51 +02:00
89fd57dea4
libc: Propagate all errors in execl() and execvpe() + add execle().
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-25 17:43:11 +02:00
b8ca749a6c
su: Default to root if no username is provided
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-24 22:24:07 +02:00
919c9dd3cf
sh: Build a more elaborate prompt using the system hostname and username
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-24 22:13:06 +02:00
403b0f6b94
kernel+libc+init: Add a way to modify the system hostname
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-24 21:20:44 +02:00
cfb4baab4b
apps: Add uname
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-24 21:02:04 +02:00
9eab0886b6
kernel+libc: Add uname()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-24 20:34:44 +02:00
a99a0e5a54
tests: Start testing libluna
All checks were successful
continuous-integration/drone/push Build is passing
Hooray!!
2023-04-23 21:52:28 +02:00
cf8a8c145a
init: Remove redundant continue statement
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-23 21:15:23 +02:00
de25338d6c
libluna: Remove redundant return statements in Result<void> 2023-04-23 21:15:00 +02:00
37547ec640
libluna: Run lint scripts
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-23 10:53:48 +02:00
2f2b45758e
tools: Update some of the lint scripts with a better system to find source files 2023-04-23 10:53:34 +02:00
e378d8ee2f
Revert "libos: Make File::read_line optionally strip the ending newline"
All checks were successful
continuous-integration/drone/push Build is passing
This should be done by the caller, as making libos do it will not return a different value if the line was empty or was EOF.

Fortunately, we now have String::trim.
2023-04-22 15:21:04 +02:00
c075aa77b9
init: Allow empty lines in service files 2023-04-22 15:19:37 +02:00
dcc6bbf055
libluna: Add String::trim 2023-04-22 15:19:07 +02:00
257c2ffd0a
init: Add a configurable service system instead of always starting /bin/sh
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-22 13:56:08 +02:00
63a2df112d
libos: Make File::read_line optionally strip the ending newline 2023-04-22 13:55:07 +02:00
e654ed6415
libos: Allow passing environment to Process::exec 2023-04-22 13:54:47 +02:00
5d56638851
kernel: Ignore all non-bootstrap processors
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-22 12:25:43 +02:00
60694f651f
kernel/ELF: Remove unused include
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-22 12:20:30 +02:00
2acd2ed75d
kernel/ELF: Avoid zeroing out memory twice
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-22 12:19:22 +02:00
4f6e020196
kernel+libc: Add framebuffer ioctls
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-21 18:25:53 +02:00
841fc25137
kernel+init: Add a framebuffer special device file
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-21 18:18:15 +02:00
58dc23e4d9
apps: Add stat
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-21 18:04:17 +02:00
15b76f94f4
chown: Parse the owner and group properly
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-20 20:08:49 +02:00
fb79e12248
StringView: Add split_once and to_uint 2023-04-20 20:08:49 +02:00
eb58b4acc8
libos: Add support for --help to ArgumentParser
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 19:16:45 +02:00
0058df9f01
libluna: Handle * characters correctly in cstyle_format 2023-04-19 19:05:09 +02:00
d56e8baca5
libos+rm: Add recursive removal of directories
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 18:20:44 +02:00
05144f65d1
libos: Remove unused include
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-19 18:19:22 +02:00
2ecb1e7c90
Vector: Call destructors on reassignment and call element copy constructors
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 20:17:05 +02:00
02f8a50b9d
kernel: Replace unlink() with unlinkat()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 19:36:29 +02:00
259ea86c20
libluna: Fix compilation
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 18:49:55 +02:00
8560918931
libluna: Add Result<void>::from_syscall
Some checks failed
continuous-integration/drone/push Build is failing
2023-04-18 18:49:24 +02:00
67e9543675
os: Add FileSystem::change_directory
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 18:46:19 +02:00
b7a0ad8ffb
sh: Remove stray variable
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 18:43:50 +02:00
00832163d4
libos: Add Process::exec
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 18:39:37 +02:00
6ce125d286
libos: Add a Process class
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 18:16:24 +02:00
fbb7de7156
sh: Do not leak memory when using cd
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-18 16:49:05 +02:00
4baee3a91f
sh: Close script file on exec 2023-04-18 16:42:43 +02:00
407e81b107
cat: Read into buffers instead of lines 2023-04-18 16:41:58 +02:00
fe11b04832
File: Add methods to read/write using buffers 2023-04-18 16:41:17 +02:00
51eedf2b16
Buffer: Add an is_empty() method 2023-04-18 16:40:37 +02:00
e466c51e9f
kernel: Also zero out mmap-ed pages
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-17 22:16:27 +02:00
95659639e5
kernel: Zero out allocated memory for userspace to avoid leaking sensitive data
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-17 20:11:07 +02:00
b2fe1f45ef
libc: Define NULL in stdio.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-16 22:00:41 +02:00
949321932f
kernel: Do not forbid filenames starting with a hyphen
All checks were successful
continuous-integration/drone/push Build is passing
Some programs on Linux seem to use those, better be careful.
2023-04-16 11:33:35 +02:00
3b4214c8be
dirname: Parse one-character paths properly
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-16 11:25:47 +02:00
e6954d2e49
kernel: Disallow problematic characters, control characters and invalid UTF-8 in filenames 2023-04-16 11:25:32 +02:00
82e7b0e860
kernel: Introduce *at() syscall framework, add openat() and fstatat()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-15 20:26:15 +02:00
df95126ccd
kernel: Remove unneeded debug logs & random cleanups
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-14 21:10:38 +02:00
8c4ead0c0f
libc: Add more conversion specifiers to strftime 2023-04-14 21:08:50 +02:00
b7df596f8a
libc: Add strftime()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-13 21:09:27 +02:00
1733fc810d
mkdir: Use os::FileSystem and add -p flag
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-13 18:33:56 +02:00
fb3430c56a
apps: Use os::FileSystem 2023-04-13 18:33:43 +02:00
5df16a9bff
libos: Add FileSystem 2023-04-13 18:33:04 +02:00
bd60c65e17
kernel: Make chown() search in the process's current directory 2023-04-13 18:20:07 +02:00
60c6e764a4
libos+apps: Add some missing functionality to File and eliminate any trace of C from cat and edit
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-13 17:31:21 +02:00
26ff964ec1
libos: Add a new main() function 2023-04-13 17:04:59 +02:00
d97bf991d1
libos: Add a very bare-bones C++ RAII File class 2023-04-12 21:46:10 +02:00
193d63c81b
libluna+libc: Add strpbrk()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-12 18:42:25 +02:00
3618a41bcd
apps: Add rm
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-12 18:11:43 +02:00
417e505750
kernel+libc: Add unlink(), rmdir(), remove() 2023-04-12 18:11:36 +02:00
1b4f48b92c
sh: Display the working directory as part of the prompt
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-11 22:45:33 +02:00
427662d5f1
kernel+libc: Add getcwd() 2023-04-11 22:45:13 +02:00
7db215819e
exec: Respect the program's working directory 2023-04-11 22:44:25 +02:00
3a45f4af53
su: Change the current directory to the user's home on login
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-11 22:15:46 +02:00
2a967f4b8b
kernel+libc: Add chdir() 2023-04-11 22:15:21 +02:00
2d30935fdb
kernel: Give each thread a working directory 2023-04-11 22:14:57 +02:00
dfce93c18f
ls: List the current directory by default instead of the root directory 2023-04-11 22:13:54 +02:00
79a96bf5af
kernel/ELF: Remove old FIXME
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-11 21:24:11 +02:00
13c9caa856
kernel+libc: Add stat() + fstat()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-10 19:56:03 +02:00
66c2896652
su: Use termios ioctls to turn off echoing and read a password
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-09 11:24:34 +02:00
3e5957f9fc
libc: Add ioctl() syscall wrapper 2023-04-09 11:24:13 +02:00
fee33e7a14
kernel: Add ioctls() for termios stuff to ConsoleDevice
Only handles echoing for now.
2023-04-09 11:23:57 +02:00
76eb8cd129
kernel: Add an ioctl() system call 2023-04-09 11:22:57 +02:00
e5a3bbcbbc
libc: Allow empty fields in the password file
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-08 22:19:51 +02:00
46be0bd458
apps: Install su as setuid
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-08 17:01:26 +02:00
3887b98a7d
kernel: Support setuid binaries
All checks were successful
continuous-integration/drone/push Build is passing
You still have to run "chmod 4755 /bin/su" as root inside Luna for now, as this is not done by the install scripts.
2023-04-08 16:32:56 +02:00
8b45766aaa
su: Use user names and read from the password file instead of using raw user IDs 2023-04-08 16:31:33 +02:00
7667f49d62
libc: Add a password file and pwd.h 2023-04-08 16:30:18 +02:00
3867a29a10
apps: Add mkdir, chown and chmod
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-08 14:47:58 +02:00
46ee0eb937
sh: Show hashtag on root's prompt 2023-04-08 14:47:50 +02:00
059c2bfa3f
kernel+libc: Add chown and chmod 2023-04-08 14:47:34 +02:00
0f8a46ab67
Vector: Copy the right amount in try_dequeue()
I always forget to multiply by sizeof(T)...
2023-04-08 14:46:58 +02:00
3da1849c99
kernel+libc: Add set* and get* syscalls for UIDs and GIDs 2023-04-08 13:50:18 +02:00
f6f9254eb4
kernel: Add process and filesystem UIDs and GIDs 2023-04-08 13:12:49 +02:00
208fdd64ac
execvpe: Execute a shell if errno == ENOEXEC
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-08 12:28:26 +02:00
eb3fb04734
libc: Add system()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-08 12:18:52 +02:00
95a93a7f66
sh: Parse arguments 2023-04-08 12:09:43 +02:00
0eab03848c
sh: Remove unused include
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-07 15:41:37 +02:00
9bb1720cca
libc: Add execvp() and execvpe()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-07 15:39:10 +02:00
fe348d56c0
String+StringView: Add split() 2023-04-07 15:14:46 +02:00
3a28771520
kernel+libc+apps: Add support for environment variables 2023-04-07 15:03:38 +02:00
3ef484b3f3
kernel: Add missing include 2023-04-07 14:37:06 +02:00
3a70accdeb
kernel: Move copy_string_vector_to_userspace to ThreadImage 2023-04-07 14:36:24 +02:00
b22bea84ec
kernel: Copy process name on fork()
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-07 14:02:36 +02:00
0f678f845c
String: Add operator=
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-07 12:14:21 +02:00
4cac49038c
sh: Use StringBuilder instead of C-like manual joining 2023-04-07 12:11:28 +02:00
7b8260f3f6
all: Enable/disable debug symbols/optimization in COMMON_FLAGS 2023-04-07 12:07:08 +02:00
d07b00a892
all: Move all warning flags to a common CMake variable 2023-04-07 12:02:49 +02:00
4e48d024d9
libluna: Add StringBuilder 2023-04-07 11:53:52 +02:00
4c0dff9b32
libos: Remove a stray os-freestanding from the CMakeLists 2023-04-07 11:53:41 +02:00
a9b5cf99f7
UBSAN: Add __ubsan_handle_nonnull_arg 2023-04-07 11:53:19 +02:00
8e8706be27
sh: Use try_move instead of try_set
Looks like Vector does not like being copied. I'll have to look into that later...
2023-04-07 11:52:59 +02:00
1210d2b7da
libluna: Add/remove some const qualifiers 2023-04-07 11:52:20 +02:00
1c6fd95a70
Result: Add from_syscall() 2023-04-07 10:56:49 +02:00
cb67b41a39
libc: Set errno in mbstowcs() and wcstombs() 2023-04-07 10:55:22 +02:00
1f0e185904
kernel: Use try_set_value(_or_error) in various places 2023-04-07 10:55:04 +02:00
baa2296aed
Result: Add try_{set,move}_value_or_error 2023-04-07 10:43:29 +02:00
c752b2b343
libos: Put everything under the os namespace 2023-04-07 10:40:46 +02:00
f1e2937528
ArgumentParser: Parse short value arguments 2023-04-07 10:37:15 +02:00
9b8996adeb
libluna: Add String::format 2023-04-07 10:37:00 +02:00
e6c4ceb18f Add clause about Unix to README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-04 20:57:55 +00:00
1ec2f39747 Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-04-04 20:52:28 +00:00
ed0727332b x86_64/CPU: Assign a proper IRQ number to the keyboard interrupt
All checks were successful
continuous-integration/drone/push Build is passing
Ah, the dangers of copy-and-paste...
2023-04-04 12:13:34 +00:00
e241c70aad Vector: Call destructors on deallocation
All checks were successful
continuous-integration/drone/push Build is passing
I hate the Gitea web editor on a phone.
2023-04-01 08:56:21 +00:00
e99ba4df36
date: Make the --date option require a value
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-30 21:39:42 +02:00
429e4c9f61
libc: Disable -pedantic
All checks were successful
continuous-integration/drone/push Build is passing
It does not like TRY().
2023-03-30 21:31:35 +02:00
47ee52dc0a
libc: Add execl()
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-30 21:28:39 +02:00
64bca780a7
kernel: Add /dev/zero
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-30 21:19:16 +02:00
2fbc6105d7
kernel+libc: Add O_DIRECTORY and use it in opendir()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-29 22:23:52 +02:00
61f969c60c
ls: Explicitly initialize booleans to false 2023-03-29 22:19:53 +02:00
43f90c4f88
cat: Use ArgumentParser
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-29 22:10:51 +02:00
e6645ed607
StringView+apps: Add a _sv literal suffix to not confuse function overloads
C++ was being naughty and implicitly casting our fallback const char* to a boolean.
2023-03-29 22:10:01 +02:00
e1c03150f8
ArgumentParser: Return leftover arguments from parse() 2023-03-29 22:07:42 +02:00
75c48e996a
ArgumentParser+date: Add value arguments
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-29 21:46:07 +02:00
d68f6bd76b
ArgumentParser+ls: Add switch arguments
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-29 19:25:11 +02:00
a164dcc160
libos: Add libos + very basic ArgumentParser
All checks were successful
continuous-integration/drone/push Build is passing
libluna but for stuff that interests only userspace, like an argument parser or files or stuff like that.
2023-03-29 18:27:02 +02:00
724dab636c
apps: Switch to C++
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-29 17:56:56 +02:00
ef01f187c3
libluna: Add StringView
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-29 17:43:10 +02:00
01813ff0dd
String: Rename from_string_literal to from_cstring 2023-03-29 17:34:30 +02:00
ee60ab78b3
String: is_empty + proper initialization 2023-03-29 17:32:53 +02:00
b6c35124d6
libluna: OwnedStringView -> String
Also with inline storage!
2023-03-29 17:28:22 +02:00
7b0b3dabc4
apps: Add ls
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-29 01:07:58 +02:00
3e30f0a88c
libc: Add opendir, readdir and closedir 2023-03-29 01:06:57 +02:00
5623f3c699
tmpfs: Set the mode of the root directory on creation 2023-03-29 01:06:26 +02:00
0320ffb485
Vector: Fix operator[]
Istg Vector has a curse or something, the annoying and inexplicable bugs always end up in Vector.
2023-03-29 01:05:30 +02:00
0847cfcb65
kernel: Add a getdents() syscall
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-28 21:28:56 +02:00
8eb4d693ac
VFS: Add virtual method get() for getdents() and make existence checking occur in add_entry() 2023-03-28 21:15:26 +02:00
0d54d0ece1
libc: Check for a compatible mode in fdopen()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-28 20:56:00 +02:00
6239ed83c7
kernel+libc: Add F_GETFD, F_SETFD, F_GETFL and F_SETFL to fcntl 2023-03-28 20:55:38 +02:00
df10544e84
libc: Add libgen.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-28 19:47:47 +02:00
d00ca0d3ed
libc: Add setjmp.h
All checks were successful
continuous-integration/drone/push Build is passing
Partially taken from pre-rewrite Luna, converted setjmp.asm to GNU assembly.
2023-03-28 19:40:48 +02:00
b8b8d20f5b
Vector: Let realloc do its job and thus avoid a UAF (a particularly nasty one)
All checks were successful
continuous-integration/drone/push Build is passing
Who even thought that copying from an old pointer passed to realloc() was a good idea?
Me, apparently.

Additionally, the entire point of this memcpy() was to copy the data over from the old buffer (which is already freed btw) to the new buffer, which is already done by realloc.
That's the entire point of realloc. The data is copied over by realloc already.

And even if the old pointer is not unmapped, we scrub freed memory with useless data, so the memcpy sets the vector's buffer to that useless data as well.

I don't even know how I managed to introduce so many bugs into Vector.

At least it should work properly now.
2023-03-28 18:37:12 +02:00
d41e5b7b74
libc: Add signal.h and inttypes.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-24 22:15:28 +01:00
a43550fb9a
apps: Add date
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-24 21:48:43 +01:00
1635eaf992
kernel: Eliminate the splash screen
Userspace is free to show a splash if it wants, but the kernel shouldn't force it upon us.
2023-03-24 21:48:32 +01:00
770286a19d
kernel+libc: Implement fcntl() for F_DUPFD and F_DUPFD_CLOEXEC
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-24 21:33:20 +01:00
0de41410c6
kernel: Use path as the new process name instead of argv[0] 2023-03-24 21:26:45 +01:00
8b712b04c2
kernel: Build with optimizations only in debug mode 2023-03-24 21:25:26 +01:00
36e48b2ad2
kernel: Do not attempt to close non-existent FDs on exec() 2023-03-24 21:21:13 +01:00
374a9ff7b8
kernel+libc: Implement O_CLOEXEC 2023-03-24 21:19:24 +01:00
d48d0efb07
kernel: Add names to threads
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-24 21:05:38 +01:00
4d3050eaab
kernel: Retrieve all thread information before marking it as dead in waitpid()
All checks were successful
continuous-integration/drone/push Build is passing
In case we get interrupted by the reaper thread.
2023-03-24 20:59:07 +01:00
54a4ebe5bb
sh+edit: Miscellaneous fixes
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-24 20:53:53 +01:00
e76ccd6c4c
kernel+libc+init: Add getppid() and wait()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-24 17:39:55 +01:00
7efcc06090
kernel+init+sh: Implement parent processes and waitpid(-1, ...)
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-24 17:37:04 +01:00
f084b57f39
kernel+sh: Allow using Ctrl+D to send EOF
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-24 17:21:21 +01:00
a18e50ff34
apps: Add cat and edit
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-24 00:52:26 +01:00
d63c8abbfd
kernel/x86_64: Terminate page faults in a waitpid-friendly way 2023-03-24 00:52:17 +01:00
e2eb9a92cb
sh: Don't do anything if Enter is pressed with no command 2023-03-24 00:51:42 +01:00
b6fb5f3dfe
kernel+libc: Implement waitpid()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-23 22:42:24 +01:00
41c7e3780d
kernel: Add support for exit codes and start preparing for waitpid() 2023-03-23 22:25:56 +01:00
355dd6c32b
apps: Add sh
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-23 22:19:54 +01:00
767dbf521c
Vector: Fix crash when trying to use vector after a call to clear() 2023-03-23 22:19:43 +01:00
00672c4b22
apps/hello: Demo fgets
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-23 21:35:21 +01:00
0e9890901f
libc: Add (f)getc, getchar, and fgets 2023-03-23 21:35:09 +01:00
937802964c
kernel: Invert O_NONBLOCK to check whether a thread should block 2023-03-23 21:34:38 +01:00
95e884db97
kernel: Fix compilation 2023-03-23 21:34:09 +01:00
03adaa356c
kernel: Avoid printing keypresses twice 2023-03-23 21:33:50 +01:00
cda036ce70
ConsoleDevice: Use a temporary buffer for backspace handling
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-23 21:22:12 +01:00
83492339ec
Buffer: Add an append_data() method 2023-03-23 21:20:57 +01:00
89ad6869a4
Vector: Add a clear() method 2023-03-23 21:20:41 +01:00
6f14bf553f
libc: Add missing header to fcntl.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-23 19:24:47 +01:00
bab9600be5
libc: Add creat()
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-19 19:21:36 +01:00
31ef96ebfc
libc: Add stdin 2023-03-19 19:19:20 +01:00
d33fccc66f
kernel: Implement reading from /dev/console 2023-03-19 19:15:19 +01:00
51f0bdff0e
kernel+libc: Add O_NONBLOCK
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-19 11:25:14 +01:00
41514d9ad2
kernel: Add support for blocking reads 2023-03-19 11:21:50 +01:00
cd00e41f59
arch/x86_64: Decode keyboard scancodes
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-19 11:17:43 +01:00
40f01c825d
libc: Add fork()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-18 23:58:56 +01:00
54f2d35416
kernel: Add the fork() system call 2023-03-18 23:45:48 +01:00
e664af4c2b
libc: Add execv()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-18 22:31:16 +01:00
a4ac3c85ed
kernel+libc: Copy argv to userspace
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-18 22:25:19 +01:00
0b00dc3fe4
kernel/exec: Rename item to string_addr
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-18 21:56:34 +01:00
7f50893786
kernel/exec: Copy argv from userspace
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-18 21:55:16 +01:00
49952320d6
kernel+libluna: Remove console_write entirely
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-18 20:12:59 +01:00
cb1ef3e404
libc: Add (v)fprintf and make (v)printf use that
All checks were successful
continuous-integration/drone/push Build is passing
Let's free libc of console_write!
2023-03-18 20:11:19 +01:00
6a6a56a8b4
kernel: Make /dev/console actually respect the length parameter instead of trusting userspace's null terminators 2023-03-18 20:10:00 +01:00
d01ba20749
kernel/TextConsole: Add a write() function that accepts a fixed-size buffer instead of relying on null terminators 2023-03-18 20:09:10 +01:00
629ed9e43b
libc: Start switching to /dev/console for console IO and add a proper init 2023-03-18 19:23:18 +01:00
8c831a6906
libc: Add mknod()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-18 09:13:31 +01:00
7173c05a22
kernel: Add support for special device files and add a mknod() syscall 2023-03-18 09:10:33 +01:00
d86da05bea
libluna/TarStream: Remove unused functionality
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-17 00:00:27 +01:00
b9e8030aac
kernel: Free the initial ramdisk memory after copying everything into the VFS
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-16 23:02:53 +01:00
59838f1225
kernel: Replace some raw divisions with get_blocks_from_size() 2023-03-16 23:01:35 +01:00
8c72e9a49a
kernel: Add an exec() system call
All checks were successful
continuous-integration/drone/push Build is passing
Doesn't support arguments or environment for now.
2023-03-16 22:44:58 +01:00
08c888eaae
kernel+libc: Remove (de)allocate_memory and replace it with POSIX mmap
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-14 20:43:15 +01:00
80a897fbc5
libc: Add fileno()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 17:38:35 +01:00
3cc2e4b2a4
app: Use C FILE instead of POSIX fd, and switch back to /etc/motd
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 17:36:56 +01:00
9e9f268562
libc: Make fopen() parse the mode string 2023-03-12 17:36:04 +01:00
d66506256d
kernel/VFS+libc: Introduce modes
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 16:55:46 +01:00
02dbcbbfa1
kernel: Add strdup_from_user()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 16:30:36 +01:00
682d3c753e
kernel+libc: Add mkdir()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 15:32:09 +01:00
d2049567c8
libluna+libc: Add strncmp, strncat and strncpy
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 15:20:44 +01:00
354ffd033c
VFS: Add a size() method to inodes to implement seeking to the end of a file
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 14:49:21 +01:00
b54a7f3a80
kernel+libc: Add O_* flags and parse them in open()
All checks were successful
continuous-integration/drone/push Build is passing
O_RDONLY, O_WRONLY, O_RDWR, O_TRUNC, O_CREAT and O_EXCL are fully implemented.

O_APPEND is partially implemented.

Other flags are not here yet.
2023-03-12 14:43:58 +01:00
bd572473ad
kernel: Remove FileDescriptorTable and add a helper to resolve fds to FileDescriptors 2023-03-12 13:57:38 +01:00
7e655e320a
kernel+libc: Add the lseek() syscall, and fseek, ftell, rewind, fsetpos, and fgetpos
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 13:15:24 +01:00
292433dc39
kernel+libc: Add the write() system call, and fwrite() 2023-03-12 11:37:41 +01:00
92dbe58729
libc: Unify function descriptions
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 11:15:45 +01:00
36e0a1e970
libc: Add definitions for strnlen, strndup and strlcpy to string.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 11:10:18 +01:00
377b8bea43
libc: Adjust comment in string.cpp
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 10:45:21 +01:00
3b03e19489
libc: Replace usize with size_t in string.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 10:43:13 +01:00
12bc59ead5
libc: Add strspn, strcspn, and strtok declarations to string.h
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-12 10:39:38 +01:00
af0cb83a58
libluna+kernel: Get rid of nullcpy()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 10:28:50 +01:00
7649b44aab
libc: Add declaration for strrchr (already implemented) 2023-03-12 10:27:07 +01:00
5c0104111d
libc: Implement fopen, fclose, fread, feof, ferror, and clearerr
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-12 10:23:08 +01:00
c0a7f6776f
kernel+libc: Add getpid()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-11 22:19:58 +01:00
8fa72f3cf0
kernel+libc: Implement read()
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-11 18:02:50 +01:00
810c4bc257
kernel+libc: Start interfacing with the VFS from userspace (open & close)
This commit adds open and close syscalls to the kernel, and adds matching wrappers to libc.

No read/write support, so file descriptors are kind of useless for now.
2023-03-11 17:45:20 +01:00
831973c39a
Option: Allow direct access to the underlying value via operator->
Crashes if the Option is empty.
2023-03-11 17:41:11 +01:00
30deed2820
libluna/CPath: Replace size_t with usize
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-11 10:39:42 +01:00
0c07e66c4f
Update all files from luna/ paths to libluna/
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-11 10:38:34 +01:00
28028d229f
README: Update luna/ links to point to libluna/ 2023-03-11 10:37:38 +01:00
dcf4444d0d
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-11 10:35:54 +01:00
ff468db675
kernel/ELF+Scheduler: Use VFS instead of TarStream
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-11 10:34:08 +01:00
c6aa2fe4ad
VFS: Populate the initial filesystem based on the initial ramdisk 2023-03-11 10:23:46 +01:00
ac304073b4
tmpfs: Disallow creating files/folders with already used names 2023-03-11 10:14:42 +01:00
d95ef110c9
vfs: Add support for creating directories given a full path 2023-03-11 01:13:44 +01:00
6fd28379a9
TarStream: Add a direct pointer to entry data in the Entry struct 2023-03-11 00:55:26 +01:00
e5a41d2d52
tmpfs: Implement FileInode read() and write() 2023-03-11 00:52:39 +01:00
89bea931cd
libluna: Add a very simple Buffer class, to help implement tmpfs files
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-11 00:27:08 +01:00
6fbf97292a
VFS: Implement resolve_path() using PathParser
All checks were successful
continuous-integration/drone/push Build is passing
Already works better than old luna (handles .. correctly)
2023-03-10 22:18:48 +01:00
4c66017807
libluna: Add PathParser, a C++-style way of iterating over path sections
Still uses strtok under the hood, though.
2023-03-10 22:17:16 +01:00
5a9da55e05
libluna/CString: Implement strspn and strcspn, and using those implement strtok 2023-03-10 21:32:18 +01:00
6512e9549e
tools: Make replace-stdint.sh search in libluna/ instead of luna/ 2023-03-10 21:30:59 +01:00
ff770b7328
VFS+TmpFS: Add support for creating subdirectories (mkdir)
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-10 21:09:08 +01:00
41203df472
libluna/Vector: Use bytes instead of count in resize()
This fixes a bug that was causing the heap linked list to become quite corrupted.
2023-03-10 21:07:08 +01:00
e8a401efc2
libluna/Heap: Crash the kernel (but not userspace) on invalid frees
This makes them way easier to catch and forces us to get those out of the way.
2023-03-10 21:02:09 +01:00
c376477080
libluna/StaticString: Rename OSize to OtherSize
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-08 16:41:09 +01:00
c51b119eb4
StaticString: Add a constructor that takes in another StaticString 2023-03-07 22:18:34 +01:00
abdd460525
tmpfs: use adopt_shared_if_nonnull instead of plain adopt_shared in FileSystem::create() 2023-03-07 22:16:52 +01:00
293be2c75a
tools: Use libluna instead of luna in run-clang-format.sh 2023-03-07 21:08:05 +01:00
e30eec4213
kernel/x86_64: Avoid kernel panics when a page fault occurs in a userspace thread 2023-03-07 21:08:05 +01:00
ca85a69442
kernel: Save floating-point environment when switching in and out of userspace threads 2023-03-07 20:59:11 +01:00
7d045e45c1
libluna/Heap: Zero out newly created heap blocks 2023-03-07 20:45:30 +01:00
eaed109fe9
libluna: Let Alignment.h functions take non-powers-of-two
Since the alignment must be known at compile-time, the compiler will optimize for powers of two and leave an inefficient implementation for other values.
2023-03-07 20:37:30 +01:00
80492f6ad3
luna: Add error_name, similar to strerrorname_np from glibc
All checks were successful
continuous-integration/drone/push Build is passing
man strerrorname_np(3)
2023-03-07 13:14:21 +01:00
3a2e5b7ce0
luna: Adjust cstyle_format's description
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-02 13:40:42 +01:00
de38eb6877
luna: Remove pure_cstyle_format
All checks were successful
continuous-integration/drone/push Build is passing
It was causing a lot of code duplication. If someone doesn't have errors, just return {} from the callback and unwrap the Result.
2023-03-02 13:38:21 +01:00
a595a77421
kernel: Print percentage in splash screen
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-27 16:27:59 +01:00
b978d02cfb
luna: Fix %% skipping a character 2023-02-27 16:27:45 +01:00
9afff7c544
kernel: Add a fun splash screen during boot :)
All checks were successful
continuous-integration/drone/push Build is passing
Mostly for fun.
Has a lot of delay in order to see the actual splash screen.
2023-02-27 16:23:51 +01:00
517ef70214
luna: Add UBSAN.cpp to CMakeLists
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-27 15:25:20 +01:00
77887eed80
luna -> libluna
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-27 15:22:39 +01:00
65dd3cd7fb
TmpFS: Use StaticString<128> instead of char[128] 2023-02-27 15:22:39 +01:00
5a9d31c2be
luna: Add StaticString, an OOP char[] 2023-02-27 15:22:39 +01:00
8ba571a30e
TmpFS: Use a fixed char array in DirInode's Entry instead of OwnedStringView 2023-02-27 15:22:39 +01:00
f88dc050a9
luna: Add strlcpy() 2023-02-27 15:22:38 +01:00
4fc16915d3
Vector: Fix try_append (hopefully)
Still doesn't work with OwnedStringViews inside of structs.
2023-02-27 15:22:38 +01:00
01b6294f76
kernel: Implement creating file inodes in tmpfs directories 2023-02-27 15:22:38 +01:00
a65f4311aa
tmpfs: make the root inode a DirInode instead of a FileInode 2023-02-27 15:22:38 +01:00
dd2f31d8d0
tmpfs: add DirInode skeleton 2023-02-27 15:22:38 +01:00
5fb292bc0e
tmpfs: rename tmpfs::Inode to tmpfs::FileInode 2023-02-27 15:22:37 +01:00
d3bda46325
tmpfs: Make m_next_inode_number atomic 2023-02-27 15:22:37 +01:00
ba9d725481
kernel: Rename FileSystem::root() to root_inode() and add a shortcut for the root filesystem's root inode 2023-02-27 15:22:37 +01:00
3a2b8bcfd7
kernel: Make a factory function for filesystem creation of inodes, and add inode numbers
Now every filesystem must provide fs->create_file_inode() for new inodes :)
2023-02-27 15:22:37 +01:00
a49555addc
kernel: Add a subclass of VFS::Inode to make it easier to implement file inodes 2023-02-27 15:22:36 +01:00
529b84cd1e
kernel, luna: Port non-VFS changes over from pull request #22
OwnedPtr, SharedPtr: Add operator bool
Option, Result: Make try_move_value() non-const since it modifies the Option
kernel: Switch to a stack we control for the main task as soon as we leave early boot
Heap: Fix GPF caused when making many small allocations
Heap: Avoid accessing a block after it's potentially deleted
luna: Skip UBSAN.cpp in CMakeLists as that's not implemented yet
luna: Use spinlocks in the heap implementation
kernel, luna: Move Spinlock.h to luna
Option: Use __builtin_launder to ensure that the compiler doesn't label this as UB
SharedPtr: Implement make_shared using adopt_shared
SharedPtr: Delete ptr on failure in all adopt_shared* functions
2023-02-27 15:22:36 +01:00
b9fb4c1ce6
SharedPtr: Implement make_shared using adopt_shared 2023-02-27 15:22:36 +01:00
be408c4cdb
SharedPtr: Delete ptr on failure in all adopt_shared* functions 2023-02-27 15:22:36 +01:00
38f0d3a4e6
luna: Skip UBSAN.cpp in CMakeLists as that's not implemented yet 2023-02-27 15:22:24 +01:00
9274ad0404
kernel, luna: Move Spinlock.h to luna 2023-02-27 15:22:24 +01:00
c422d11682
kernel: Start working on a VFS implementation using OOP and SharedPtr 2023-02-27 15:22:24 +01:00
71b981175e
InitRD: Use MMU::translate_physical_address instead of allocating VM
All checks were successful
continuous-integration/drone/push Build is passing
This one is a perfect candidate, since we're just mapping a fixed continuous range of physical memory to virtual memory.
2023-02-27 13:27:21 +01:00
f0a3f99cf9
MemoryManager: Initialize KernelVM at the end of init()
KernelVM is not needed for MMU's init process anymore.
2023-02-27 13:24:58 +01:00
519aa347dd
x86_64: Remove recursive mapping related things from MMU.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-27 13:07:52 +01:00
3ec54fafde
x86_64/MMU: Do not allocate level 1 page tables for huge page entries
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
This would leak memory, since we would never end up using them.
2023-02-27 12:55:15 +01:00
752dfdbf1c
MemoryManager: Reuse the existing mapping of physical memory that MMU has
All checks were successful
continuous-integration/drone/pr Build is passing
2023-02-27 12:51:29 +01:00
8df441064f
x86_64/MMU: Map the physical address space using huge pages 2023-02-27 12:47:17 +01:00
426f6e4da8
x86_64: Allow mapping huge pages, but don't do it yet 2023-02-27 12:41:28 +01:00
837d483e0b
x86_64/MMU: Copy from the mapped kernel directory instead of the physical version
All checks were successful
continuous-integration/drone/pr Build is passing
2023-02-27 12:30:52 +01:00
995d1bc36e
x86_64/MMU: Map all physical memory into the higher half instead of using recursive mapping
All checks were successful
continuous-integration/drone/pr Build is passing
This still has a few problems. Notably, we are not using huge pages for this mapping, which would be a lot more efficient.
Right now, used memory is 8.1 MiB at boot for a 256MiB system.
But after improving it, this system will be much better than recursive mapping.
fork() will be MUCH easier to implement, for example.
2023-02-27 12:24:21 +01:00
7dd8e85554
Update README.md with realism 2023-02-25 18:20:06 +01:00
0985b75057
kernel: Add a guard page to the bootstrap stack so that we can catch more stack overflows
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-25 17:42:32 +01:00
4fd871fdaa
luna: Introduce fail(...), a replacement for expect(false, ...)
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-25 17:41:28 +01:00
8352df5ee8
kernel: Enable UBSAN when building in debug mode
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-25 17:37:50 +01:00
da436b3856
luna: Add UB sanitizer, for both kernel-space and userspace 2023-02-25 17:37:38 +01:00
03ed2c3e12
libc: Make dbgln() also print a newline in userspace
Previously, dbgln() only printed a newline in kernel-space.
2023-02-25 17:36:03 +01:00
794567327f
kernel, luna: Port non-VFS changes over from pull request #22
All checks were successful
continuous-integration/drone/push Build is passing
OwnedPtr, SharedPtr: Add operator bool
Option, Result: Make try_move_value() non-const since it modifies the Option
kernel: Switch to a stack we control for the main task as soon as we leave early boot
Heap: Fix GPF caused when making many small allocations
Heap: Avoid accessing a block after it's potentially deleted
luna: Skip UBSAN.cpp in CMakeLists as that's not implemented yet
luna: Use spinlocks in the heap implementation
kernel, luna: Move Spinlock.h to luna
Option: Use __builtin_launder to ensure that the compiler doesn't label this as UB
SharedPtr: Implement make_shared using adopt_shared
SharedPtr: Delete ptr on failure in all adopt_shared* functions
2023-02-25 17:09:03 +01:00
89958fbc74
kernel: Show a more technical message on failure to remap kernel data sections
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-02 21:26:07 +01:00
c05a87c7ff
kernel: Reenable the text console on panic
All checks were successful
continuous-integration/drone/push Build is passing
2023-02-01 22:58:31 +01:00
e9a009478f
SharedPtr: Fixes and support for casting to other SharedPtr types
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-31 19:59:06 +01:00
3a84e4998c
kernel/Thread: Add FIXME
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-31 17:02:49 +01:00
35501407c1
kernel: Stop shouting when creating threads
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-25 21:25:34 +01:00
fd0e29ede5
kernel: Add FIXME in copy_to_user()/copy_from_user()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-25 21:22:14 +01:00
8098ff0616
tools: Avoid rebuilding libc and friends every single time
All checks were successful
continuous-integration/drone/push Build is passing
We do this by preserving timestamps when copying headers so CMake doesn't think they have changed.
2023-01-25 21:16:20 +01:00
635437a4a4
luna: Add a new idiomatic way to mark unused parameters as used while keeping their names
Just call ignore(...)
2023-01-25 21:14:44 +01:00
39042cbbd4
kernel: PCI constness updates
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-25 21:01:45 +01:00
fa29d6e9b9
kernel: Rename PCI::callback_t to PCI::Callback
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-25 20:58:59 +01:00
15c89a3592
kernel: Implement filtered PCI scans
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-23 21:24:05 +01:00
3a4ca73df7
kernel: Sync log output
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-23 20:42:34 +01:00
6677c643a5
kernel: Start scanning the PCI bus for devices
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-23 20:07:17 +01:00
de04c094e7
x86_64: Skip enabling WP for now until I find how to check for its availability 2023-01-23 20:06:45 +01:00
8cb9c14b1e
luna/Format: Make output_(pure_)integer_data take a const reference to vstate
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-22 17:36:02 +01:00
7f8a8cdcaf
kernel, libc: Add an usleep() system call and use that to implement usleep() and sleep() in libc
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-22 15:00:20 +01:00
d5b1d72396
x86_64/MMU: Map the kernel page directory to virtual memory
This avoids depending on the kernel address space to create a new userspace one,
since there is no physical memory access.

This was fine for a single process, since its address space was created from the kernel one
and no more address spaces were created,
but for two or more, this started to become problematic, since we would create one address space
while being in another process's address space, which has no direct mapping of physical memory.
2023-01-22 14:46:03 +01:00
a7a38d3433
Bitmap: Add a fallible variant of match_region() that does not crash if arguments are out of range
All checks were successful
continuous-integration/drone/push Build is passing
This lets us call deallocate_memory() with any address and it will not crash.
2023-01-22 14:25:51 +01:00
cb59a4e0e3
libc: Add assert.h
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-22 12:51:30 +01:00
34a9b35037
Option, Result: Propagate caller locations when erroring out
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-22 12:00:52 +01:00
0126a8fb6e
luna: Add a new SourceLocation class and use that in check() and expect() 2023-01-22 11:43:48 +01:00
129297a0b0
CString: Fix compilation in strnlen() 2023-01-22 11:43:10 +01:00
cf8d3c6ff9
OwnedStringView: Add a method to extract a substring
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-22 11:27:54 +01:00
12d2039f68
CString: Add strnlen() and strndup() 2023-01-22 11:27:37 +01:00
944d32de36
Bitmap: Introduce new malloc-aware initialization functions
All checks were successful
continuous-integration/drone/push Build is passing
Lets us call resize(new_size) instead of initialize(realloc(location, new_size), new_size)
2023-01-21 23:16:50 +01:00
0e607c2fef
Bitmap: Declare more variables as const
I miss Rust's immutability-by-default...
2023-01-21 23:04:21 +01:00
a6974b605e
tools+CMake: Prefix all environment variables with LUNA_
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-21 22:44:16 +01:00
a3d0fa7d0a
UserVM: Validate the entire range when freeing multiple VM pages
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-16 21:16:38 +01:00
631cdd0204
x86_64/CPU: Skip null instruction pointers on stack trace generation
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-16 20:44:45 +01:00
c374c25523
Convert some FIXMEs into NOTES
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-16 20:30:35 +01:00
1d92784608
luna, kernel: Replace some uses of char by truly 1-byte wide types
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-16 19:52:34 +01:00
329e8ab182
luna/Heap: Scrub reallocations properly 2023-01-16 19:50:35 +01:00
1b807a4e06
arch/Timer: Make sure ARCH_TIMER_FREQ is a power of two
(avoid division and modulo, division is slow)
Fortunately, GCC will optimize divisions by powers of two to simple bitwise shifts :)
2023-01-16 19:43:05 +01:00
d0600f5714
luna: Make Utf8StringEncoder short-circuit instead of failing when hitting the length limit
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-14 12:07:08 +01:00
e3ef29e80d
libc: Implement wcstombs()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-14 11:59:08 +01:00
00ee8314b3
luna: Make Utf8String{De,En}coders return the number of bytes written
This means we can avoid a call to code_points() in mbstowcs(),
which would parse a string twice.
2023-01-14 11:55:19 +01:00
da805eec83
Describe what check() and expect() are
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-14 10:59:30 +01:00
eb35abfa52
Vector: Assigment, copy&move constructors, and destructor 2023-01-14 10:50:28 +01:00
3b4b750cbf
luna: Vector is here!!
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-13 22:28:03 +01:00
28bde216c4
libc: Implement perror()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-13 21:08:10 +01:00
e676fb8299
libc: Add a wide range of time manipulation functions, including reentrant variants 2023-01-13 21:06:27 +01:00
2d2db300b0
libc: Add malloc(), calloc(), realloc() and free()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-13 20:00:20 +01:00
5fb2ff09c7
kernel, luna, libc: Move the heap code to a common zone, to be used by both kernel and userspace 2023-01-13 19:27:53 +01:00
d864bda751
libc: Add (de)allocate_memory wrappers located in sys/mman.h 2023-01-13 19:08:02 +01:00
139c0b5eb1
Kernel: Make a UserVM wrapper around Bitmap and use that to allocate user VM
This lets us allocate more than one page of memory from the user side.
2023-01-13 19:05:20 +01:00
7462b764d8
Kernel: Add __cxa_atexit iomplementation 2023-01-13 18:56:05 +01:00
09dc8bd522
Bitmap: Add find_region() and find_and_toggle_region() 2023-01-13 18:55:31 +01:00
59db656f25
size_t -> usize 2023-01-13 18:55:05 +01:00
16a62552db
SharedPtr: Add a nullptr constructor 2023-01-13 18:54:39 +01:00
445aeed80d
OwnedPtr: Implement assignment operators 2023-01-13 18:54:25 +01:00
9454b65682
allocate_memory: Respect PROT_NONE 2023-01-12 17:59:17 +01:00
586ca19b62
Add a VERY BASIC and hacky way of allocating memory from userspace
All checks were successful
continuous-integration/drone/push Build is passing
Only supports one-page allocations and doesn't have libc wrappers, which means it has to be invoked using syscall().
2023-01-11 23:02:42 +01:00
0e1e15e85a
Result: Construct a Result from an Option using from_option() 2023-01-11 23:02:42 +01:00
79a5b98d65
Kernel: Keep the user pointer const through copy_from_user()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-11 19:26:53 +01:00
6e4cd6300d
Kernel: Add copy_from_user() and copy_from_user_typed()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-11 19:25:28 +01:00
73ddd0b0c5
tools: Be more arch-agnostic
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-11 19:14:35 +01:00
d150c55143
TarStream: Support mode
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-11 18:42:50 +01:00
82b555cf5c
TarStream: Refactor the API to get rid of that awful method in Result
All checks were successful
continuous-integration/drone/push Build is passing
That method being try_set_value_with_specific_error()
2023-01-11 17:30:53 +01:00
6cf042e65e
Result: Remove m_has_value, rely on Option::has_value()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-11 17:09:32 +01:00
67ebb00bd3
Option, Result: Introduce try_move_value(), which is the release_value() equivalent of try_set_value() 2023-01-11 17:06:17 +01:00
84c82a4e75
luna, kernel: More constness
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-10 19:31:41 +01:00
5aa667c776
luna: Make OwnedStringView::clone() just call from_string_literal()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-10 19:03:00 +01:00
3ac3d54788
luna: Make check() and expect() output errors in userspace 2023-01-10 19:02:16 +01:00
c82ed5df01
Enable -Os on all targets 2023-01-10 18:13:21 +01:00
feaf9ed19b
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-09 18:16:39 +01:00
c83f6c03b5
Bitmap: Add a 'find_and_toggle' method
All checks were successful
continuous-integration/drone/push Build is passing
Just like find(), but toggles the value when finding it.
Avoids doing this manually in MemoryManager and KernelVM.
2023-01-09 18:08:50 +01:00
4287ec6cb0
Bitmap: Introduce a new method 'find' and use it in MM and KernelVM
All checks were successful
continuous-integration/drone/push Build is passing
This method looks for the first bit with a value, optionally from a starting index, and returns its index.
This should be (haven't benchmarked) way faster than the manual way,
AKA what MM and KernelVM were doing.

This is due to this method using bit and byte manipulation tricks instead of just calling get() until getting the desired result :)
2023-01-09 17:59:52 +01:00
31ee97b7de
Remove restart from CI configuration
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-08 15:55:26 +01:00
15c5b80dc9
Rewrite README.md now that restart is gone 2023-01-08 15:55:01 +01:00
afe9a01bbf
Merge branch 'restart' into main
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #21
2023-01-08 15:45:56 +01:00
1f135261e7
Revert "Kernel: Make readdir() available in created InitRD directories"
This reverts commit 511bb7a8c1.
2023-01-08 15:42:48 +01:00
49d1e4f011
Revert "mprotect(): Validate the entire range to protect is in userspace memory"
This reverts commit 4ef764e62e.
2023-01-08 15:41:53 +01:00
401a807551
Revert "Update README.md"
This reverts commit 1f4c4f1a0c.
2023-01-08 15:41:39 +01:00
b0e5d02c9a
kernel: Turn off console logging before starting the init process
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
2023-01-08 15:32:59 +01:00
a620b00b18
Unify libc header descriptions 2023-01-08 15:29:30 +01:00
8de59138ef
We are platform-agnostic now (kind of)
All checks were successful
continuous-integration/drone/push Build is passing
Still tied to x86_64, but because there's no other platform implemented.

Also making this commit just to test CI with the new toolchain.
2023-01-07 21:42:57 +01:00
0c5a84f932
toolchain: Update to binutils 2.39
Some checks failed
continuous-integration/drone/push Build is failing
CI will fail, it's normal. Wait for me to build a new toolchain for it.
2023-01-07 21:23:01 +01:00
0c73d69a70
Kernel: Fix shadow 12GiB reserved entry when running QEMU without KVM on
All checks were successful
continuous-integration/drone/push Build is passing
Fix inspired by: https://github.com/serenityos/serenity/pull/16345
2023-01-07 20:58:12 +01:00
c97f588d44
Fix TRY() with Option 2023-01-07 20:53:23 +01:00
fde1727218
KernelVM: Expand the available VM range
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 12:33:00 +01:00
8ee634d19b
Kernel/Scheduler: Display addresses starting with 0x when creating threads
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 12:02:14 +01:00
471103e4f3
Remove the word 'header' from libc header descriptions
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 11:39:15 +01:00
12dc96b4a5
Fix comment typo
All checks were successful
continuous-integration/drone/push Build is passing
My bad :(
2023-01-07 11:31:08 +01:00
b70bbc0ba6
More libc commenting
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 11:21:53 +01:00
7e377ef712
Implement printf()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-07 01:49:26 +01:00
29bd8a69fa
MemoryManager: Add helper functions to validate arbitrary ranges of userspace memory 2023-01-07 01:39:33 +01:00
7fb2807d0c
libc: Implement time() using clock_gettime().
All checks were successful
continuous-integration/drone/push Build is passing
The cool POSIX kids use clock_gettime() now because it has NANOSECONDS (and different clocks!),
but ANSI C prefers this function.

We can still implement it based on clock_gettime(), we just have to discard the NANOSECONDS.
2023-01-07 00:27:23 +01:00
a8a64863c8
kernel, libc: Add clock_gettime() 2023-01-07 00:21:08 +01:00
6e9b4491a6
MemoryManager: Add copy_to_user() and copy_to_user_typed() 2023-01-07 00:17:16 +01:00
b851dcf9b9
libc: Implement mbstowcs() using Utf8StringDecoder
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 21:01:37 +01:00
8891304509
libc: Add ctype.h 2023-01-06 20:48:08 +01:00
80f5c790f8
Implement string formatting into libc :)
All checks were successful
continuous-integration/drone/push Build is passing
Of course, using <luna/Format.h> makes it so simple. No need for duplicate code!
2023-01-06 20:15:43 +01:00
367a2ce521
libc: header documentation for supported functions
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 20:02:07 +01:00
c3653cd4e6
More stdlib.h implementation + commenting + atexit()
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 19:40:25 +01:00
50509baea6
More c_cpp_properties.json
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 19:06:47 +01:00
65d2f1c041
Update c_cpp_properties.json
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 19:03:35 +01:00
0a472000be
Fix CI by providing a host C++ compiler
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 19:00:32 +01:00
83651b4b90
CMake: Respect the ARCH env variable
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 18:59:59 +01:00
bdfe7dac17
libc: Remove crti.o and crtn.o
Some checks failed
continuous-integration/drone/push Build is failing
Looks like these are now provided by the compiler.
2023-01-06 17:59:54 +01:00
8838e2cf22
Bring back the OS-Specific Toolchain on restart :^)
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 17:35:07 +01:00
e37280b0e5
ELFLoader: Set both the read-write and execute flags if the section has both
Not good for W^X, but the compiler decides to squash everything into a single program header :(
2023-01-06 17:34:24 +01:00
87a4bc91d8
arch/x86_64: Nicer display for page faults that shows a human-readable version of the error code 2023-01-06 17:31:22 +01:00
a01b56ed39
CString: Support strcpy(), strcat() and strchr() 2023-01-06 16:20:35 +01:00
30555f8e5a
Skip these because CI needed a toolchain rebuild
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-06 15:00:49 +01:00
7acef24494
Make libc depend on crt{0,i,n}.o
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 14:32:38 +01:00
71414c0653
Explicitly set the link path to make it build on CI
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 14:28:53 +01:00
db1941140c
Explicitly include system headers to make it build on CI
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 13:40:53 +01:00
08608d2344
Depend on libc headers
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 13:38:48 +01:00
f1923ce5bd
Install headers before compilation
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 13:35:57 +01:00
129e3c434a
Switch to C for userspace, with a very bare-bones libc!!
Some checks failed
continuous-integration/drone/push Build is failing
2023-01-06 13:31:14 +01:00
b27cefb9c5
SystemError: Define _LUNA_SYSTEM_ERROR_EXTENSIONS to compile properly in hosted envs 2023-01-06 13:30:49 +01:00
293b979e75
ELFLoader: Do not crash on non-page-aligned sections 2023-01-06 13:30:17 +01:00
fd8a0175d9
Add a syscall infrastructure (our baby program can print to the console now!)
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-05 22:39:56 +01:00
caa3fe8c45
MemoryManager: Add validate_userspace_string()
A bit crude, should be replaced by a strdup_from_user() helper to avoid touching userspace memory directly.
But it'll do for now.
2023-01-05 22:39:09 +01:00
0ea9974512
First user process!
All checks were successful
continuous-integration/drone/push Build is passing
Putting it all together, we have a user process that successfully calls sys_exit() w/o crashing.
2023-01-05 21:55:21 +01:00
0aac6c888d
x86_64: Basic exit() syscall!
User processes need to do something, amirite?
2023-01-05 21:53:48 +01:00
a33a72915e
Scheduler: Creation, destruction and switching of userspace tasks :))
From a TarStream. Not optimal, but OK for the moment.
2023-01-05 21:52:26 +01:00
ea89b92675
Store a bit more stuff in a thread :) 2023-01-05 21:50:53 +01:00
31ea030c7f
MMU: Add functions to create and delete userspace page directories 2023-01-05 21:50:26 +01:00
c53bba0392
MemoryManager: Add an unmap_weak_and_free_vm() helper function
This function mirrors unmap_owned_and_free_vm(), but using weak unmapping (does not free the underlying physical memory)
2023-01-05 21:50:06 +01:00
d3c414af4e
ELFLoader: Do not keep track of segments
This reduces calls to kmalloc() since segment data is heap-allocated, and the segments loaded will be deleted when deleting the page directory.
2023-01-05 21:46:03 +01:00
f0e14cf7e9
Update year range in LICENSE :)
All checks were successful
continuous-integration/drone/push Build is passing
2023-01-02 13:08:42 +01:00
5854e5e530
Add newlines at end-of-file 2023-01-02 13:07:29 +01:00
aab3a0a840
Update settings.json 2023-01-02 13:07:13 +01:00
3442970678
Add vscode configuration 2023-01-02 13:00:22 +01:00
4ef764e62e
mprotect(): Validate the entire range to protect is in userspace memory
Before this patch, sys_mprotect() only validated the starting address.
This was as bad as it sounds, in fact it let me write a fun exploit
using it.
Now, this exploit is no longer possible.

This patch is probably not relevant, since this branch will be gone in
the future, as soon as restart gets merged into main.
I made it anyways :^)
2023-01-02 11:51:08 +01:00
df8f9c6cf6
SharedPtr: adopt_shared_from_owned
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-31 12:02:15 +01:00
831711ab7e
TypeTraits: Remove const, volatile, and reference
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-31 11:50:30 +01:00
e2e21923d7
Result: Implement operator=()
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-30 19:06:47 +01:00
4081186b27
Heap: Rewrite kmalloc to use Option<HeapBlock*> instead of nullable pointers to iterate over the heap
All checks were successful
continuous-integration/drone/push Build is passing
At some point, this should be done inside LinkedList itself, but we have no such thing as break in for_each().
It's iterate over everything or nothing.

This also requires operator= in Option, might be also added to Result in the future.
2022-12-30 19:02:25 +01:00
3a3968b268
Result: Add nonnull_or_error() 2022-12-30 18:46:27 +01:00
973e39a255
LinkedList: Move nonnull_or_empty_option to Option.h so everyone can use it 2022-12-30 18:46:18 +01:00
28f53f9ccf
LinkedList: Rename the nonnull_or_error() helper to a more accurate nonnull_or_empty_option() 2022-12-30 18:44:37 +01:00
1f36ecd044
LinkedList: Make expect_first() and expect_last() show a more accurate error description on panic
Instead of showing a generic "Option::value() called on an empty Option" with no useful source location,
you will get something like "check failed: m_start_node at LinkedList.h:139"
2022-12-30 18:43:39 +01:00
24773fbece
kernel/main: Remove reference to 'extern const BOOTBOOT bootboot' 2022-12-30 18:38:50 +01:00
74aa30a44f
Init: Call efficient_halt() on magic number mismatch instead of busy-looping 2022-12-30 18:36:22 +01:00
9569385691
Remove unused include 2022-12-30 18:32:44 +01:00
400d0395a2
Result: Avoid double-checking when calling through to the underlying Option
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-30 15:00:02 +01:00
8e59a0a79f
CMakeLists improvements
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-30 11:48:18 +01:00
7952d1d8a0
x86_64: Add basic keyboard support with an ASYNC DRIVER
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-26 19:59:18 +01:00
ed34009b50
Heap: Log more details of blocks
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-26 16:17:24 +01:00
2af3997456
LinkedList: Fixed some boogs, LinkedList is now boog-free :) 2022-12-26 15:54:29 +01:00
1c70ab5a1a
Heap: Avoid combines with blocks outside a range 2022-12-26 15:20:56 +01:00
a1eca479d5
x86_64: Add a getter for the initial page directory
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-26 12:57:25 +01:00
2600acc96c
Thread: Add init_regs_user() 2022-12-26 12:46:07 +01:00
7efb79dd26
LinkedList: Check for nullptrs in detach_from_list() 2022-12-26 12:45:49 +01:00
7e62ee66be
Change heap.first().has_value() to the cheaper heap.count()
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-26 12:24:39 +01:00
73c58bd902
Init: Move platform_init() before MemoryManager::init()
All checks were successful
continuous-integration/drone/push Build is passing
This enables NX before we actually use it.
Wasn't causing problems with KVM on, but crashed with KVM off with a 'reserved bit set' page fault.
2022-12-26 12:12:55 +01:00
0054777e7d
x86_64: Warn if NX is not supported 2022-12-26 12:11:10 +01:00
08984e1673
x86_64: Create a has_flag() helper function and remove redundant clearing of reserved bits 2022-12-26 12:10:47 +01:00
59d69f684f
x86_64: Add general protection fault handler
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-24 11:49:47 +01:00
f71ccde833
Add an overload for aligned deletes which just calls the normal operator delete 2022-12-24 11:49:12 +01:00
f2cc797599
Add a simple ELF loader
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-23 13:09:21 +01:00
e5ae2b0435
TarStream: Make read_contents and friends const 2022-12-23 13:08:31 +01:00
ad0f6546d7
Add a global initrd TarStream to make the initial ramdisk accessible everywhere
All checks were successful
continuous-integration/drone/push Build is passing
It's also mapped into virtual memory instead of directly going into the physical location!!
2022-12-23 11:33:23 +01:00
6ff92b1714
MemoryManager: Add get_kernel_mapping_for_frames()
This function allocates a continuous range of VM and maps the physical frames passed to said VM range.
2022-12-23 11:30:49 +01:00
74235c2c99
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-23 11:06:59 +01:00
e6384ae90d
Use the new toolchain location
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-23 11:06:37 +01:00
575752eb23
Update drone config to pull toolchain from a new purpose-built toolchain archive for CI 2022-12-23 11:04:50 +01:00
c39e54b7c6
Make TarStream::read_contents take any pointer as output 2022-12-23 10:51:55 +01:00
34e6c05cef
Fix it up a bit more
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-23 10:48:00 +01:00
913b13b380
Fix up the header install script
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-23 10:46:44 +01:00
4fa33a9689
SharedPtr: Add operator=
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-23 10:31:48 +01:00
bd4b05e534
Add OwnedPtr and SharedPtr
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-23 10:23:13 +01:00
9afaad8fed
Add dbgln() for the luna library
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-22 18:00:35 +01:00
a3595e71a9
Update .clang-format
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-21 20:22:44 +01:00
96135ff808
Use limits.h for the standard definition of WCHAR_MAX
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-21 20:11:00 +01:00
16bf8b38ea
UTF-8 decoder: Error out on overlong encodings
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-21 20:08:43 +01:00
fcefab4383
TextConsole: Add wide-character overloads for print() and println()
All checks were successful
continuous-integration/drone/push Build is passing
These can't fail from UTF-8 decoding errors.
2022-12-21 19:41:13 +01:00
293b7b0f11
TextConsole: Propagate UTF-8 decoding errors
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-21 17:38:19 +01:00
2e8ea724a0
arch/x86_64: Refactor the stack tracing code to remove duplicate code
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-21 17:21:01 +01:00
7a2cb28475
Make sure isize matches ssize_t on most cases
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-20 17:12:44 +01:00
e2a6cba3c6
Log: Update formatting to make ANSI weirdness more sensible
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-19 21:42:53 +01:00
703c3f44fb
Add two FIXMEs
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-19 21:41:27 +01:00
042f999677
Heap: SCRUB IT ALL
All checks were successful
continuous-integration/drone/push Build is passing
If your memory is all 0xacacacac there is a big probability you haven't initialized it.
2022-12-19 13:20:38 +01:00
a11a5dec1f
DoublyLinkedList -> LinkedList
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-19 12:43:23 +01:00
1269a045bd
LinkedList: Add a convenience delayed_for_each() method.
This is a special way of iterating over the list which permits removing items while iterating.
2022-12-19 12:41:25 +01:00
5b72144fac
Add a handy consume() method to LinkedList
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-19 12:35:08 +01:00
92a7004c2f
Move the reaping logic to Scheduler 2022-12-19 12:24:15 +01:00
31ee901e01
TarStream: Add a variant of read_contents() returning an OwnedStringView 2022-12-19 12:21:17 +01:00
9eb829f3a2
CString: Add strcmp() 2022-12-19 12:20:56 +01:00
60520dff4c
Make MemoryManager's scope guards more robust
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-19 11:55:53 +01:00
0bdbffe0ca
Spinlock+LockedValue: Add try_lock() methods
All checks were successful
continuous-integration/drone/push Build is passing
For when you want to lock a resource if possible but not get blocked if it is locked by another thread.
2022-12-18 20:37:26 +01:00
283e641ece
Spinlock+LockedValue: Remove init() functions
Let's set the default (unlocked) value of Spinlock's underlying atomic to 0, so even if the constructor is not called it stays like that.
2022-12-18 20:36:15 +01:00
a63146a798
Show the date and time of build :)
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 18:51:25 +01:00
751377de0a
Scheduler: Make it possible for a thread to stop existing
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 18:43:34 +01:00
1b92fe36b4
Store the stack inside a thread 2022-12-18 18:43:17 +01:00
00cf267ac7
Lock EFIXME and error_string() behind a #define
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 18:14:48 +01:00
a08310ff5e
Add some more errno definitions
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 18:09:52 +01:00
cda0d49a4e
Add todo()
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 17:15:42 +01:00
4a7e48ed5d
Make sure wchar_t is wide enough to hold all Unicode code-points
All checks were successful
continuous-integration/drone/push Build is passing
Too bad if it isn't.
2022-12-18 17:14:12 +01:00
6c3b7672a0
Kernel: Demo the initrd using TarStream
All checks were successful
continuous-integration/drone/push Build is passing
Yes, we're using the physical address. Not optimal, this is only for demo purposes.
2022-12-18 16:39:35 +01:00
1d6092341a
Add a generic TarStream class
As long as it's in memory, we can use it :)
2022-12-18 16:38:47 +01:00
eadca3d25b
Add nullcpy()
Invented function to memcpy() with a specific size, but add a null terminator.
2022-12-18 16:31:02 +01:00
0d65f188f0
Alignment.h: Include the Types 2022-12-18 16:30:27 +01:00
730d0682ee
Result: Add try_set_value_with_specific_error() 2022-12-18 16:30:09 +01:00
b01878cd3c
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 14:55:04 +01:00
ffd3385d0d
TextConsole: decoder -> utf8_decoder
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 14:42:53 +01:00
6389099808
UTF-8 part 2: Encoding wide-character strings into UTF-8
All checks were successful
continuous-integration/drone/push Build is passing
We now have Utf8StringEncoder and Utf8Encoder (no state this time)
2022-12-18 14:34:50 +01:00
9c1c6bb320
Add wcslen()
I think this can go in CString.h, no need to create a separate CWChar.h or something
2022-12-18 14:33:13 +01:00
36179155e1
Add UTF-8 support to TextConsole!!
All checks were successful
continuous-integration/drone/push Build is passing
Not much support, since the font only covers codepoints from U+0000 to U+00FF,
(Basic Latin & Latin Extended-A), but unprintable code-points are rendered as ONE box per code-point,
instead of multiple garbage characters.
So it's Unicode-aware, even if it can't print most characters.
2022-12-18 13:09:37 +01:00
75ba14a3ad
Add UTF-8 decoder support!! 2022-12-18 13:04:40 +01:00
23d405bbda
Add an unreachable() macro function that panics if reached 2022-12-18 12:40:28 +01:00
a89ae9bed7
Run include-what-you-use
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 15:51:19 +01:00
1b867151bd
MemoryManager: Run include-what-you-use
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 15:47:35 +01:00
95b0091622
Split off arch/x86_64/CPU.cpp into various files
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 15:45:06 +01:00
799a02c883
Remove unnecessary std:: prefix from inside std
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 15:33:47 +01:00
d5b9ff1569
Remove unused function definition
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 15:30:57 +01:00
e4b971f09c
Make LinkedList::prepend() also set the element as the last one if we have no elements
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 15:28:18 +01:00
f5de9c5589
LinkedList: Add a prepend() method
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 15:27:16 +01:00
c5220cbf64
LinkedList: Rename append_after to add_after 2022-12-17 15:27:00 +01:00
2bc6398d3e
TRY(): Call release_value() instead of expect_release_value()
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 15:15:27 +01:00
34c738116c
Result: Make some member functions const 2022-12-17 15:15:00 +01:00
90bd4a83c0
Result, Option: Move member initialization to constructors 2022-12-17 15:14:27 +01:00
ee6387e7b5
Refactor NumberParsing.cpp + a lot of comments 2022-12-17 15:00:19 +01:00
97cb57d521
Check for overflow/underflow in parse_signed_integer
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 14:42:56 +01:00
59c9d8f119
asm -> asm volatile
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 14:32:24 +01:00
acb0ab1cd7
Use TypeTraits in Alignment.h to make static assertions more readable
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 13:50:27 +01:00
ace674e518
LinkedList: Make sure the contained type inherits from DoublyLinkedListNode<T> 2022-12-17 13:49:47 +01:00
2cbc9fa385
Add some nice TypeTraits 2022-12-17 13:48:55 +01:00
f77126768f
Improve message 2022-12-17 13:48:22 +01:00
16954695dd
Tell the compiler that string_format is a printf-style function
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 12:45:26 +01:00
16e00bada0
Add comments to Format.h
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 12:43:29 +01:00
abbed13f27
Add a 'pure' variant of cstyle_format which is infallible
If we cannot fail to output, it doesn't make sense to propagate errors. So if you're SURE there are no errors, use pure_cstyle_format().
If, however, output can fail, use cstyle_format().

This has a drawback of adding quite a bit of code duplication to Format.cpp.
Some of it is dealt using templates, but some code still remains duplicate.
2022-12-17 12:38:22 +01:00
48fcb8734a
Give number parsing functions more meaningful names 2022-12-17 12:12:58 +01:00
cf3b2176f0
Implement OwnedStringView::from_string_literal
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 11:36:16 +01:00
df9a13cbfb
KernelVM: Make g_used_vm atomic and g_kernelvm_bitmap a LockedValue
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-17 10:56:24 +01:00
132963070b
MemoryManager: Make some variables atomic and the frame bitmap a LockedValue 2022-12-17 10:56:24 +01:00
f97515bd7e
Kernel: Add Spinlock and LockedValue<T> 2022-12-17 10:55:54 +01:00
6e5d2b5335
Thread: Make g_next_id atomic 2022-12-17 10:50:49 +01:00
14461c6fe8
Atomic: Add operators += and -= 2022-12-17 10:49:19 +01:00
9d6235e109
CPU: Add a pause() method 2022-12-17 10:45:55 +01:00
a16f357ab9
Add an Atomic class
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 21:15:22 +01:00
b316e3b3b7
Print stack trace on assertion fail
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 20:49:09 +01:00
da39ba33a9
Move OwnedStringView::operator[] out of line 2022-12-16 20:48:58 +01:00
59765aa334
Rename String.h -> CString.h
All checks were successful
continuous-integration/drone/push Build is passing
Let's not confuse String.h with a managed string class, it's in fact the equivalent of the C stdlib's <string.h>
2022-12-16 20:40:04 +01:00
42a2c2af49
Add strdup() 2022-12-16 20:37:57 +01:00
e56075fb46
Use nothrow in raw_malloc 2022-12-16 20:36:43 +01:00
345e13965e
Add missing include
All checks were successful
continuous-integration/drone/push Build is passing
No one was noticing because everyone using OwnedStringView included Result.h before it
2022-12-16 20:27:44 +01:00
4a6c59d519
Make all methods in OwnedStringView const
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 19:48:22 +01:00
2e24e09146
Convert MemoryMapIterator to Option
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 19:47:20 +01:00
a32590ff8a
Call expect_value more 2022-12-16 19:44:33 +01:00
cedcfa9c63
Improve cleanup on MemoryManager failure + add methods that use KernelVM
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 19:36:38 +01:00
814672c771
Remove some redundant error propagation
All checks were successful
continuous-integration/drone/push Build is passing
Why can printing to the serial port or format onto a string fail?
Even if cstyle_format returns Result<usize>, we shouldn't always follow suit.
2022-12-16 18:32:29 +01:00
41b3c8adb2
Convert to_dynamic_unit to OwnedStringView and rename the old variant to to_dynamic_unit_cstr
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-16 18:18:24 +01:00
be22cf6267
Introduce OwnedStringView
A managed String which uses RAII to free its contents. It's not a proper string though, since it's read-only.
So it's a StringView... but an owned one.

Can't be copied automatically, must be either moved or copied manually by calling clone() on it.
2022-12-16 18:17:15 +01:00
d759058b80
Introduce std::nothrow
Let's make sure we explicitly tell new that we don't want exceptions
2022-12-16 18:14:48 +01:00
32c8869973
Option: Simplify release_value
This avoids copying + we don't need to destroy the item if we move it, since it either gets emptied by moving it or doesn't have anything to destroy.
2022-12-16 18:13:40 +01:00
19a4e2ab58
Result, Option: Make sure everything is properly moved 2022-12-16 18:11:17 +01:00
e729c38200 Merge pull request 'Add an Option type and get rid of ENONE' (#19) from optionals-and-empty-errors into restart
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #19
2022-12-08 15:13:24 +00:00
b9f3d3c349
Remove ENONE
All checks were successful
continuous-integration/drone/pr Build is passing
If you want to return an error without meaning, use Option.
2022-12-08 16:09:33 +01:00
da104c87cb
Heap: Return Option in split() 2022-12-08 16:09:12 +01:00
b6173e2b67
LinkedList: Return Option instead of ENONE if no value 2022-12-08 16:09:04 +01:00
406af68a54
Result: Use Option as backend 2022-12-08 16:08:18 +01:00
b58eba63f1
Add a new Option class which behaves like Result, but has no error number, just a value or no value 2022-12-08 16:08:02 +01:00
6cee208e62
Kernel: Enable -Wsign-conversion
All checks were successful
continuous-integration/drone/push Build is passing
For real this time, turns out me, being dumb, added it to Luna instead of the kernel.
2022-12-08 15:09:32 +01:00
779fda307a
More scope guards!!
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-08 15:01:04 +01:00
1d5d1daa57
Add scope guards 2022-12-08 14:56:11 +01:00
6de7753b4c
Add malloc wrappers
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-07 18:17:49 +01:00
c8302a4fef
Add convenience functions to print the stack trace directly
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-07 18:11:24 +01:00
0d437cfcca
Add support for stack traces
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-07 17:39:59 +01:00
416e96c4d5 Merge pull request 'Add a basic scheduler with threads' (#18) from threads into restart
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #18
2022-12-07 16:11:59 +00:00
d93d95f23c Add sleeping mechanism 2022-12-07 16:11:59 +00:00
757cee4693 Add accessors for when you're sure a linked list is not empty 2022-12-07 16:11:59 +00:00
70497c37fb Check for runnable threads 2022-12-07 16:11:59 +00:00
57517252d8 Add a state to Thread 2022-12-07 16:11:59 +00:00
f169718a4b Initialize and demo the scheduler 2022-12-07 16:11:59 +00:00
c907e16311 x86_64: Invoke the scheduler every millisecond 2022-12-07 16:11:59 +00:00
13f5d09cfd Add a Scheduler!! 2022-12-07 16:11:59 +00:00
12aa014a3d Add a Thread class which can be part of a DoublyLinkedList 2022-12-07 16:11:59 +00:00
fbd290c01b KernelVM: clean up a bit 2022-12-07 16:11:59 +00:00
8da5521273 Add a Stack convenience class 2022-12-07 16:11:59 +00:00
0bbd026660 CPU.h: pragma once 2022-12-07 16:11:59 +00:00
5d988c088f Make idle_loop noreturn 2022-12-07 16:11:59 +00:00
f65ed465c4 Bitmap: Fix crash by attempting to memset -1 bits (UINT64_MAX) 2022-12-07 16:11:59 +00:00
d3458f2f0f Bitmap: short circuit on 0-byte clears 2022-12-07 16:11:59 +00:00
4fdd1d57f5 Make build-debug.sh also add debug symbols to luna 2022-12-07 16:11:59 +00:00
c657b302c9 Timer: add raw_ticks 2022-12-07 16:11:59 +00:00
fd6a74e61c CPU: Add an idle_loop method 2022-12-07 16:11:59 +00:00
287c4ab060 Run clang-format 2022-12-07 16:11:59 +00:00
bbfaa4645a Add a should_invoke_scheduler method 2022-12-07 16:11:59 +00:00
986aa01948
size_t -> usize
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-07 17:06:29 +01:00
beab3454b5
kernel: Enable -Wsign-conversion and -Wcast-align
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-07 11:47:46 +01:00
1badc40a4a
Run include-what-you-use everywhere 2022-12-07 11:40:02 +01:00
c2927de191
Remove unused includes
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-07 11:22:34 +01:00
a3b69a0cfa
Update README.md
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-07 11:13:16 +01:00
ee276a3a35
Add the nodiscard attribute to make and make_array
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-07 11:01:45 +01:00
dad95a8160
Map the page bitmap to virtual memory 2022-12-07 10:58:59 +01:00
1ebd892c16
Convert uses of u64 to usize
Not all of them, but if you're measuring a size it's more appropriate to use usize than u64.
2022-12-07 10:55:47 +01:00
8598b1e8fc
Replace the _noreturn macro with the C++ native attribute [[noreturn]]
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 19:40:35 +01:00
c099877c35
Remove unnecessary error propagation in Log.cpp
All checks were successful
continuous-integration/drone/push Build is passing
Serial and TextConsole always succeed, no need to act as if they could fail
2022-12-06 19:35:34 +01:00
314acbfe21
Change the serial log to display only milliseconds
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 19:31:41 +01:00
39b310b6b9
Make alignment a template parameter to help the compiler optimize
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 19:27:58 +01:00
d48eb85d1d
Heap: Avoid magic numbers
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 19:05:00 +01:00
b5c6ae253d
Make LinkedList a lot better
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 18:41:35 +01:00
09e447d9d2
Heap: Use LinkedList instead of doing things manually 2022-12-06 18:28:04 +01:00
d8f75f1d3c
LinkedList: Add an append_after() method
Can be used to append an item after another one instead of at the end of the list.
With doubly linked lists, this is extremely easy to achieve (O(1)).
2022-12-06 18:25:08 +01:00
146da13e43
LinkedList: Make sure to explicitly mark the first node's next and last nodes as nullptr 2022-12-06 18:23:19 +01:00
07e6ebd3cc
LinkedList: Fix nonnull_or_error 2022-12-06 18:22:45 +01:00
2734353a5d
Heap: Just align it on a 16-byte boundary if it's not aligned 2022-12-06 18:21:19 +01:00
cccf89dd16
Heap: Remove outdated FIXME 2022-12-06 18:20:18 +01:00
87fb195202
Add DoublyLinkedList data structure
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 17:37:43 +01:00
dd29156c85
Alloc: make() now takes variadic arguments, to forward to the constructor 2022-12-06 17:36:20 +01:00
eef74e2897
Add a generic error code (ENONE) 2022-12-06 17:35:38 +01:00
a021e7a309
Move make and destroy to luna
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 16:41:22 +01:00
1fa99f4f64
Make {add,sub,mul}_will_overflow more compiler-independent
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 15:53:06 +01:00
26b44e651d
Change safe_{sub,add,mul} so they perform the operation only once
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-06 15:47:59 +01:00
b338126854
Heap: Use safe_mul in kcalloc() 2022-12-06 15:44:21 +01:00
e91c04b1d1
luna: Introduce safe arithmetic operations, which return an error if an operation would overflow 2022-12-06 15:40:18 +01:00
8ff9cb4b96
x86_64: Add a friendlier handler for page faults
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-05 21:02:21 +01:00
1d0dd8fa93
Use KernelVM in kmalloc() and friends
Much better now!!
2022-12-05 21:02:05 +01:00
ba758bcef8
Initialize the KernelVM 2022-12-05 21:01:18 +01:00
6c3024d4ee
Heap: Count the heap blocks' size in the size required for an allocation 2022-12-05 21:01:06 +01:00
0edabd6d87
Heap: Add a new block to the end of the linked list
*facepalm*

This was causing page faults when having two blocks and the first one (oldest one) being freed first.
2022-12-05 21:00:21 +01:00
d445b29477
Add a virtual memory allocator for the kernel 2022-12-05 20:36:24 +01:00
a8fb4ca739
Move CI badge 2022-12-05 19:57:41 +01:00
eaf8a8aafe
Make sure the OS used in CI is Linux
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-05 19:26:27 +01:00
bf7bcd7d56
Rename CI pipeline
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-05 19:19:50 +01:00
20eeecb3e1
Run CI on push
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-05 19:16:58 +01:00
4ec6442ba0
Add build status badge 2022-12-05 19:16:11 +01:00
2677fca5b7
Remove formatting step 2022-12-05 19:09:33 +01:00
f767d98037
Please work 2022-12-05 19:07:01 +01:00
adf6844d49
Update drone.yml 2022-12-05 19:03:06 +01:00
999d90d588
Update check-formatting.sh 2022-12-05 19:02:23 +01:00
62e4ed824d
Update drone.yml 2022-12-05 18:50:01 +01:00
ac2da14319
Update config for CI 2022-12-05 18:48:40 +01:00
bd7b9ad237
Update drone.yml 2022-12-05 18:44:44 +01:00
ca0e47b8e4
Update drone.yml 2022-12-05 18:26:31 +01:00
744d39c27b
Update drone.yml 2022-12-05 18:24:34 +01:00
0c9b822304
Update drone.yml 2022-12-05 18:22:52 +01:00
f21d153077
Update drone.yml 2022-12-05 18:21:30 +01:00
82eda5d6aa
Update drone.yml 2022-12-05 18:19:55 +01:00
d8a3d74779
Actual steps 2022-12-05 18:13:12 +01:00
08b4c078dd
Will it work now? 2022-12-05 18:11:22 +01:00
8f3e80ae47
Try to get it right? 2022-12-05 18:08:50 +01:00
4074835185
Update drone.yml 2022-12-05 18:06:30 +01:00
e6c56172d3
Try adding a drone.yml 2022-12-05 18:00:05 +01:00
95d969ed25
Add message to inform of prebuilt toolchains 2022-12-05 17:48:26 +01:00
762131a425
Make more constexpr 2022-12-05 16:43:52 +01:00
2eaa458555
Remove release_value call 2022-12-05 16:41:39 +01:00
1e3706ac01
Make ARCH_PAGE_SIZE and ARCH_TIMER_FREQ known at compile-time 2022-12-05 16:36:41 +01:00
4f183958e3
General constness + [[gnu::packed]] everywhere 2022-12-05 16:13:38 +01:00
a63a8b32b5
Make new and delete noexcept and return nullptr on failure 2022-12-05 13:45:32 +01:00
891320f7d3
Heap: Make const 2022-12-05 13:41:58 +01:00
7cc139c3f7
Make expect and check use unlikely 2022-12-05 13:35:33 +01:00
ea7893ba71
Make CHECK_PAGE_ALIGNED use expect() instead of check() 2022-12-05 13:28:36 +01:00
55a30ac487
Make CHECK_PAGE_ALIGNED use expect() instead of check() 2022-12-05 13:26:50 +01:00
bfd4647467
Rename largest_free -> largest_free_entry 2022-12-05 13:26:09 +01:00
d9fc50f1ea
Make MemoryMapEntry have private fields with public getters 2022-12-05 13:23:01 +01:00
ec1354fc8d
const in TextConsole 2022-12-05 13:06:12 +01:00
58ecf11424
Make all refs to the bootboot structure const 2022-12-05 13:04:01 +01:00
54ce511f1d
More const 2022-12-05 13:00:41 +01:00
792642dd6f
MORE CONST 2022-12-05 12:58:59 +01:00
86a12f301e
Make value_byte a helper 2022-12-05 12:53:16 +01:00
004e13a5f3
Make bitmap methods const if not modifying the bitmap 2022-12-05 12:50:30 +01:00
3b77ba6b04
EVERYTHING IS CONSTANT IN THIS UNIVERSE
Here's one advantage of Rust over C++:
Immutability by default. In Rust, you have to mark a variable as mutable, whereas in C++ you have to mark it as immutable.

What's the problem here? Usually, most variables don't need mutability. Thus we end up with const all over the place.
2022-12-05 12:49:01 +01:00
af96db3641
Remove bootboot declaration from MemoryManager now that it's MemoryMapIterator's job to walk the mmap 2022-12-04 15:56:25 +01:00
77e64d74a0
Remove unused header 2022-12-04 15:55:52 +01:00
0a296413e6
It's not worth it aborting when failing to determine CPU name 2022-12-04 15:55:12 +01:00
766804b3a0
Use get_blocks_from_size instead of +1 2022-12-04 15:52:56 +01:00
0d10c98477
SImplify init_physical_frame_allocator() even more 2022-12-04 15:50:21 +01:00
5f6c48bd12
Use a friendlier way of iterating over the memory map 2022-12-04 15:45:13 +01:00
5aa2d1fa18
Add a Bitmap class to provide common functionality and use that in the MemoryManager 2022-12-04 15:14:07 +01:00
ee76bdf84d
Add sanity check 2022-12-04 13:41:14 +01:00
bde3d55eb2
Remove escape from comment 2022-12-04 13:38:48 +01:00
f8120e01c0
Panic in delete as well 2022-12-04 12:58:37 +01:00
22019ac6b2
Print the error instead 2022-12-04 12:57:43 +01:00
96b32f5a93
Please use make<T> and destroy<T> instead of new and delete
Those are there only for common stuff (in the Luna library) that needs an environment-agnostic way of allocating memory.
new and delete are standard, thus we should use those.
2022-12-04 12:55:32 +01:00
adb2c2ab41
Add kernel-side new and delete 2022-12-04 12:52:49 +01:00
b8239698db
Add descriptions in CMakeLists 2022-12-04 12:47:08 +01:00
c7ab6bc2d3
Reorganize the luna/ directory so that headers aren't in the top level include path 2022-12-04 12:42:43 +01:00
cdbed6970a
Result: Add expect_ variants of value() and release_value() 2022-12-04 12:32:34 +01:00
bed29e71af
Replace some uses of check() with expect() 2022-12-04 12:25:16 +01:00
bb92480aa3
Add a variant of check() that accepts an error message 2022-12-04 12:19:17 +01:00
a0c4bbe6f3 Make sure to clean CMake cache when rebuilding 2022-12-04 11:55:47 +01:00
5d9c50eb12 Make build-debug.sh work 2022-12-04 10:27:25 +01:00
9a6d0d1bae Update README.md 2022-12-04 10:07:56 +01:00
37a41f3d2c Add warning message 2022-12-03 17:53:47 +01:00
d72478de29 Update README.md 2022-12-03 17:51:39 +01:00
1f4c4f1a0c Update README.md 2022-12-03 17:49:42 +01:00
bbc5470ae4 Update symlink location 2022-12-03 17:39:22 +01:00
e440df58c9 cleanup: remove unused scripts 2022-12-03 17:37:12 +01:00
505dde35ac Make GDB source .gdbconf relative to the root directory 2022-12-03 17:34:36 +01:00
dcd5a82073 Make GDB use the correct kernel file 2022-12-03 17:34:14 +01:00
1d7b9260c3 Add config.h for version information 2022-12-03 17:25:25 +01:00
bdc9747f9e Set a project version 2022-12-03 17:18:25 +01:00
3740309427 Check for STRINGIZE_VALUE_OF before defining it 2022-12-03 17:18:16 +01:00
9c9cb6a05a oopsie 2022-11-30 17:29:18 +01:00
2bc99f2e6e Make log __attribute__(format), so the compiler can warn us of bad format strings 2022-11-30 17:28:46 +01:00
3f40ccd703 Indicate the log level in the serial console 2022-11-30 17:26:33 +01:00
985d45ddfb Switch to logging functions everywhere 2022-11-30 17:16:36 +01:00
d2856d8812 Provide meaningful error numbers 2022-11-30 17:13:59 +01:00
29dad5651d Move __check_failed to Log.cpp so it can be logged across all backends 2022-11-30 17:12:06 +01:00
1d51935d43 Make Result able to return an error string 2022-11-30 17:10:43 +01:00
fc0779a2f9 Add a SystemError module for errno values :) 2022-11-30 17:10:30 +01:00
fe47e0d5cb Clean init() up 2022-11-30 16:30:42 +01:00
f8ed74fda5 Improve unit representation code 2022-11-30 14:41:35 +01:00
9f5fb547f7 Add logging system :) 2022-11-30 13:29:28 +01:00
f1756e6f58 Add unit formatting 2022-11-30 12:42:11 +01:00
552186ad51 Add string_format and vstring_format 2022-11-30 12:36:21 +01:00
1ed51d11cb Do not push unused values 2022-11-23 19:37:25 +01:00
82893fa3a4 Introduce a kernel_yield function to use once a scheduler is implemented 2022-11-23 19:34:04 +01:00
88681bdc74 Default to ninja 2022-11-23 19:01:28 +01:00
7230eceb4d x86_64/Timer: Show explanatory message on static assertion fail 2022-11-23 18:58:39 +01:00
9934719f6b Use a more reliable signed 64-bit type than "long" 2022-11-23 18:05:01 +01:00
88f588a0c5 Make ARCH_TIMER_FREQ less frequent so it is more accurate (I hope) 2022-11-23 18:00:09 +01:00
3b2dc5db55 PlacementNew.h: Use Types.h 2022-11-23 17:22:16 +01:00
46cad14052 Print "All files OK" when all files are using correct types 2022-11-20 18:57:22 +01:00
f982152caa Add a script to manually check files with stdint.h types 2022-11-20 18:54:39 +01:00
2df0bc4238 Convert one tiny type to Types.h in Format.cpp 2022-11-20 18:31:55 +01:00
43e26e583c Calculate the boot timestamp in UNIX time for further usage 2022-11-20 18:30:40 +01:00
459e1ed653 luna/String.h: Convert to Types.h 2022-11-20 18:29:23 +01:00
1f2901d41a Add convenience script to replace stdint.h types with Types.h types 2022-11-20 18:28:46 +01:00
285c3cc411 Add Luna sources to list of sources to be formatted 2022-11-20 18:28:16 +01:00
ff952fa2e4 Confirm alignment when calculating an offset to split at 2022-11-20 18:04:29 +01:00
35b7194fb7 Move initialization into an init() function returning Result<void> so we can use TRY
And remove a lot of testing code as well.
2022-11-20 17:56:07 +01:00
a58b60d0cf Add a framebuffer text renderer 2022-11-20 17:55:22 +01:00
29defdf54d Add a debug function to dump heap usage 2022-11-20 16:33:54 +01:00
d54c882c63 Add new/delete-like functions but with Results 2022-11-20 15:48:08 +01:00
caf6d1563c Kernel: Add a heap memory allocator
This is the first time I've actually dropped liballoc in favor of writing my own implementation.
Usually, malloc() and such looked so complicated that I preferred to let a nice external library do the job.
But I've decided to try writing my own allocator, and now we have heap memory without any 3rd party code!
2022-11-20 15:15:26 +01:00
3815f9aa9f Introduce an offset_ptr function to avoid quirky C pointer arithmetic 2022-11-20 15:12:18 +01:00
cb88630d86 Bugfix: Make alloc_at return the start of the virtual memory range instead of the end 2022-11-20 15:11:53 +01:00
33876dcda4 Use _strto{i,u} in _atou and _atos 2022-11-20 09:28:17 +01:00
bde5de68ca Simplify is_valid_digit_for_base by reaching out to parse_digit_unchecked 2022-11-20 09:24:21 +01:00
44f44aedca Make _strtoi call _strtou, to deduplicate code 2022-11-19 22:52:08 +01:00
30a7d760ae Move a few repeated lambdas into their own functions 2022-11-19 22:48:20 +01:00
af267772f0 Rename MemoryManager::map to map_frames_at
To make it clearer that this API is only intented for mapping contiguous frames of physical memory (for MMIO perhaps?)
2022-11-19 22:32:48 +01:00
1b41a3e9cf Introduce a few helpers to allocate/map/unmap several pages, which wrap around the MMU functionality 2022-11-19 22:28:45 +01:00
c886669d56 Break down operations to make protect_kernel_sections() more readable 2022-11-19 22:27:59 +01:00
d96cb73995 Rename physical "pages" to "frames"
AFAIK, this is the proper naming scheme. "Pages" are virtual, and "frames" physical.
2022-11-19 22:27:08 +01:00
847f2b4f4c Replace more usage of stdint.h types with Luna's Types.h 2022-11-19 22:25:03 +01:00
83bcac7a16 Kernel: Introduce a timer interface 2022-11-19 20:01:01 +01:00
047f445651 Kernel: Add helpers to validate memory addresses 2022-11-19 18:38:47 +01:00
424b069d55 Kernel: Start the call stack with a null RBP on x86_64 2022-11-19 18:38:32 +01:00
db3e34b2ba Result: Add try_set_value()
This helper returns true if the Result contains a value, or false if it doesn't.
Additionally, if it has a value, it sets the passed reference to it.
2022-11-19 18:38:01 +01:00
883a1da0d7 More indentation in CMakeLists.txt 2022-11-19 18:00:45 +01:00
70c6b78e35 Organize source tree 2022-11-19 17:59:49 +01:00
a44e2f41fe Cleanup kernel/CMakeLists.txt 2022-11-19 17:59:39 +01:00
102eabcb4b Do some more formatted logging 2022-11-19 17:52:24 +01:00
83e6bd1322 Make the build system more platform-agnostic 2022-11-19 17:46:53 +01:00
8cae20a82c Move __check_failed out of line so anyone can implement it 2022-11-19 17:20:10 +01:00
2b9bdf560e Move include to .cpp file 2022-11-19 17:19:25 +01:00
b8c136eeb4 Make a common header for attribute shorthands 2022-11-19 17:18:51 +01:00
648bd3fb61 Switch format.h to use Result 2022-11-19 16:13:25 +01:00
31673c0ac9 Introduce format attribute 2022-11-19 15:53:58 +01:00
3cdf224b90 Remove useless files now that functions are out of line 2022-11-19 15:46:46 +01:00
dadc3e570b Move a few functions out of line 2022-11-19 15:43:09 +01:00
56c2ca3381 Add _strtoi and _strtou 2022-11-19 15:27:55 +01:00
bad856afe0 Add %p and %% to cstyle_format 2022-11-19 15:26:29 +01:00
88af7a915b Start padding and alternate forms for integers 2022-11-19 13:59:06 +01:00
c48203997a Move output_integer into a function that accepts value arguments 2022-11-19 13:21:21 +01:00
4ebf244d3b Support printing some integers in output_integer 2022-11-19 13:15:13 +01:00
603ff46d8c Add a format implementation 2022-11-19 12:30:36 +01:00
be2e915d0d Use the standard names for ctype functions if inside moon or _LUNA_OVERRIDE_STDC is defined 2022-11-18 21:17:26 +01:00
1b3243a80c Add ctype.h functions to the Luna library 2022-11-18 21:12:54 +01:00
762ca844d8 Add CPU::platform_string 2022-11-18 21:04:53 +01:00
109de54822 Provide stubbed handlers for many more x86 exceptions
I am now officially a big-boy OS developer, I read the Intel manuals for this!! (Not that the OSDev wiki doesn't have the information, but it was missing descriptions for some more obscure exceptions)
2022-11-18 20:51:25 +01:00
860f13cd7e Rename align_base to alignment 2022-11-18 18:02:38 +01:00
2e2656a02f Add static assertions to constexpr functions 2022-11-18 17:59:19 +01:00
9d318d50aa Use TRY in MMU.cpp 2022-11-16 20:37:41 +01:00
2c9329928c Replace page_size (function) with ARCH_PAGE_SIZE (constant) 2022-11-16 20:37:32 +01:00
30ac95bcf8 Use usize/isize instead of (s)size_t
Since we're using Rust-style integer types already, why not go all in?
2022-11-16 20:30:34 +01:00
7fc5a6b753 Make kernel rodata and data not executable 2022-11-16 20:02:04 +01:00
7f15ba0ac5 Add some interrupt handling 2022-11-16 17:37:18 +01:00
df8666fd73 Remove unneeded label 2022-11-15 20:47:50 +01:00
bb46cd890b Add GDT and IDT setup and loading + NX if supported 2022-11-15 20:41:59 +01:00
c9feb11366 Introduce a check() method (like assert() but always on) 2022-11-15 19:36:50 +01:00
c319336e3d Add a CPU interface 2022-11-15 19:10:32 +01:00
e16324887f MMU: Properly clear flags 2022-11-15 19:10:19 +01:00
3358454833 Add getters for free, used and reserved memory 2022-11-13 16:56:03 +01:00
6a7097c9ec Add variables for the future 2022-11-13 16:54:07 +01:00
ae235e5538 MMU: unmap and remap for x86_64 2022-11-13 16:51:21 +01:00
ba1bf72e1b Remove unused include 2022-11-13 16:32:28 +01:00
d6c56fb512 Mapping finally works!! 2022-11-13 16:31:32 +01:00
4c4f72b865 More MMU stuff, but writing still fails 2022-11-13 15:33:53 +01:00
d148e0aff7 Initialize MemoryManager instead of MMU directly 2022-11-13 14:29:59 +01:00
705c2747de Add memory manager 2022-11-13 14:29:15 +01:00
6b95307b54 Add init 2022-11-13 12:20:53 +01:00
ffbe5260a5 Add Framebuffer stuff 2022-11-13 11:25:15 +01:00
82c2381ac9 Serial printing!! 2022-11-13 10:30:10 +01:00
cf758fdfdc Initial commit :) 2022-11-13 10:09:09 +01:00
42efc21110 Start implementing read and write support in tmpfs
write seems to work fine, read just hangs there, waiting.
2022-11-12 20:11:26 +01:00
046065c533 Fix tmpfs 2022-11-12 19:05:47 +01:00
37fe95b128 Remove FIXME 2022-11-12 18:15:32 +01:00
3451d50a37 Try building a tmpfs, but weird stuff happens 2022-11-12 18:13:41 +01:00
000ffd1fae Scheduler: Handle weird cases when the task we're iterating on is null 2022-11-12 18:12:42 +01:00
37bb3273ce Kernel: Add a C interface to the logging system 2022-11-12 18:12:18 +01:00
511bb7a8c1 Kernel: Make readdir() available in created InitRD directories 2022-11-12 18:11:58 +01:00
bde9a97db5 sh: Add a sleep command 2022-11-12 17:44:13 +01:00
fa325072ac Kernel: Add __cxa_atexit and __cxa_finalize 2022-11-12 17:43:57 +01:00
e54f033578 libc: Add wcslen (with a test) and wcscat 2022-11-12 14:16:00 +01:00
35829a6998 libc: Remove unnecessary casts in strcat() and strncat() 2022-11-12 14:15:38 +01:00
6ab246a05e libc: Add a basic implementation of pathconf() 2022-11-12 14:15:21 +01:00
9e8a57cec7 libc: Add getdtablesize()
No system call for this, since the limit is fixed right now
2022-11-12 14:15:02 +01:00
f46831f459 libc: Define PATH_MAX
This restriction is actually not enforced by the kernel. It should be.
2022-11-12 14:13:28 +01:00
5fa8569ff9 libc: Add creat() 2022-11-12 14:12:49 +01:00
a3896c2546 libc: Define MB_CUR_MAX 2022-11-12 13:24:04 +01:00
3f867b936e libc: Implement stpcpy
This function is unsafe so it is marked as deprecated, but if programs need it they can use it.
2022-11-12 13:20:28 +01:00
16e6fba2d0 Add a bit more C++ stuff to the C++ app 2022-11-12 13:12:51 +01:00
de2451e553 Kernel: Change up the logging in the kernel's PRNG 2022-11-12 12:56:13 +01:00
11ee01f269 Kernel: Remove "checkpoint logging" in main.cpp 2022-11-12 12:55:47 +01:00
bf1d3d3f05 mkdir: Print newline after usage 2022-11-12 12:53:33 +01:00
5c51b82f6a Kernel: Remove obtain_user_ref and add copy_typed_to and from_user 2022-11-12 12:08:26 +01:00
58fb422161 Kernel: Return a Result in MemoryManager and strdup_from_user 2022-11-12 11:56:40 +01:00
662afad426 Kernel: Add a Result class 2022-11-12 11:30:28 +01:00
a3465c2f5e tools: Make buildstep exit on error 2022-11-12 11:30:17 +01:00
559d074ce4 Kernel: Make a more convenient wrapper for basename() and dirname() 2022-11-12 10:39:25 +01:00
5a1d15d2b5 Show only short names of apps when installing 2022-11-10 17:55:41 +01:00
4aa3bd3107 Next version! 2022-11-09 17:25:05 +01:00
902 changed files with 50334 additions and 19832 deletions

View File

@ -9,4 +9,6 @@ AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Always AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: 'true' AllowShortLoopsOnASingleLine: 'true'
PointerAlignment: Left PointerAlignment: Left
Cpp11BracedListStyle: 'false'
SpaceBeforeCpp11BracedList: 'true'

View File

@ -1,4 +1,4 @@
file kernel/bin/moon.elf file kernel/moon
break _start break _start
target remote :1234 target remote :1234
continue continue

View File

@ -0,0 +1,23 @@
name: Build and test
run-name: ${{ gitea.actor }} is testing and running the code
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v3
- name: Download dependencies
run: |
apt update
apt install -y cmake ninja-build nasm genext2fs qemu-system build-essential wget git clang-format
- name: Set up the toolchain
run: |
wget https://pub.cloudapio.eu/luna/toolchains/ci-toolchain-arm64.tar.gz --quiet
tar xf ci-toolchain-arm64.tar.gz
rm ci-toolchain-arm64.tar.gz
- name: Check formatting
run: tools/check-formatting.sh
- name: Build and run tests
run: tools/run-tests.sh

26
.gitignore vendored
View File

@ -1,15 +1,19 @@
Luna.iso Luna.iso
toolchain/ toolchain/
.vscode/ build/
**/*.o
initrd/boot/moon initrd/boot/moon
kernel/bin/moon initrd/ksyms
initrd/sys/moon.sym env-local.sh
initrd/bin/** initrd/bin/**
apps/bin/** base/usr/*
tests/**/bin/** !base/usr/share
base/usr/** base/usr/share/*
**/*.a !base/usr/share/fonts
ports/**/workdir/** !base/usr/share/icons
ports/ports.list !base/usr/share/applications
**/*.pkg.tar.xz base/etc/skel/LICENSE
.fakeroot
kernel/config.cmake
ports/out/
ports/temp/
ports/dev/

19
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
"configurations": [
{
"name": "Luna",
"compilerPath": "${workspaceFolder}/toolchain/x86_64-luna/bin/x86_64-luna-gcc",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "gcc-x64",
"configurationProvider": "ms-vscode.cmake-tools",
"includePath": [
"${default}",
"${workspaceFolder}/base/usr/include",
"${workspaceFolder}/libc/include",
"${workspaceFolder}/libluna/include"
]
}
],
"version": 4
}

28
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,28 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "xaver.clang-format",
"files.exclude": {
"toolchain/build/**": true,
"toolchain/tarballs/**": true,
},
"search.exclude": {
"toolchain/build/**": true,
"toolchain/tarballs/**": true,
},
"editor.tabSize": 4,
"files.trimFinalNewlines": true,
"files.insertFinalNewline": true,
"git.inputValidationLength": 72,
"git.inputValidationSubjectLength": 72,
"doxdocgen.file.fileOrder": [
"file",
"author",
"brief",
"empty",
"copyright",
"empty"
],
"doxdocgen.file.copyrightTag": [
"@copyright Copyright (c) {year}, the Luna authors."
]
}

54
CMakeLists.txt Normal file
View File

@ -0,0 +1,54 @@
cmake_minimum_required(VERSION 3.8..3.22)
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
set(CMAKE_CROSSCOMPILING true)
project(Luna LANGUAGES C CXX ASM ASM_NASM VERSION 0.7.0)
set(LUNA_RELEASE_NAME "Pulsar")
set(LUNA_ROOT ${CMAKE_CURRENT_LIST_DIR})
set(LUNA_BASE ${CMAKE_CURRENT_LIST_DIR}/base)
set(LUNA_ARCH $ENV{LUNA_ARCH})
if(NOT DEFINED LUNA_ARCH)
set(LUNA_ARCH "x86_64")
endif()
set(CMAKE_C_COMPILER ${LUNA_ARCH}-luna-gcc)
set(CMAKE_CXX_COMPILER ${LUNA_ARCH}-luna-g++)
set(CMAKE_ASM_COMPILER ${LUNA_ARCH}-luna-gcc)
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
set(CMAKE_ASM_NASM_LINK_EXECUTABLE "${LUNA_ARCH}-luna-ld <FLAGS> <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_FIND_ROOT_PATH ${LUNA_ROOT}/toolchain/${LUNA_ARCH}-luna)
message(STATUS "Configuring Luna for ${LUNA_ARCH}")
set(COMMON_FLAGS -Wall -Wextra -Werror -Wvla
-Wdisabled-optimization -Wformat=2 -Winit-self
-Wmissing-include-dirs -Wswitch-default -Wcast-qual
-Wundef -Wcast-align -Wwrite-strings -Wlogical-op
-Wredundant-decls -Wshadow -Wconversion -Wbidi-chars=any
-fno-asynchronous-unwind-tables -fno-omit-frame-pointer
-std=c++20 -fno-rtti -fno-exceptions)
if(LUNA_NO_OPTIMIZATIONS)
set(COMMON_FLAGS ${COMMON_FLAGS} -ggdb)
else()
set(COMMON_FLAGS ${COMMON_FLAGS} -Os)
endif()
add_subdirectory(libluna)
add_subdirectory(libos)
add_subdirectory(gui)
add_subdirectory(libc)
add_subdirectory(kernel)
add_subdirectory(utils)
add_subdirectory(tests)
add_subdirectory(shell)
add_subdirectory(system)

View File

@ -1,6 +1,6 @@
BSD 2-Clause License BSD 2-Clause License
Copyright (c) 2022, apio. Copyright (c) 2022-2025, apio.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -22,4 +22,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 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 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. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,26 +0,0 @@
CC := x86_64-luna-gcc
CXX := x86_64-luna-g++
ASM := nasm
AR := x86_64-luna-ar
LD := x86_64-luna-ld
build:
+@tools/sync-libc.sh
+@tools/buildstep.sh kernel build
+@tools/buildstep.sh libs build
+@tools/buildstep.sh apps build
clean: initrd-clean
+@tools/buildstep.sh kernel clean
+@tools/buildstep.sh libs clean
+@tools/buildstep.sh apps clean
initrd-clean:
rm -f $(LUNA_ROOT)/initrd/boot/moon $(LUNA_ROOT)/Luna.iso
rm -rf $(LUNA_ROOT)/initrd/bin
install:
+@tools/buildstep.sh kernel install
+@tools/buildstep.sh libs install
+@tools/buildstep.sh apps install
+@tools/install-built-ports.sh

105
README.md
View File

@ -1,99 +1,56 @@
# Luna # Luna
A simple kernel and userspace for the x86_64 platform, written mostly in C++ and C. A simple POSIX-based operating system for 64-bit computers, written in C++.
## Another UNIX clone?
[Yes, another UNIX clone](https://wiki.osdev.org/User:Sortie/Yes_Another_Unix_Clone).
## Features ## Features
- x86_64-compatible [kernel](kernel/). - Lightweight 64-bit [kernel](kernel/). Compatible with the x86_64 architecture.
- Keeps track of which [memory](kernel/src/memory/) is used and which memory is free, and can allocate memory for itself and [user programs](kernel/src/sys/mem.cpp). - Basic threads/processes, using a simple round-robin [scheduler](kernel/src/thread/).
- Can read, write and execute files from a [virtual file system](kernel/src/fs/) supporting an initial ramdisk, device pseudo-filesystems... but no hard disks yet. - Read-only [ext2](kernel/src/fs/ext2/) filesystem.
- Preemptive multitasking, with a round-robin [scheduler](kernel/src/thread/) that can switch between tasks. - Can [load ELF executables](kernel/src/binfmt/ELF.cpp), [shebang scripts](kernel/src/binfmt/Script.cpp) or [arbitrary binary formats](kernel/src/binfmt/BinaryFormat.h) (registered through kernel modules, which are not supported yet =D).
- Can [load ELF programs](kernel/src/sys/elf/) from the file system as userspace tasks. - [C Library](libc/), aiming for POSIX compatibility, with many features such as local domain sockets, signals, and shared memory.
- [System call](kernel/src/sys/) interface and [C Library](libs/libc/), aiming to be mostly POSIX-compatible. - Support for [several third-party programs](ports/), including the [GNU binutils](ports/binutils/PACKAGE) suite of utilities and the [GCC](ports/gcc/PACKAGE) compiler.
- UNIX-like [multitasking primitives](kernel/src/sys/exec.cpp), which allow user tasks to spawn other tasks. - Designed to be [portable](kernel/src/arch), so that additional architectures can be added in the future with relatively low effort.
- Some simple [userspace programs](apps/src/), written in C. - Everything text-related is designed around [UTF-8](libluna/include/luna/Utf8.h).
- Simple [command-line shell](apps/src/sh.c), allowing for interactive use of the system. - Environment-agnostic [utility library](libluna/), which can be used in both kernel and userspace.
- Basic multi-user system with [a password file](initrd/etc/passwd) and utilities for [logging in](apps/src/session.c) and [switching users](apps/src/su.c). - An extensive set of [standard Unix utilities](apps/), from [ls](apps/ls.cpp) to [uname](apps/uname.cpp) to [base64](apps/base64.cpp). Written in modern C++ and very small amounts of code, using Luna's practical [OS library](libos/).
- A simple and efficient [windowing system](wind/), providing a lightweight GUI environment (still in development, not many GUI apps exist).
## Notes ## Screenshot
- The default user is named 'selene' and you can log into it with the password 'moon'. ![Screenshot as of 0.6.0](docs/screenshots/screenshot-0.6.0.png)
## System requirements and dependencies
Read [docs/dependencies.md](docs/dependencies.md) for the full information. In short, all modern Unixes should work, provided the dependencies are available.
## Setup ## Setup
To build and run Luna, you will need to build a [GCC Cross-Compiler](https://wiki.osdev.org/Why_do_I_need_a_Cross_Compiler%3F) and cross-binutils for `x86_64-luna`. (Yes, Luna is advanced enough that it can use its own [OS-Specific Toolchain](https://wiki.osdev.org/OS_Specific_Toolchain), instead of a bare metal target like `x86_64-elf`. It is the first of my OS projects to be able to do so. The patches for Binutils and GCC are [binutils.patch](tools/binutils.patch) and [gcc.patch](tools/gcc.patch)).
You should start by installing the [required dependencies](https://wiki.osdev.org/GCC_Cross_Compiler#Installing_Dependencies). To build and run Luna, you will need to build a [cross-compiler](https://wiki.osdev.org/Why_do_I_need_a_Cross_Compiler) and cross-binutils for `x86_64-luna`.
Then, run `tools/setup.sh` to build the toolchain. There is a script provided for this. Run `tools/setup.sh` to build the toolchain.
This script will check whether you have the required versions of the toolchain already setup, and will skip building them if so. (This means that it is used by the build scripts to install the toolchain if it is missing before building, so you could skip running it manually.)
Please beware that building GCC and Binutils can take some time, depending on your machine. Please beware that building GCC and Binutils can take some time, depending on your machine.
## Building
Yes, there is a Makefile sitting on the top level of the repository. It's tempting. But do not use it directly, since it depends on environment variables set by the build scripts.
There are a variety of scripts for building Luna.
`tools/build.sh` will build the kernel, libc and binaries.
`tools/rebuild.sh` will do a full rebuild of the kernel, libc and binaries.
`tools/install.sh` will install those to the system root and initial ramdisk.
`tools/sync-libc.sh` will install the libc headers to the system root, build libc and install it.
`tools/build-iso.sh` will build, install, and make an ISO disk image named Luna.iso.
`tools/build-debug.sh` will rebuild the kernel with debug symbols and optimizations disabled, install, and make an ISO image. This script should only be used when you are going to be running the system with a debugger (such as GDB).
`tools/build-stable-iso.sh` does the same thing as build-iso.sh, but configures the kernel so that the version does not show the commit hash (used for stable versions).
`tools/rebuild-iso.sh` will do a clean rebuild, install, and make an ISO disk image.
In most cases, you should just use `build-iso.sh`.
## Running ## Running
You should have [QEMU](https://www.qemu.org/) installed. `tools/run.sh` is the script you should use in most cases. It will build changed files, install, make an ISO image, and run Luna in QEMU.
You can choose between 3 run scripts: If you have no toolchain set up, `run.sh` will build it automatically, which means that you don't necessarily have to run `setup.sh` manually since `run.sh` does it for you.
`tools/run.sh` is the one you should use in most cases. It will build (only files that have changed since last build), install, make an ISO image, and run Luna in QEMU. ## Login UI
`tools/rebuild-and-run.sh` will rebuild, install, make an ISO, and run Luna in QEMU. For development convenience, the system automatically starts a GUI session as the default user, without prompting for a password.
`tools/debug.sh` will run Luna in QEMU with a port open for GDB to connect to. (run `tools/build-debug.sh`, `tools/gdb.sh`, and then `tools/debug.sh` in a separate terminal for an optimal debugging experience) Despite this, Luna does have a login window built-in. If you'd like to try this feature out or start a GUI session as a different user, you'll need to edit [base/etc/loginui.conf](base/etc/loginui.conf) and change the line that says `Autologin=true` to `Autologin=false`.
Beware that running with optimizations disabled may cause the kernel to behave differently, which is why I don't use it that often.
Essentially, since `run.sh` builds the toolchain if it hasn't been built, builds Luna if it hasn't been built, and runs it, you could just checkout this repo, run `run.sh`, and you're done. No need for the other scripts. Those are included for more fine-grained control/building step-by-step.
You can pass any arguments you want to the run scripts, and those will be forwarded to QEMU. Example: `tools/run.sh -m 512M -net none -machine q35`.
## Prebuilt images ## Prebuilt images
Prebuilt ISO images (numbered) for every version can be found at [pub.cloudapio.eu](https://pub.cloudapio.eu/luna/releases). Prebuilt ISO images for every release version can be found at [pub.cloudapio.eu](https://pub.cloudapio.eu/luna/releases).
These images are built manually whenever I decide to make a new version, and thus don't reflect the latest changes on the `main` branch.
Every hour, my server pulls the latest commits on `main` and builds an hourly ISO image. The ten most recent ones can be found in the [hourly](https://pub.cloudapio.eu/luna/hourly) directory, and [Luna-latest.iso](https://pub.cloudapio.eu/luna/Luna-latest.iso) should always be symlinked to the newest one.
These images do reflect the latest changes on the `main` branch, but are obviously less stable. Additionally, an hourly image will be skipped if building the latest commit of the project fails.
## Is there third-party software I can use on Luna? ## Is there third-party software I can use on Luna?
Yes, actually! Check out the [ports](ports/) directory. Yes! A ports system is in place, and you can use the build scripts to add some ports to your image. More information in the [Ports](ports/README.md) page.
Right now, there are very few ports, because our C Library is a bit primitive and doesn't support complex projects.
You should also keep in mind that it is not possible to compile software written in any language other than C/C++ (and C++ was added recently, its standard library doesn't work very well) for Luna right now.
But feel free to try to port some program yourself and add it to the ports directory!
Port usage:
`ports/add-port.sh <port-name>` will build and add a port to the list of installed ports, and the built port will automatically get installed into the system root every time you run Luna.
`ports/remove-port.sh <port-name>` will remove the port from the list of installed ports, remove built files from the system root, as well as the build directory.
`ports/make-package.sh <port-name>` will compile the port and make a package archive from it, which may be used in the future with a package manager :)
## License ## License
Luna is open-source and free software under the [BSD-2 License](LICENSE). Luna is open-source and free software under the [BSD-2-Clause License](LICENSE).

View File

@ -1,33 +0,0 @@
C_APPS := init sh uname uptime hello ps ls args cat stat su session date mkdir screen
CXX_APPS := hello-cpp
APPS_DIR := $(LUNA_ROOT)/apps
APPS_SRC := $(APPS_DIR)/src
APPS_BIN := $(APPS_DIR)/bin
C_APPS_PATH := $(patsubst %, $(APPS_BIN)/%, $(C_APPS))
CXX_APPS_PATH := $(patsubst %, $(APPS_BIN)/%, $(CXX_APPS))
CFLAGS := -Wall -Wextra -Werror -Os -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -Wl,--gc-sections
CXXFLAGS := -fno-exceptions
$(APPS_BIN)/%: $(APPS_SRC)/%.c
@mkdir -p $(@D)
@$(CC) $(CFLAGS) -o $@ $^
@echo " CC $^"
$(APPS_BIN)/%: $(APPS_SRC)/%.cpp
@mkdir -p $(@D)
@$(CXX) $(CFLAGS) $(CXXFLAGS) -o $@ $^
@echo " CXX $^"
build: $(C_APPS_PATH) $(CXX_APPS_PATH)
install: $(C_APPS_PATH) $(CXX_APPS_PATH)
@mkdir -p $(LUNA_ROOT)/initrd/bin
@cp $(C_APPS_PATH) $(CXX_APPS_PATH) $(LUNA_ROOT)/initrd/bin
@echo " INSTALL $(C_APPS_PATH) $(CXX_APPS_PATH)"
@chmod a+s $(LUNA_ROOT)/initrd/bin/su
clean:
rm -f $(APPS_BIN)/*

View File

@ -1,7 +0,0 @@
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
for (int i = 0; i < argc; i++) puts(argv[i]);
}

View File

@ -1,45 +0,0 @@
#define _GNU_SOURCE // for program_invocation_name
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void cat(FILE* stream)
{
char buf[BUFSIZ];
do {
fgets(buf, BUFSIZ, stream);
if (ferror(stream))
{
perror(program_invocation_name);
exit(EXIT_FAILURE);
}
fputs(buf, stdout);
} while (!feof(stream));
}
int main(int argc, char** argv)
{
if (argc == 1) cat(stdin);
else
{
for (int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "-") == 0) cat(stdin);
else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--newline") == 0)
putchar('\n');
else
{
FILE* stream = fopen(argv[i], "r");
if (!stream)
{
perror(program_invocation_name);
return EXIT_FAILURE;
}
cat(stream);
fclose(stream);
}
}
}
}

View File

@ -1,9 +0,0 @@
#include <stdio.h>
#include <time.h>
int main()
{
time_t date = time(NULL);
fputs(ctime(&date), stdout);
}

View File

@ -1,6 +0,0 @@
#include <cstdio>
int main()
{
printf("Well hello world!\n");
}

View File

@ -1,6 +0,0 @@
#include <stdio.h>
int main()
{
puts("Hello, world!");
}

View File

@ -1,77 +0,0 @@
#include <errno.h>
#include <fcntl.h>
#include <luna.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
void show_motd()
{
int fd = open("/etc/motd", O_RDONLY | O_CLOEXEC);
if (fd < 0)
{
if (errno != ENOENT) { perror("open"); }
return;
}
FILE* fp = fdopen(fd, "r");
if (!fp)
{
perror("fopen");
return;
}
char buf[4096];
size_t nread = fread(buf, 1, sizeof(buf) - 1, fp);
if (ferror(fp))
{
perror("fread");
fclose(fp);
return;
}
buf[nread] = 0;
puts(buf);
fclose(fp);
putchar('\n');
}
int main()
{
if (getpid() != 1)
{
fprintf(stderr, "init must be started as PID 1\n");
return 1;
}
if (getuid() != 0)
{
fprintf(stderr, "init must be started as root\n");
return 1;
}
show_motd();
pid_t child = fork();
if (child < 0)
{
perror("fork");
return 1;
}
if (child == 0)
{
char* argv[] = {"/bin/session", NULL};
execv(argv[0], argv);
perror("execv");
return 1;
}
pid_t result;
for (;;)
{
result = wait(NULL);
if (result == child) return 0;
}
}

View File

@ -1,31 +0,0 @@
#include <dirent.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
const char* pathname;
if (argc == 1) pathname = "/";
else
pathname = argv[1];
DIR* dp = opendir(pathname);
if (!dp)
{
perror("opendir");
return 1;
}
bool first_ent = true;
do {
struct dirent* ent = readdir(dp);
if (!ent) break;
printf(first_ent ? "%s" : " %s", ent->d_name);
first_ent = false;
} while (1);
printf("\n");
closedir(dp);
return 0;
}

View File

@ -1,17 +0,0 @@
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
if (argc == 1)
{
fprintf(stderr, "Usage: %s [directory]", argv[0]);
return 1;
}
if (mkdir(argv[1], 0755) < 0)
{
perror("mkdir");
return 1;
}
}

View File

@ -1,48 +0,0 @@
#include <errno.h>
#include <luna/pstat.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pid_t get_current_max_threads()
{
pid_t result = pstat(-1, NULL);
if (result < 0)
{
perror("pstat(-1)");
exit(1);
}
return result;
}
void display_process(struct pstat* pstatbuf)
{
struct passwd* pwd = getpwuid(pstatbuf->pt_uid);
if (!pwd && errno) perror("getpwuid");
printf("%s %ld %ld %s %s (%ld ms)\n", pwd ? pwd->pw_name : "???", pstatbuf->pt_pid, pstatbuf->pt_ppid,
pstatbuf->pt_name, pstatname(pstatbuf), pstatbuf->pt_time);
}
int try_pstat(pid_t pid, struct pstat* pstatbuf)
{
pid_t result = pstat(pid, pstatbuf);
if (result < 0)
{
if (errno == ESRCH) return 0;
perror("pstat");
exit(1);
}
return 1;
}
int main()
{
struct pstat pst;
pid_t max = get_current_max_threads();
for (pid_t pid = 0; pid <= max; pid++)
{
if (try_pstat(pid, &pst)) { display_process(&pst); }
}
endpwent();
}

View File

@ -1,32 +0,0 @@
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main()
{
int fd = open("/dev/fb0", O_WRONLY | O_CLOEXEC);
if (fd < 0)
{
perror("open");
return 1;
}
int fb_width = ioctl(fd, FB_GET_WIDTH);
if (fb_width < 0)
{
perror("ioctl(FB_GET_WIDTH)");
return 1;
}
int fb_height = ioctl(fd, FB_GET_HEIGHT);
if (fb_height < 0)
{
perror("ioctl(FB_GET_HEIGHT)");
return 1;
}
printf("Your screen is %dx%d\n", fb_width, fb_height);
close(fd);
}

View File

@ -1,145 +0,0 @@
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
static char* echoing_fgets(char* buf, size_t size, FILE* stream)
{
char* s = buf;
memset(buf, 0, size);
size_t oldsize = size;
while (size)
{
int c = fgetc(stream);
if (c == EOF)
{
if (ferror(stream)) return NULL;
if (feof(stream))
{
if (s != buf) return s;
else
return NULL;
};
}
if ((char)c == '\b')
{
if (size != oldsize)
{
buf--;
size++;
putchar('\b');
}
}
else
{
size--;
*buf = (char)c;
buf++;
putchar((char)c);
if ((char)c == '\n') return s;
}
*buf = 0;
}
return s;
}
static void strip_newline(char* str)
{
size_t len = strlen(str);
if (str[len - 1] == '\n') str[len - 1] = 0;
}
static char* collect_password()
{
static char buf[BUFSIZ];
printf("Password: ");
fgets(buf, BUFSIZ, stdin);
strip_newline(buf);
putchar('\n');
char* copy = strdup(
buf); // The password only stays in a caller-controlled heap-allocated buffer, where it can be freed at will.
memset(buf, 0, BUFSIZ);
return copy;
}
static void login_as(struct passwd* user)
{
pid_t child = fork();
if (child < 0)
{
perror("fork");
return;
}
if (child == 0)
{
setgid(user->pw_gid);
setuid(user->pw_uid);
char* argv[] = {user->pw_shell, NULL};
execv(argv[0], argv);
perror("execv");
exit(EXIT_FAILURE);
}
wait(NULL);
}
static int login()
{
printf("Username: ");
char username[BUFSIZ];
echoing_fgets(username, BUFSIZ, stdin);
strip_newline(username);
if (strcmp("exit", username) == 0) return 1;
struct passwd* user = getpwnam(username);
if (!user)
{
if (errno) perror("getpwnam");
else
printf("Unknown user %s\n", username);
return 0;
}
char* password = collect_password();
putchar('\n');
if (strcmp(user->pw_passwd, password) == 0)
{
free(password);
login_as(user);
puts("logout\n");
}
else
{
free(password);
puts("Invalid password.\n");
}
return 0;
}
int main(int argc, char** argv)
{
(void)argc;
if (getuid() != 0)
{
fprintf(stderr,
"%s must be run as root.\nYou are probably looking for the 'su' command, which lets you switch users "
"once logged in.\n",
argv[0]);
return EXIT_FAILURE;
}
for (;;)
{
if (login()) break;
}
endpwent();
return EXIT_SUCCESS;
}

View File

@ -1,359 +0,0 @@
#include <assert.h>
#include <errno.h>
#include <luna.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
static int status = 0;
static char* username = NULL;
typedef struct
{
char* buffer;
size_t size;
size_t capacity;
int interactive;
} command_t;
char** split_command_into_argv(const char* cmd)
{
size_t argc = 1;
char* ptr = strdup(cmd);
char* endptr;
char** arr = calloc(sizeof(char*), argc);
for (;;)
{
endptr = strchr(ptr, ' ');
arr[argc - 1] = ptr;
if (endptr == NULL) break;
*endptr = 0;
ptr = endptr + 1;
if (*ptr)
{
argc++;
arr = realloc(arr, sizeof(char*) * argc);
}
else
break;
}
argc++;
arr = realloc(arr, sizeof(char*) * argc);
arr[argc - 1] = NULL;
return arr;
}
char* shell_concat_path(const char* dirname, const char* basename)
{
char* buf = malloc(strlen(basename) + strlen(dirname) + 6);
strlcpy(buf, dirname, strlen(dirname) + 1);
strncat(buf, basename, strlen(basename));
return buf;
}
void shell_execvp(char* pathname, char* const argv[])
{
char* new_path;
if (access(pathname, F_OK) == 0)
{
execv(pathname, argv);
return;
}
if (pathname[0] == '/') return; // We do not want to lookup absolute paths
new_path = shell_concat_path("/bin/", pathname);
if (access(new_path, F_OK) == 0)
{
execv(new_path, argv);
return;
}
free(new_path);
new_path = shell_concat_path("/usr/bin/", pathname);
execv(new_path, argv);
int saved = errno;
free(new_path);
errno = saved;
}
void show_prompt()
{
if (WEXITSTATUS(status)) { printf("%d [%s]> ", WEXITSTATUS(status), username); }
else
printf("[%s]> ", username);
}
int command_matches(command_t* cmd, const char* string)
{
if (cmd->size <= strlen(string)) // cmd->size includes null terminator
return 0;
return strncmp(cmd->buffer, string, strlen(string)) == 0;
}
int command_matches_exactly(command_t* cmd, const char* string)
{
if (cmd->size <= strlen(string)) // cmd->size includes null terminator
return 0;
if (cmd->size > (strlen(string) + 1)) return 0;
return strncmp(cmd->buffer, string, strlen(string)) == 0;
}
int command_match_builtins(command_t* cmd)
{
if (command_matches(cmd, "exit ")) { exit(atoi(cmd->buffer + 5)); }
if (command_matches_exactly(cmd, "exit")) { exit(0); }
if (command_matches_exactly(cmd, "id"))
{
printf("pid %ld, ppid %ld, uid %d (%s), gid %d\n", getpid(), getppid(), getuid(), username, getgid());
return 1;
}
if (command_matches_exactly(cmd, "clear"))
{
fputs("\033@", stdout); // clear screen. for now, escape sequences in luna are non-standard.
return 1;
}
return 0;
}
void command_expand(command_t* cmd, long new_capacity)
{
char* buffer = realloc(cmd->buffer, new_capacity);
if (!buffer)
{
perror("realloc");
exit(1);
}
cmd->buffer = buffer;
cmd->capacity = new_capacity;
}
void command_push(command_t* cmd, char c)
{
if (cmd->size == cmd->capacity) command_expand(cmd, cmd->capacity + 8);
cmd->buffer[cmd->size] = c;
cmd->size++;
}
void command_pop(command_t* cmd)
{
cmd->size--;
}
void command_init(command_t* cmd)
{
cmd->buffer = malloc(5);
cmd->capacity = 5;
cmd->size = 0;
}
void command_clear(command_t* cmd)
{
free(cmd->buffer);
return command_init(cmd);
}
void process_execute_command(const char* command)
{
char** argv = split_command_into_argv(command);
shell_execvp(argv[0], argv);
perror(argv[0]);
exit(127);
}
void command_execute(command_t* cmd)
{
command_push(cmd, '\0');
if (command_match_builtins(cmd))
{
command_clear(cmd);
if (cmd->interactive) show_prompt();
return;
}
pid_t child = fork();
if (child < 0)
{
perror("fork");
command_clear(cmd);
if (cmd->interactive) show_prompt();
return;
}
if (child == 0) process_execute_command(cmd->buffer);
pid_t result = waitpid(child, &status, 0);
if (result < 0)
{
perror("waitpid");
command_clear(cmd);
if (cmd->interactive) show_prompt();
return;
}
int exit_status = WEXITSTATUS(status);
if (exit_status == -2 || exit_status == -3) printf("(PID %ld) Segmentation fault\n", result);
if (exit_status == -1) printf("(PID %ld) Aborted\n", result);
command_clear(cmd);
if (cmd->interactive) show_prompt();
}
void command_concat_char(command_t* cmd, char c)
{
if (c == '\b')
{
if (cmd->size != 0)
{
if (cmd->interactive) putchar(c);
command_pop(cmd);
}
}
else if (c == '\n')
{
if (cmd->interactive) putchar(c);
if (cmd->size == 0)
{
status = 0;
if (cmd->interactive) show_prompt();
}
else
command_execute(cmd);
}
else
{
if (cmd->interactive) putchar(c);
command_push(cmd, c);
}
}
void command_concat(command_t* cmd, const char* str)
{
while (*str)
{
command_concat_char(cmd, *str);
str++;
}
}
void shell_interactive()
{
show_prompt();
command_t shell_command;
command_init(&shell_command);
shell_command.interactive = 1;
while (1)
{
int c = getchar();
if (c == EOF)
{
if (ferror(stdin))
{
perror("getchar");
exit(EXIT_FAILURE);
}
if (feof(stdin)) exit(EXIT_SUCCESS);
assert(false); // we should never get here
}
command_concat_char(&shell_command, (char)c);
}
}
void shell_read_from_file(const char* pathname)
{
FILE* fp = fopen(pathname, "r");
if (!fp)
{
perror("sh");
exit(EXIT_FAILURE);
}
command_t file_command;
command_init(&file_command);
file_command.interactive = 0;
char buffer[BUFSIZ];
while (fgets(buffer, BUFSIZ, fp))
{
command_concat(&file_command, buffer);
if (feof(fp)) break;
}
if (file_command.size > 0) // last line of file, does not end with newline
{
command_execute(&file_command);
}
fclose(fp);
}
void shell_execute_command(const char* command)
{
command_t cmd;
cmd.buffer = strdup(command);
cmd.size = strlen(command) + 1;
if (command_match_builtins(&cmd)) return;
command_clear(&cmd);
process_execute_command(command);
}
void fetch_username()
{
struct passwd* user = getpwuid(getuid());
if (!user)
{
perror("getpwuid");
exit(EXIT_FAILURE);
}
username = user->pw_name;
endpwent();
}
int main(int argc, char** argv)
{
fetch_username();
if (argc == 1) shell_interactive();
else if (argc == 2)
{
if (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version"))
{
puts("Luna sh version 0.1"); // FIXME: Store the version somewhere, or use the kernel's version.
return 0;
}
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
{
printf("To use interactively: %s\n", argv[0]);
printf("To run a script: %s [script-name]\n", argv[0]);
printf("To get help: %s --help\n", argv[0]);
printf("To show the version: %s --version\n", argv[0]);
printf("To run a command: %s -c [command]\n", argv[0]);
return 0;
}
if (!strcmp(argv[1], "-c") || !strcmp(argv[1], "--command"))
{
fprintf(stderr, "Usage: %s %s [command]\n", argv[0], argv[1]);
fprintf(stderr, "Use the --help flag for more help.\n");
return 1;
}
shell_read_from_file(argv[1]);
}
else if (argc == 3)
{
if (!strcmp(argv[1], "-c") || !strcmp(argv[1], "--command")) shell_execute_command(argv[2]);
else
{
fprintf(stderr, "%s: too many arguments\n", argv[0]);
fprintf(stderr, "Use the --help flag for more help.\n");
return 1;
}
}
else
{
fprintf(stderr, "%s: too many arguments\n", argv[0]);
fprintf(stderr, "Use the --help flag for more help.\n");
return 1;
}
}

View File

@ -1,66 +0,0 @@
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
const char* mode_to_string(mode_t mode)
{
static char mode_string[12];
char mode_set[12] = {'s', 'g', 'r', 'w', 'x', 'r', 'w', 'x', 'r', 'w', 'x', 0};
mode_t mode_val[12] = {S_ISUID, S_ISGID, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP,
S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH, S_IFMT};
for (int i = 0; i < 12; i++)
{
if (mode & mode_val[i]) mode_string[i] = mode_set[i];
else
mode_string[i] = '-';
}
return mode_string;
}
int main(int argc, char** argv)
{
if (argc == 1)
{
fprintf(stderr, "Usage: stat [file]\n");
return EXIT_FAILURE;
}
struct stat st;
if (stat(argv[1], &st) < 0)
{
perror("stat");
return EXIT_FAILURE;
}
printf("Type: ");
switch (st.st_mode & S_IFMT)
{
case S_IFREG: puts("Regular file"); break;
case S_IFDIR: puts("Directory"); break;
case S_IFCHR: puts("Character device"); break;
default: puts("Unknown"); break;
}
struct passwd* own = getpwuid(st.st_uid);
printf("Length: %ld\n", st.st_size);
printf("Inode: %ld\n", st.st_ino);
if (!own) printf("Owned by: UID %d\n", st.st_uid);
else
printf("Owned by: %s\n", own->pw_name);
printf("Mode: %s\n", mode_to_string(st.st_mode));
printf("Accessed on: %s", ctime(&st.st_atime));
printf("Modified on: %s", ctime(&st.st_mtime));
printf("Changed on: %s", ctime(&st.st_ctime));
endpwent();
return EXIT_SUCCESS;
}

View File

@ -1,88 +0,0 @@
#include <errno.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void run_program(char** argv)
{
execv(argv[0], argv);
perror("execv");
exit(EXIT_FAILURE);
}
void strip_newline(char* str)
{
size_t len = strlen(str);
if (str[len - 1] == '\n') str[len - 1] = 0;
}
static const char* collect_password()
{
static char buf[BUFSIZ];
printf("Password: ");
fgets(buf, BUFSIZ, stdin);
strip_newline(buf);
putchar('\n');
return buf;
}
int main(int argc, char** argv)
{
const char* username;
if (argc == 1) username = "root";
else
username = argv[1];
if (geteuid() != 0)
{
fprintf(stderr, "%s must be setuid root", argv[0]);
return EXIT_FAILURE;
}
struct passwd* user = getpwnam(username);
endpwent();
if (!user)
{
if (errno) perror("getpwnam");
else
fprintf(stderr, "Unknown user %s\n", username);
return EXIT_FAILURE;
}
if (getuid() != geteuid()) // we were started from a non-root user
{
const char* pw = collect_password();
if (strcmp(pw, user->pw_passwd) != 0)
{
fprintf(stderr, "Invalid password\n");
return EXIT_FAILURE;
}
}
if (setgid(user->pw_gid) < 0)
{
perror("setgid");
return EXIT_FAILURE;
}
if (setuid(user->pw_uid) < 0)
{
perror("setuid");
return EXIT_FAILURE;
}
char* default_argv[] = {user->pw_shell, NULL};
if (argc < 3) run_program(default_argv);
else
run_program(argv + 2);
}

View File

@ -1,18 +0,0 @@
#include <stdio.h>
int main()
{
FILE* fp = fopen("/dev/version", "r");
if (!fp)
{
perror("fopen");
return 1;
}
char buf[BUFSIZ];
fgets(buf, sizeof(buf), fp);
printf("%s\n", buf);
fclose(fp);
}

View File

@ -1,38 +0,0 @@
#include <stdio.h>
#include <time.h>
#define VALUE_SINGULAR_AT_ONE(v) v, v == 1 ? "" : "s"
int main()
{
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp); // On Luna, CLOCK_MONOTONIC starts at boot.
struct tm* time = gmtime(
&tp.tv_sec); // just splitting the value into seconds, minutes, hours, days... not the best way to do it but ok.
time->tm_year -= 70;
if (time->tm_year)
{
printf("up for %d year%s, %d day%s, %d hour%s, %d minute%s, %d second%s\n",
VALUE_SINGULAR_AT_ONE(time->tm_year), VALUE_SINGULAR_AT_ONE(time->tm_yday),
VALUE_SINGULAR_AT_ONE(time->tm_hour), VALUE_SINGULAR_AT_ONE(time->tm_min),
VALUE_SINGULAR_AT_ONE(time->tm_sec));
}
else if (time->tm_yday)
{
printf("up for %d day%s, %d hour%s, %d minute%s, %d second%s\n", VALUE_SINGULAR_AT_ONE(time->tm_yday),
VALUE_SINGULAR_AT_ONE(time->tm_hour), VALUE_SINGULAR_AT_ONE(time->tm_min),
VALUE_SINGULAR_AT_ONE(time->tm_sec));
}
else if (time->tm_hour)
{
printf("up for %d hour%s, %d minute%s, %d second%s\n", VALUE_SINGULAR_AT_ONE(time->tm_hour),
VALUE_SINGULAR_AT_ONE(time->tm_min), VALUE_SINGULAR_AT_ONE(time->tm_sec));
}
else if (time->tm_min)
printf("up for %d minute%s, %d second%s\n", VALUE_SINGULAR_AT_ONE(time->tm_min),
VALUE_SINGULAR_AT_ONE(time->tm_sec));
else
printf("up for %d second%s\n", VALUE_SINGULAR_AT_ONE(time->tm_sec));
}

1
base/bin Symbolic link
View File

@ -0,0 +1 @@
usr/bin

5
base/etc/group Normal file
View File

@ -0,0 +1,5 @@
root:!:0:
users:!:1:selene
wind:!:2:selene
wsys:!:3:
selene:!:1000:

1
base/etc/hostname Normal file
View File

@ -0,0 +1 @@
lunar

4
base/etc/init/00-home Normal file
View File

@ -0,0 +1,4 @@
Name=mount-home
Description=Mount the user's home directory on a writable filesystem.
Command=/etc/startup/mount-home.sh
Wait=true

6
base/etc/init/99-login Normal file
View File

@ -0,0 +1,6 @@
Name=login
Description=Start a graphical user session.
Command=/usr/bin/loginui
StandardOutput=/dev/uart0
StandardError=/dev/uart0
Restart=true

5
base/etc/loginui.conf Normal file
View File

@ -0,0 +1,5 @@
# Configuration file for loginui.
# If this parameter is set to "true", loginui automatically spawns a UI session as the below user instead of prompting for a username and password.
Autologin=true
# The user to create a session for if "Autologin" is set to true (see above). If the username is invalid, loginui will behave as if "Autologin" was set to false.
AutologinUser=selene

4
base/etc/motd Normal file
View File

@ -0,0 +1,4 @@
Welcome to the Luna system!
Have a look around, you can run 'ls /bin' to list available commands.
You can use the username 'selene' with the password 'moon' to start a user session.

3
base/etc/passwd Normal file
View File

@ -0,0 +1,3 @@
root:x:0:0:Administrator:/:/usr/bin/sh
wind:x:2:2:Window Manager:/:/usr/bin/init
selene:x:1000:1000:User:/home/selene:/usr/bin/sh

3
base/etc/shadow Normal file
View File

@ -0,0 +1,3 @@
root:ce5ca673d13b36118d54a7cf13aeb0ca012383bf771e713421b4d1fd841f539a:0:0:99999:7:::
wind:!:0:0:99999:7:::
selene:9e78b43ea00edcac8299e0cc8df7f6f913078171335f733a21d5d911b6999132:0:0:99999:7:::

26
base/etc/skel/welcome Normal file
View File

@ -0,0 +1,26 @@
Welcome to the Luna operating system!
You are running on the default user account, selene.
If you are familiar with Unix-style operating systems (like Linux or *BSD),
you should be able to use the Luna terminal without much problems.
Following the traditional Unix filesystem structure,
programs are installed in /usr/bin (/bin is a symlink to /usr/bin).
The command `ls /bin` will show all commands available on
your current Luna installation.
Currently, because of driver limitations,
the root file system is mounted read-only.
Your home folder is writable, but volatile; it is
created and populated on boot,
and its contents will vanish after a reboot.
The system is booted using the 'init' program.
You can read its configuration files in the /etc/init directory to
learn more about the boot process.
Luna is free software, released under the BSD-2-Clause license.
The license is included in the LICENSE file in your home directory.
View the source code and read more about Luna at
https://git.cloudapio.eu/apio/Luna.

View File

@ -0,0 +1,10 @@
#!/bin/sh
# Create and populate a volatile home directory.
mount -t tmpfs tmpfs /home/selene
chown selene:selene /home/selene
cp /etc/skel/welcome /home/selene/
cp /etc/skel/LICENSE /home/selene/
chown selene:selene /home/selene/welcome
chown selene:selene /home/selene/LICENSE

3
base/etc/user/00-welcome Normal file
View File

@ -0,0 +1,3 @@
Name=welcome
Description=Show a welcome message for the user.
Command=/usr/bin/editor welcome

View File

@ -0,0 +1,3 @@
Name=terminal
Icon=/usr/share/icons/32x32/app-terminal.tga
Command=/usr/bin/terminal

View File

@ -0,0 +1,3 @@
Name=about
Icon=/usr/share/icons/32x32/app-about.tga
Command=/usr/bin/about

View File

@ -0,0 +1,3 @@
Name=gol
Icon=/usr/share/icons/32x32/app-gol.tga
Command=/usr/bin/gol

View File

@ -0,0 +1,3 @@
Name=clock
Icon=/usr/share/icons/32x32/app-clock.tga
Command=/usr/bin/clock

View File

@ -0,0 +1,3 @@
Name=2048
Icon=/usr/share/icons/32x32/app-2048.tga
Command=/usr/bin/2048

View File

@ -0,0 +1,3 @@
Name=editor
Icon=/usr/share/icons/32x32/app-editor.tga
Command=/usr/bin/editor

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

256
docs/boot_process.md Normal file
View File

@ -0,0 +1,256 @@
# The Luna boot process
## Stage 0: The Bootloader
Luna uses the [BOOTBOOT](https://gitlab.com/bztsrc/bootboot) bootloader. _(For more information, read the [bootloader specification](https://gitlab.com/bztsrc/bootboot/-/blob/master/bootboot_spec_1st_ed.pdf).)_
This bootloader reads the initial ramdisk, which contains the following files:
```
/sys/config - copy of the configuration file for the bootloader
/boot/moon - the kernel itself
/bin/preinit - the first user program run in the boot process, before the root filesystem is mounted
```
The bootloader loads the kernel in 64-bit mode into the higher half at address `0xffffffffffe02000`, with an appropriate stack already set up.
The first 16Gb of memory are identity-mapped at page 0.
It places a few other things into known addresses:
```
0xfffffffffc000000 - initial framebuffer
0xffffffffffe00000 - bootloader information passed to the kernel
0xffffffffffe01000 - kernel command line
```
From here, the kernel takes over.
## Stage 1: The Kernel
_Relevant files: [kernel/src/main.cpp](../kernel/src/main.cpp), [kernel/src/arch/x86_64/CPU.cpp](../kernel/src/arch/x86_64/CPU.cpp#L285)_
The kernel begins execution in the `_start()` function. This function initializes basic kernel functionality, such as time-keeping, memory management, graphics, and finally threading.
Once threading is set up and the scheduler is started, the kernel starts up a new kernel thread titled `[kinit]` to finish starting up other subsystems that assume they're running in a thread.
Before switching to `[kinit]`, `_start` does one more thing, it calls the `CPU::platform_finish_init()` function which is platform-specific. On x86_64, this function does the following things:
- Creates a new kernel thread: `[x86_64-io]`, which handles keyboard and mouse interrupts asynchronously
- Starts receiving external interrupts
- Initializes the mouse
As soon as the scheduler switches to the `[kinit]` thread, it will never return to `_start` (since it has no thread associated to it).
**IMPORTANT**: Although the `[kinit]` thread is the first thread to be started in the system, it has PID 2, not 1. The reason for this is that PID 1 is reserved for the userspace init process.
`[kinit]` does the following things, in order:
- Loads kernel debug symbols from the initial ramdisk
- Creates the virtual file system and mounts the initial ramdisk on /
- Initializes virtual device files such as `/dev/null` (the internal kernel representation of them, `/dev` is not mounted yet)
- Loads `/bin/preinit` from the initial ramdisk as PID 1
- Creates two more kernel threads, `[reap]` and `[oom]`
- Scans for ATA hard disks and reads their partition tables
- Finally, it sets PID 1's state to "Running" so that the scheduler can switch to it, and exits
### Kernel threads
`[kinit]` spawns two more kernel threads, `[reap]` and `[oom]`. While `[kinit]` exits before PID 1 is started, `[reap]` and `[oom]` are present throughout the lifetime of a Luna system, and can be seen in the output of `ps`. Let's take a look at what they do.
- `[reap]`: To understand what this thread does, we must take a look at what happens when processes exit on Luna.
_(Relevant files: [kernel/src/main.cpp](../kernel/src/main.cpp#L23), [kernel/src/thread/Scheduler.cpp](../kernel/src/thread/Scheduler.cpp#L231), [kernel/src/thread/Thread.cpp](../kernel/src/thread/Thread.cpp#L126), [kernel/src/sys/waitpid.cpp](../kernel/src/sys/waitpid.cpp#L84))_
When a process calls the `_exit()` syscall, all its threads' states are set to "Dying". This tells the scheduler to avoid switching to them, and the process's parent is notified, by sending SIGCHLD and (optionally) unblocking a blocked `waitpid()` call. The process remains visible to the rest of the system, and if its parent does not wait for it, it will stay there as a "zombie process". Meanwhile, the `[reap]` thread runs and collects all the resources from each thread. The process object is still alive (in a "zombie" state), but its threads have been cleaned up.
When the process's parent waits for it, it is marked for reaping (by setting its thread count to -1 (PROCESS_SHOULD_REAP)), and the `[reap]` thread runs.
The `[reap]` thread then "reaps" all the dead processes' resources. It frees up their memory, file descriptors, and other resources. After reaping, the process is deleted, and no trace of it is left.
- `[oom]`: This thread handles Out-Of-Memory (OOM) situations. Whenever the kernel has 1/4 or 1/8 of the available physical memory left (thresholds may be tweaked in the future), or it has run out, it runs this thread.
The OOM thread then goes through all the disk caches and purges them all, hoping to reclaim as much memory as possible.
### File system and process layout
After the kernel stage of the boot process, the system looks like this:
#### File system
```
/ - initial ramdisk
/sys/config - copy of the configuration file for the bootloader
/boot/moon - the kernel itself
/bin/preinit - the first user program run in the boot process
```
#### Processes
```
/bin/preinit - PID 1
[kinit] - PID 2 (Exited, soon to be reaped)
[x86_64-io] - PID 3
[reap] - PID 4
[oom] - PID 5
```
## Stage 2: preinit
_Relevant files: [system/preinit.cpp](../system/preinit.cpp)_
Luna's userspace init process is split into two programs: `/bin/preinit`, which resides on the initial ramdisk, and `/usr/bin/init`, which resides on the root partition.
`/bin/preinit`'s job is to set up the file system in a "minimal known good" state for the actual `init` to run.
The "minimal known good" state includes:
- The ext2 root partition, which includes all the binaries in /usr
- The /dev file system
`preinit` does the following things, in order:
- Mounts `/dev` to get access to disk device files
- Mounts the root partition (`/dev/cd0p2`) on `/osroot`
- Unmounts `/dev`
- Uses the `pivot_root` system call to change the root file system to the one that was in `/osroot`, and mounts the old one on `/mnt` (previously `/osroot/mnt`)
- Unmounts the initial ramdisk on `/mnt`
- Mounts the `/dev` file system again on the new root partition
- Executes `/usr/bin/init`
For now, much of `preinit`'s functionality is hard-coded, but as Luna supports more devices, it will become responsible for loading device drivers, discovering the root partition, and more...
### File system and process layout
After the preinit stage of the boot process, the system looks like this:
#### File system
```
/ - ext2 root partition
/dev - device file system
/usr, /etc, /home... - other directories contained in the root partition
```
#### Processes
```
/usr/bin/init - PID 1
[x86_64-io] - PID 3
[reap] - PID 4
[oom] - PID 5
```
## Stage 3: init
_Relevant files: [system/init.cpp](../system/init.cpp#L406)_
`/usr/bin/init` is the actual init system. It is in charge of starting user-defined services.
It does the following things:
- Mounts `/tmp`, `/dev/shm` and `/dev/pts`
- Sets the system hostname by reading `/etc/hostname`
- Reads configuration files from `/etc/init`
- Starts services defined in `/etc/init`
- Enters the init loop, waiting for child processes and restarting them if needed
Currently, there are two service files defined by default in `/etc/init`:
`00-home`: This service sets up a `tmpfs` on `/home/selene`, so that the home directory is writable.
`99-login`: This service starts a graphical session, by calling `/usr/bin/loginui`. This service will be restarted if necessary.
### File system and process layout
After the init stage of the boot process, the system looks like this:
#### File system
```
/ - ext2 root partition
/dev - device file system
/dev/shm - POSIX shared memory file system
/dev/pts - POSIX pseudoterminal file system
/tmp - system temporary file directory
/usr, /etc, /home... - other directories contained in the root partition
/home/selene - temporary home directory
```
#### Processes
```
/usr/bin/init - PID 1
[x86_64-io] - PID 3
[reap] - PID 4
[oom] - PID 5
/usr/bin/loginui - PID 13
```
_Note: loginui is PID 13 because the `00-home` service is a shell script, which starts a few subprocesses. Since Luna does not allow for PID reuse right now, loginui ends up with PID 13._
## Stage 4: loginui
_Relevant files: [gui/loginui.cpp](../gui/loginui.cpp), [gui/wind/main.cpp](../gui/wind/main.cpp)_
`/usr/bin/loginui`'s job is quite simple: it prompts the user to log in with their password, after which a graphical session is started.
_Note: On development builds, Autologin=true is added to /etc/loginui.conf which disables password prompting and executes startui directly._
First, loginui starts the display server, `/usr/bin/wind`, so that it can use its capabilities to show a graphical login prompt. It is started with permissions `root:root`, and later drops privileges to `wind:wind`.
After that, loginui prompts for a username and password, checks it against the hashed password stored in `/etc/shadow`, and finally executes `/usr/bin/startui` which does the actual heavy work of starting all the services needed for a UI session.
### File system and process layout
After the loginui stage of the boot process, the system looks like this:
#### File system
```
/ - ext2 root partition
/dev - device file system
/dev/shm - POSIX shared memory file system
/dev/pts - POSIX pseudoterminal file system
/tmp - system temporary file directory
/usr, /etc, /home... - other directories contained in the root partition
/home/selene - temporary home directory
```
#### Processes
```
/usr/bin/init - PID 1
[x86_64-io] - PID 3
[reap] - PID 4
[oom] - PID 5
/usr/bin/startui - PID 13
/usr/bin/wind - PID 14
```
## Stage 5: startui
_Relevant files: [system/startui.cpp](../system/startui.cpp), [gui/wind/main.cpp](../gui/wind/main.cpp)_
`/usr/bin/startui` starts a graphical user session.
A Luna graphical user session includes the following components:
- The display server itself, `/usr/bin/wind`. If not already started by loginui, `startui` makes sure it's running.
- The execution server (`/usr/bin/execd`), which starts processes and keeps them alive on behalf of other processes. It is started with the standard permissions `selene:selene`.
- The taskbar, `/usr/bin/taskbar`. It is started with the standard permissions `selene:selene`, plus an extra group `wsys` to be able to connect to a special display server socket (`/tmp/wsys.sock`, as opposed to the standard `/tmp/wind.sock`). This grants it the ability to use advanced wind features, such as placing the taskbar window behind all other windows.
- The init process corresponding to that session (`/usr/bin/init --user`). This process does the same thing as `init` above (manages services), but runs with user privileges and reads configuration files from `/etc/user` instead (in the future this will be changed to a user-specific directory).
Currently, `init --user` only does one thing: it opens up a text editor with a welcome message on startup. It can be configured to do whatever the user desires to do on startup, by placing the appropriate configuration files in `/etc/user`.
### File system and process layout
After the startui stage of the boot process, the system is fully started up and looks like this:
#### File system
```
/ - ext2 root partition
/dev - device file system
/dev/shm - POSIX shared memory file system
/dev/pts - POSIX pseudoterminal file system
/tmp - system temporary file directory
/usr, /etc, /home... - other directories contained in the root partition
/home/selene - temporary home directory
```
#### Processes
```
/usr/bin/init - PID 1
[x86_64-io] - PID 3
[reap] - PID 4
[oom] - PID 5
/usr/bin/startui - PID 13
/usr/bin/wind - PID 14
/usr/bin/execd - PID 15
/usr/bin/taskbar - PID 16
/usr/bin/init --user - PID 17
/usr/bin/editor welcome - PID 18

35
docs/dependencies.md Normal file
View File

@ -0,0 +1,35 @@
# Dependencies required to build and run Luna
## System requirements
Any modern UNIX-like system that supports all the tools listed below should work (Hopefully, that will include Luna itself in the future!).
I personally build and run Luna on an amd64 Fedora Linux 40 machine. CI runs on arm64 Ubuntu 22.04. Any other configurations are untested. Windows is not supported, although you can try using WSL if you really want to.
## Building a cross-compiler toolchain
For this, you should start by installing the [required dependencies](https://wiki.osdev.org/GCC_Cross_Compiler#Installing_Dependencies) for any OSdev cross-compiler build.
Also make sure you have the perl module `File::Compare` installed, it is required to build autoconf. On Fedora you can install it using the package manager by running `# dnf install perl-File-Compare`. If your distro doesn't have it, you might have to install it via `cpan`.
## Building the actual system
The build process needs some extra dependencies to run: `cmake`, `ninja`, `nasm`, `fakeroot` and `genext2fs`. On some distributions the `ninja` package is called `ninja-build` instead.
If you want to use `make` instead of `ninja`, create a file called `env-local.sh` in the project root and add the line `USE_MAKE=1`. In this case, ninja does not need to be installed.
## Running the built image in a virtual machine
The script provided by the project to run the system, `tools/run.sh`, assumes that QEMU is installed and uses that to run the image. Therefore, make sure your system has `qemu-system-x86_64` in the PATH. If it doesn't, install it using the method appropriate for your system, usually installing `qemu` or `qemu-system` from the package manager.
That being said, there's no requirement to use QEMU. If you want to use a different virtualization program, such as Oracle VirtualBox or VMWare, just use `tools/build-iso.sh` instead of `run.sh` and use the built `Luna.iso` in those programs.
## Formatting/linting
Please make sure you have `clang-format` installed. Additionally, if your editor does not support format-on-save or you do not have it configured, please run `tools/run-clang-format.sh` before committing, to make sure all code follows the same style conventions.
## Source dependencies
TLDR: Luna does not depend on any third-party library.
Every part of Luna is written from scratch and depends only on its own libraries and programs, with two small exceptions (included here for crediting and licensing purposes, but there is no need to download and build them separately):
The bootloader, BOOTBOOT. It is available at [gitlab.com/bztsrc/bootboot](https://gitlab.com/bztsrc/bootboot), under the MIT license. It is automatically pulled and built from source by `tools/setup.sh`.
[libc/src/strtod.cpp](../libc/src/strtod.cpp). Written by Yasuhiro Matsumoto, adapted from https://gist.github.com/mattn/1890186 and available under a public domain license.

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

17
gui/CMakeLists.txt Normal file
View File

@ -0,0 +1,17 @@
function(luna_service SOURCE_FILE APP_NAME)
add_executable(${APP_NAME} ${SOURCE_FILE})
target_compile_options(${APP_NAME} PRIVATE -Os ${COMMON_FLAGS} -Wno-write-strings)
add_dependencies(${APP_NAME} libc)
target_include_directories(${APP_NAME} PRIVATE ${LUNA_BASE}/usr/include)
target_link_libraries(${APP_NAME} PRIVATE os)
install(TARGETS ${APP_NAME} DESTINATION ${LUNA_BASE}/usr/bin)
endfunction()
add_subdirectory(libui)
add_subdirectory(wind)
add_subdirectory(apps)
luna_service(execd.cpp execd)
luna_service(run.cpp run)
luna_service(loginui.cpp loginui)
target_link_libraries(loginui PRIVATE ui)

364
gui/apps/2048.cpp Normal file
View File

@ -0,0 +1,364 @@
#include <luna/RefString.h>
#include <luna/Utf8.h>
#include <stdlib.h>
#include <time.h>
#include <ui/Alignment.h>
#include <ui/App.h>
#include <ui/Font.h>
#include <ui/Layout.h>
static ui::Color colors[] = {
ui::Color::from_rgb(255, 255, 0), ui::Color::from_rgb(255, 230, 0), ui::Color::from_rgb(255, 210, 0),
ui::Color::from_rgb(255, 190, 0), ui::Color::from_rgb(255, 170, 0), ui::Color::from_rgb(255, 150, 0),
ui::Color::from_rgb(255, 130, 0), ui::Color::from_rgb(255, 110, 0), ui::Color::from_rgb(255, 90, 0),
ui::Color::from_rgb(255, 70, 0), ui::Color::from_rgb(255, 50, 0),
};
struct Tile
{
int number { 0 };
int color { 0 };
};
class GameWidget final : public ui::Widget
{
public:
static constexpr int MARGIN = 5;
Result<void> draw(ui::Canvas& canvas) override
{
int width = m_rect.width / 4;
int height = m_rect.height / 4;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
auto subcanvas = canvas.subcanvas(
ui::Rect { width * j + MARGIN, height * i + MARGIN, width - MARGIN, height - MARGIN });
int index = i * 4 + j;
TRY(draw_tile(index, subcanvas));
}
}
return {};
}
Result<ui::EventResult> handle_key_event(const ui::KeyEventRequest& request) override
{
if (!request.pressed) return ui::EventResult::DidNotHandle;
bool should_add_tile = false;
switch (request.code)
{
case moon::K_UpArrow: {
bool changed;
changed = move_up();
if (changed) should_add_tile = true;
join_up();
changed = move_up();
if (changed) should_add_tile = true;
}
break;
case moon::K_LeftArrow: {
bool changed;
changed = move_left();
if (changed) should_add_tile = true;
join_left();
changed = move_left();
if (changed) should_add_tile = true;
}
break;
case moon::K_DownArrow: {
bool changed;
changed = move_down();
if (changed) should_add_tile = true;
join_down();
changed = move_down();
if (changed) should_add_tile = true;
}
break;
case moon::K_RightArrow: {
bool changed;
changed = move_right();
if (changed) should_add_tile = true;
join_right();
changed = move_right();
if (changed) should_add_tile = true;
}
break;
case moon::K_Home: {
reset();
return ui::EventResult::DidHandle;
}
break;
default: return ui::EventResult::DidNotHandle;
}
if (should_add_tile) add_tile();
return ui::EventResult::DidHandle;
}
bool move_left()
{
Tile new_tiles[16];
bool changed = false;
for (int i = 0; i < 4; i++)
{
int pos = 0;
for (int j = 0; j < 4; j++)
{
if (tiles[i * 4 + j].number != 0)
{
new_tiles[i * 4 + pos] = tiles[i * 4 + j];
pos += 1;
changed = true;
}
}
}
memcpy(tiles, new_tiles, sizeof(tiles));
return changed;
}
void join_left()
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
auto& from_tile = tiles[i * 4 + j];
auto& to_tile = tiles[i * 4 + j + 1];
if (from_tile.number != 0 && from_tile.number == to_tile.number)
{
from_tile.number *= 2;
from_tile.color += 1;
to_tile.number = 0;
}
}
}
}
bool move_right()
{
Tile new_tiles[16];
bool changed = false;
for (int i = 0; i < 4; i++)
{
int pos = 3;
for (int j = 0; j < 4; j++)
{
if (tiles[i * 4 + j].number != 0)
{
new_tiles[i * 4 + pos] = tiles[i * 4 + j];
pos -= 1;
changed = true;
}
}
}
memcpy(tiles, new_tiles, sizeof(tiles));
return changed;
}
void join_right()
{
for (int i = 0; i < 4; i++)
{
for (int j = 1; j < 4; j++)
{
auto& from_tile = tiles[i * 4 + j];
auto& to_tile = tiles[i * 4 + j - 1];
if (from_tile.number != 0 && from_tile.number == to_tile.number)
{
from_tile.number *= 2;
from_tile.color += 1;
to_tile.number = 0;
}
}
}
}
bool move_up()
{
Tile new_tiles[16];
bool changed = false;
for (int j = 0; j < 4; j++)
{
int pos = 0;
for (int i = 0; i < 4; i++)
{
if (tiles[i * 4 + j].number != 0)
{
new_tiles[pos * 4 + j] = tiles[i * 4 + j];
pos += 1;
changed = true;
}
}
}
memcpy(tiles, new_tiles, sizeof(tiles));
return changed;
}
void join_up()
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
auto& from_tile = tiles[i * 4 + j];
auto& to_tile = tiles[i * 4 + j + 4];
if (from_tile.number != 0 && from_tile.number == to_tile.number)
{
from_tile.number *= 2;
from_tile.color += 1;
to_tile.number = 0;
}
}
}
}
bool move_down()
{
Tile new_tiles[16];
bool changed = false;
for (int j = 0; j < 4; j++)
{
int pos = 3;
for (int i = 0; i < 4; i++)
{
if (tiles[i * 4 + j].number != 0)
{
new_tiles[pos * 4 + j] = tiles[i * 4 + j];
pos -= 1;
changed = true;
}
}
}
memcpy(tiles, new_tiles, sizeof(tiles));
return changed;
}
void join_down()
{
for (int i = 1; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
auto& from_tile = tiles[i * 4 + j];
auto& to_tile = tiles[i * 4 + j - 4];
if (from_tile.number != 0 && from_tile.number == to_tile.number)
{
from_tile.number *= 2;
from_tile.color += 1;
to_tile.number = 0;
}
}
}
}
void add_tile()
{
bool can_add_tile = false;
for (int i = 0; i < 16; i++)
{
if (tiles[i].number == 0)
{
can_add_tile = true;
break;
}
}
if (!can_add_tile)
{
reset();
return;
}
int start;
do {
start = rand() % 16;
} while (tiles[start].number != 0);
tiles[start].number = 2;
tiles[start].color = 0;
}
void reset()
{
for (int i = 0; i < 16; i++)
{
tiles[i].number = 0;
tiles[i].color = 0;
}
add_tile();
}
Tile tiles[16];
private:
Result<void> draw_tile(int index, ui::Canvas& canvas)
{
auto tile = tiles[index];
if (tile.number == 0)
{
canvas.fill(ui::GRAY);
return {};
}
canvas.fill(colors[tile.color]);
auto fmt = TRY(RefString::format("%d"_sv, tile.number));
auto font = ui::Font::default_bold_font();
auto rect = ui::align({ 0, 0, canvas.width, canvas.height },
{ 0, 0, (int)fmt.length() * font->width(), font->height() },
ui::VerticalAlignment::Center, ui::HorizontalAlignment::Center);
auto subcanvas = canvas.subcanvas(rect);
Utf8StringDecoder decoder(fmt.chars());
wchar_t buf[4096];
TRY(decoder.decode(buf, sizeof(buf)));
font->render(buf, ui::BLACK, subcanvas);
return {};
}
};
Result<int> luna_main(int, char**)
{
srand((unsigned)time(NULL));
ui::App app;
TRY(app.init());
auto* window = TRY(ui::Window::create(ui::Rect { 300, 300, 400, 400 }));
app.set_main_window(window);
window->set_background(ui::BLACK);
window->set_title("2048");
GameWidget game;
window->set_main_widget(game);
game.reset();
return app.run();
}

17
gui/apps/CMakeLists.txt Normal file
View File

@ -0,0 +1,17 @@
function(luna_app SOURCE_FILE APP_NAME)
add_executable(${APP_NAME} ${SOURCE_FILE})
target_compile_options(${APP_NAME} PRIVATE -Os ${COMMON_FLAGS} -Wno-write-strings)
add_dependencies(${APP_NAME} libc)
target_include_directories(${APP_NAME} PRIVATE ${LUNA_BASE}/usr/include)
target_link_libraries(${APP_NAME} PRIVATE os ui)
install(TARGETS ${APP_NAME} DESTINATION ${LUNA_BASE}/usr/bin)
endfunction()
luna_app(about.cpp about)
luna_app(taskbar.cpp taskbar)
luna_app(2048.cpp 2048)
luna_app(clock.cpp clock)
luna_app(gol.cpp gol)
add_subdirectory(editor)
add_subdirectory(terminal)

47
gui/apps/about.cpp Normal file
View File

@ -0,0 +1,47 @@
#include <luna/String.h>
#include <sys/utsname.h>
#include <ui/App.h>
#include <ui/Button.h>
#include <ui/Label.h>
#include <ui/Layout.h>
static constexpr ui::Color BACKGROUND_COLOR = ui::Color::from_rgb(89, 89, 89);
Result<int> luna_main(int, char**)
{
ui::App app;
TRY(app.init());
auto* window = TRY(ui::Window::create(ui::Rect { 300, 300, 400, 300 }));
app.set_main_window(window);
window->set_title("About");
window->set_background(BACKGROUND_COLOR);
utsname info;
uname(&info);
ui::VerticalLayout main_layout;
window->set_main_widget(main_layout);
ui::Label title("About Luna");
title.set_font(ui::Font::default_bold_font());
main_layout.add_widget(title);
ui::VerticalLayout version_info;
main_layout.add_widget(version_info);
ui::Label license("Licensed under the BSD-2-Clause license.");
main_layout.add_widget(license);
String os_release_text = TRY(String::format("OS release: %s"_sv, info.release));
ui::Label os_release(os_release_text.view());
version_info.add_widget(os_release);
String kernel_version_text = TRY(String::format("Kernel version: %s"_sv, info.version));
ui::Label kernel_version(kernel_version_text.view());
version_info.add_widget(kernel_version);
return app.run();
}

43
gui/apps/clock.cpp Normal file
View File

@ -0,0 +1,43 @@
#include <os/Timer.h>
#include <time.h>
#include <ui/App.h>
#include <ui/Label.h>
ui::Label* g_label;
void update_time()
{
time_t t = time(NULL);
struct tm* tp = localtime(&t);
static char buf[2048];
strftime(buf, sizeof(buf), "%H:%M:%S", tp);
g_label->set_text(StringView { buf });
ui::App::the().main_window()->draw();
}
Result<int> luna_main(int, char**)
{
ui::App app;
TRY(app.init());
auto* window = TRY(ui::Window::create(ui::Rect { 500, 400, 100, 50 }));
app.set_main_window(window);
window->set_title("Clock");
window->set_background(ui::GRAY);
g_label = TRY(make<ui::Label>("00:00:00"));
g_label->set_font(ui::Font::default_bold_font());
g_label->set_color(ui::BLACK);
window->set_main_widget(*g_label);
update_time();
auto timer = TRY(os::Timer::create_repeating(1000, update_time));
return app.run();
}

View File

@ -0,0 +1,12 @@
set(SOURCES
main.cpp
EditorWidget.h
EditorWidget.cpp
)
add_executable(editor ${SOURCES})
target_compile_options(editor PRIVATE -Os ${COMMON_FLAGS} -Wno-write-strings)
add_dependencies(editor libc)
target_include_directories(editor PRIVATE ${LUNA_BASE}/usr/include ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(editor PRIVATE os ui)
install(TARGETS editor DESTINATION ${LUNA_BASE}/usr/bin)

View File

@ -0,0 +1,259 @@
/**
* @file EditorWidget.cpp
* @author apio (cloudapio.eu)
* @brief Multiline text editing widget.
*
* @copyright Copyright (c) 2024, the Luna authors.
*
*/
#include "EditorWidget.h"
#include <ctype.h>
#include <luna/PathParser.h>
#include <luna/RefString.h>
#include <luna/Utf8.h>
#include <os/File.h>
#include <os/FileSystem.h>
#include <ui/App.h>
#include <ui/Dialog.h>
EditorWidget::EditorWidget(SharedPtr<ui::Font> font) : ui::TextInput(), m_font(font)
{
recalculate_lines();
}
Result<void> EditorWidget::load_file(const os::Path& path)
{
struct stat st;
auto rc = os::FileSystem::stat(path, st, true);
if (!rc.has_error() && !S_ISREG(st.st_mode))
{
auto message = TRY(RefString::format("%s is not a regular file", path.name().chars()));
ui::Dialog::show_message("Error", message.view());
return {};
}
os::eprintln("Loading file: %s", path.name().chars());
auto file = TRY(os::File::open_or_create(path, os::File::ReadOnly));
m_data = TRY(file->read_all());
os::eprintln("Read %zu bytes.", m_data.size());
m_cursor = m_data.size();
m_path = TRY(String::from_string_view(path.name()));
auto basename = TRY(PathParser::basename(m_path.view()));
String title = TRY(String::format("Text Editor - %s"_sv, basename.chars()));
window()->set_title(title.view());
TRY(recalculate_lines());
return {};
}
Result<ui::EventResult> EditorWidget::handle_key_event(const ui::KeyEventRequest& request)
{
// Avoid handling "key released" events
if (!request.pressed) return ui::EventResult::DidNotHandle;
if (request.code == moon::K_UpArrow)
{
if (m_cursor_position.y > 0) m_cursor_position.y--;
else
return ui::EventResult::DidNotHandle;
recalculate_cursor_index();
update_cursor();
return ui::EventResult::DidHandle;
}
if (request.code == moon::K_DownArrow)
{
if (m_cursor_position.y + 1 < (int)m_lines.size()) m_cursor_position.y++;
else
return ui::EventResult::DidNotHandle;
recalculate_cursor_index();
update_cursor();
return ui::EventResult::DidHandle;
}
if (request.code == moon::K_LeftArrow)
{
if (m_cursor > 0) m_cursor--;
else
return ui::EventResult::DidNotHandle;
recalculate_cursor_position();
update_cursor();
return ui::EventResult::DidHandle;
}
if (request.code == moon::K_RightArrow)
{
if (m_cursor < m_data.size()) m_cursor++;
else
return ui::EventResult::DidNotHandle;
recalculate_cursor_position();
update_cursor();
return ui::EventResult::DidHandle;
}
if (request.code == moon::K_Backspace)
{
if (m_cursor == 0) return ui::EventResult::DidNotHandle;
m_cursor--;
delete_current_character();
TRY(recalculate_lines());
update_cursor();
return ui::EventResult::DidHandle;
}
if (request.letter != '\n' && iscntrl(request.letter)) return ui::EventResult::DidNotHandle;
if (m_cursor == m_data.size()) TRY(m_data.append_data((const u8*)&request.letter, 1));
else
TRY(insert_character(request.letter));
m_cursor++;
TRY(recalculate_lines());
update_cursor();
return ui::EventResult::DidHandle;
}
Result<void> EditorWidget::save_file_as()
{
ui::Dialog::show_input_dialog(
"Save file as...", "Please enter the path to save this file to:", [this](StringView path) {
m_path = String::from_string_view(path).release_value();
auto rc = save_file();
if (rc.has_error())
{
os::eprintln("Failed to save file %s: %s", m_path.chars(), rc.error_string());
ui::Dialog::show_message("Error", "Failed to save file");
}
else
{
auto basename = PathParser::basename(m_path.view()).release_value();
String title = String::format("Text Editor - %s"_sv, basename.chars()).release_value();
window()->set_title(title.view());
}
});
return {};
}
Result<void> EditorWidget::save_file()
{
if (m_path.is_empty())
{
TRY(save_file_as());
return {};
}
auto file = TRY(os::File::open_or_create(m_path.view(), os::File::WriteOnly));
return file->write(m_data);
}
Result<void> EditorWidget::draw(ui::Canvas& canvas)
{
int visible_lines = canvas.height / m_font->height();
int visible_columns = canvas.width / m_font->width();
if ((usize)visible_lines > m_lines.size()) visible_lines = static_cast<int>(m_lines.size());
for (int i = 0; i < visible_lines; i++)
{
auto line = m_lines[i];
if (line.begin == line.end) continue;
auto slice = TRY(m_data.slice(line.begin, line.end - line.begin));
auto string = TRY(
String::from_string_view(StringView::from_fixed_size_cstring((const char*)slice, line.end - line.begin)));
Utf8StringDecoder decoder(string.chars());
wchar_t buf[4096];
decoder.decode(buf, sizeof(buf)).release_value();
int characters_to_render = (int)wcslen(buf);
for (int j = 0; j < visible_columns && j < characters_to_render; j++)
{
auto subcanvas =
canvas.subcanvas({ j * m_font->width(), i * m_font->height(), m_font->width(), m_font->height() });
m_font->render(buf[j], ui::WHITE, subcanvas);
}
}
// Draw the cursor
if (m_cursor_position.x < visible_columns && m_cursor_position.y < visible_lines && m_cursor_activated)
{
canvas
.subcanvas(
{ m_cursor_position.x * m_font->width(), m_cursor_position.y * m_font->height(), 1, m_font->height() })
.fill(ui::WHITE);
}
return {};
}
Result<void> EditorWidget::recalculate_lines()
{
m_lines.clear();
Line l;
l.begin = 0;
for (usize i = 0; i < m_data.size(); i++)
{
if (m_data.data()[i] == '\n')
{
l.end = i;
TRY(m_lines.try_append(l));
l.begin = i + 1;
}
}
l.end = m_data.size();
TRY(m_lines.try_append(l));
recalculate_cursor_position();
return {};
}
void EditorWidget::recalculate_cursor_position()
{
if (m_cursor == 0) m_cursor_position = { 0, 0 };
for (int i = 0; i < (int)m_lines.size(); i++)
{
auto line = m_lines[i];
if (m_cursor >= line.begin && m_cursor <= line.end)
{
m_cursor_position.x = (int)(m_cursor - line.begin);
m_cursor_position.y = i;
return;
}
}
unreachable();
}
void EditorWidget::recalculate_cursor_index()
{
m_cursor = m_lines[m_cursor_position.y].begin + m_cursor_position.x;
if (m_cursor > m_lines[m_cursor_position.y].end)
{
m_cursor = m_lines[m_cursor_position.y].end;
recalculate_cursor_position();
}
}

View File

@ -0,0 +1,50 @@
/**
* @file EditorWidget.h
* @author apio (cloudapio.eu)
* @brief Multiline text editing widget.
*
* @copyright Copyright (c) 2024, the Luna authors.
*
*/
#include <luna/String.h>
#include <os/Timer.h>
#include <ui/Font.h>
#include <ui/TextInput.h>
#include <ui/Widget.h>
class EditorWidget : public ui::TextInput
{
public:
EditorWidget(SharedPtr<ui::Font> font);
Result<void> load_file(const os::Path& path);
Result<void> save_file();
Result<void> save_file_as();
Result<ui::EventResult> handle_key_event(const ui::KeyEventRequest& request) override;
Result<void> draw(ui::Canvas& canvas) override;
os::Path path()
{
return m_path.view();
}
private:
SharedPtr<ui::Font> m_font;
struct Line
{
usize begin;
usize end;
};
Vector<Line> m_lines;
String m_path;
Result<void> recalculate_lines();
void recalculate_cursor_position();
void recalculate_cursor_index();
};

53
gui/apps/editor/main.cpp Normal file
View File

@ -0,0 +1,53 @@
/**
* @file main.cpp
* @author apio (cloudapio.eu)
* @brief Graphical text editor.
*
* @copyright Copyright (c) 2024, the Luna authors.
*
*/
#include "EditorWidget.h"
#include <os/ArgumentParser.h>
#include <os/File.h>
#include <ui/App.h>
#include <ui/Dialog.h>
Result<int> luna_main(int argc, char** argv)
{
StringView path;
os::ArgumentParser parser;
parser.add_description("A graphical text editor"_sv);
parser.add_system_program_info("editor"_sv);
parser.add_positional_argument(path, "path", false);
parser.parse(argc, argv);
ui::App app;
TRY(app.init());
auto* window = TRY(ui::Window::create(ui::Rect { 200, 300, 600, 600 }));
window->set_background(ui::Color::from_rgb(40, 40, 40));
window->set_title("Text Editor");
app.set_main_window(window);
auto* editor = TRY(make<EditorWidget>(ui::Font::default_font()));
window->set_main_widget(*editor);
if (!path.is_empty()) editor->load_file(path);
TRY(window->add_keyboard_shortcut({ moon::K_CH26, ui::Mod_Ctrl }, true, [&](ui::Shortcut) {
auto result = editor->save_file();
if (result.has_error())
{
os::eprintln("Failed to save file %s: %s", editor->path().name().chars(), result.error_string());
ui::Dialog::show_message("Error", "Failed to save file");
}
}));
TRY(window->add_keyboard_shortcut({ moon::K_CH26, ui::Mod_Ctrl | ui::Mod_Shift }, true,
[&](ui::Shortcut) { editor->save_file_as(); }));
window->draw();
return app.run();
}

127
gui/apps/gol.cpp Normal file
View File

@ -0,0 +1,127 @@
#include <assert.h>
#include <fcntl.h>
#include <luna/Heap.h>
#include <os/ArgumentParser.h>
#include <os/Timer.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ui/App.h>
#include <ui/Window.h>
#include <unistd.h>
struct Cell
{
bool state;
bool new_state;
};
static int g_num_rows = 40;
static int g_num_columns = 60;
static Cell* g_cells;
static ui::Window* g_window;
static Result<void> fill_cells()
{
g_cells = (Cell*)TRY(calloc_impl(g_num_rows, g_num_columns * sizeof(Cell), false));
for (isize i = 0; i < (g_num_rows * g_num_columns); i++)
{
auto value = rand() % 2;
g_cells[i].state = g_cells[i].new_state = value;
}
return {};
}
static Cell& find_cell(int row, int column)
{
assert(row < g_num_rows);
assert(column < g_num_columns);
return g_cells[row * g_num_columns + column];
}
static constexpr int BYTES_PER_PIXEL = sizeof(u32);
static constexpr ui::Color activated_cell_color = ui::CYAN;
static constexpr ui::Color deactivated_cell_color = ui::Color::from_rgb(40, 40, 40);
static void draw_cells()
{
const int CELL_WIDTH = g_window->canvas().width / g_num_columns;
const int CELL_HEIGHT = g_window->canvas().height / g_num_rows;
auto canvas = g_window->canvas();
for (int i = 0; i < g_num_rows; i++)
{
for (int j = 0; j < g_num_columns; j++)
{
auto subcanvas = canvas.subcanvas(ui::Rect { j * CELL_WIDTH, i * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT });
auto& cell = find_cell(i, j);
ui::Color color = cell.state ? activated_cell_color : deactivated_cell_color;
subcanvas.fill(color);
}
}
g_window->update();
}
static int find_neighbors(int row, int column)
{
int sum = 0;
if (row > 0 && column > 0) sum += find_cell(row - 1, column - 1).state;
if (row > 0) sum += find_cell(row - 1, column).state;
if (row > 0 && (column + 1) < g_num_columns) sum += find_cell(row - 1, column + 1).state;
if (column > 0) sum += find_cell(row, column - 1).state;
if ((column + 1) < g_num_columns) sum += find_cell(row, column + 1).state;
if ((row + 1) < g_num_rows && column > 0) sum += find_cell(row + 1, column - 1).state;
if ((row + 1) < g_num_rows) sum += find_cell(row + 1, column).state;
if ((row + 1) < g_num_rows && (column + 1) < g_num_columns) sum += find_cell(row + 1, column + 1).state;
return sum;
}
static void next_generation()
{
for (int i = 0; i < g_num_rows; i++)
{
for (int j = 0; j < g_num_columns; j++)
{
auto& cell = find_cell(i, j);
int neighbors = find_neighbors(i, j);
if (!cell.state && neighbors == 3) cell.new_state = true;
else if (cell.state && (neighbors < 2 || neighbors > 3))
cell.new_state = false;
}
}
for (isize i = 0; i < (g_num_rows * g_num_columns); i++) g_cells[i].state = g_cells[i].new_state;
}
static void update()
{
next_generation();
draw_cells();
}
Result<int> luna_main(int, char**)
{
ui::App app;
TRY(app.init());
g_window = TRY(ui::Window::create(ui::Rect { 200, 200, 600, 400 }));
g_window->set_title("Game of Life");
app.set_main_window(g_window);
TRY(fill_cells());
update();
auto timer = TRY(os::Timer::create_repeating(100, update));
return app.run();
}

152
gui/apps/taskbar.cpp Normal file
View File

@ -0,0 +1,152 @@
#include <luna/Sort.h>
#include <luna/StringBuilder.h>
#include <os/Config.h>
#include <os/Directory.h>
#include <os/File.h>
#include <os/FileSystem.h>
#include <os/IPC.h>
#include <os/Process.h>
#include <os/ipc/Launcher.h>
#include <signal.h>
#include <sys/wait.h>
#include <ui/App.h>
#include <ui/Button.h>
#include <ui/Container.h>
#include <ui/Image.h>
#include <ui/Layout.h>
static constexpr ui::Color TASKBAR_COLOR = ui::Color::from_rgb(83, 83, 83);
static OwnedPtr<os::IPC::Client> launcher_client;
void sigquit_handler(int)
{
// Reload the taskbar by exec-ing the executable, resetting everything.
StringView args[] = { "/usr/bin/taskbar" };
os::Process::exec(args[0], { args, 1 });
}
Result<void> create_widget_group_for_app(ui::HorizontalLayout& layout, StringView path, StringView icon)
{
auto* button = TRY(make<ui::Button>(ui::Rect { 0, 0, 50, 50 }));
layout.add_widget(*button);
auto* container = TRY(
make<ui::Container>(ui::Rect { 0, 0, 50, 50 }, ui::VerticalAlignment::Center, ui::HorizontalAlignment::Center));
button->set_widget(*container);
button->set_action([=] {
os::Launcher::LaunchDetachedRequest request;
SET_IPC_STRING(request.command, path.chars());
launcher_client->send_async(request);
});
auto image = TRY(ui::ImageWidget::load(icon));
container->set_widget(*image);
image.leak();
return {};
}
struct ApplicationFile
{
String name;
String command;
String icon;
};
Vector<ApplicationFile> s_app_files;
// Pretty much copied from init.cpp.
static Result<void> load_application_file(const os::Path& path)
{
os::println("[taskbar] reading app file: %s", path.name().chars());
auto file = TRY(os::ConfigFile::open(path));
ApplicationFile app_file;
app_file.name = TRY(String::from_string_view(file->read_string_or("Name", "")));
if (app_file.name.is_empty())
{
os::println("[taskbar] app file is missing 'Name' entry, aborting!");
return {};
}
app_file.command = TRY(String::from_string_view(file->read_string_or("Command", "")));
if (app_file.command.is_empty())
{
os::println("[taskbar] app file is missing 'Command' entry, aborting!");
return {};
}
app_file.icon = TRY(String::from_string_view(file->read_string_or("Icon", "")));
if (app_file.icon.is_empty())
{
os::println("[taskbar] app file is missing 'Icon' entry, aborting!");
return {};
}
os::println("[taskbar] loaded app %s into memory", app_file.name.chars());
TRY(s_app_files.try_append(move(app_file)));
return {};
}
static Result<void> load_app_files_from_path(StringView path)
{
os::println("[taskbar] loading app files from %s", path.chars());
auto dir = TRY(os::Directory::open(path));
auto services = TRY(dir->list_names(os::Directory::Filter::ParentAndBase));
sort(services.begin(), services.end(), String::compare);
for (const auto& entry : services) TRY(load_application_file({ dir->fd(), entry.view() }));
return {};
}
Result<int> luna_main(int, char**)
{
ui::App app;
TRY(app.init("/tmp/wsys.sock"));
app.pledge(ui::Pledge::ExtendedLayers);
TRY(os::EventLoop::the().register_signal_handler(SIGQUIT, sigquit_handler));
launcher_client = TRY(os::IPC::Client::connect("/tmp/execd.sock", false));
ui::Rect screen = app.screen_rect();
ui::Rect bar = ui::Rect { ui::Point { 0, screen.height - 50 }, screen.width, 50 };
auto window = TRY(ui::Window::create(bar, ui::WindowType::System));
app.set_main_window(window);
window->set_background(TASKBAR_COLOR);
window->set_layer(ui::Layer::Background);
app.pledge(0);
ui::HorizontalLayout layout(ui::Margins { 0, 0, 0, 0 }, ui::AdjustHeight::Yes, ui::AdjustWidth::No);
window->set_main_widget(layout);
load_app_files_from_path("/usr/share/applications/");
auto home = TRY(os::FileSystem::home_directory());
StringBuilder sb;
TRY(sb.add(home.view()));
TRY(sb.add("/.applications/"_sv));
auto local_app_file_dir = TRY(sb.string());
load_app_files_from_path(local_app_file_dir.view());
for (const auto& app_file : s_app_files)
{
create_widget_group_for_app(layout, app_file.command.view(), app_file.icon.view());
}
return app.run();
}

View File

@ -0,0 +1,12 @@
set(SOURCES
main.cpp
TerminalWidget.h
TerminalWidget.cpp
)
add_executable(terminal ${SOURCES})
target_compile_options(terminal PRIVATE -Os ${COMMON_FLAGS} -Wno-write-strings)
add_dependencies(terminal libc)
target_include_directories(terminal PRIVATE ${LUNA_BASE}/usr/include ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(terminal PRIVATE os ui)
install(TARGETS terminal DESTINATION ${LUNA_BASE}/usr/bin)

View File

@ -0,0 +1,460 @@
#include "TerminalWidget.h"
#include <ctype.h>
#include <errno.h>
#include <luna/CType.h>
#include <os/File.h>
#include <os/Process.h>
#include <pty.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <time.h>
#include <ui/App.h>
#include <unistd.h>
static constexpr auto RED = ui::Color::from_u32(0xffcd0000);
static constexpr auto GREEN = ui::Color::from_u32(0xff00cd00);
static constexpr auto YELLOW = ui::Color::from_u32(0xffcdcd00);
static constexpr auto BLUE = ui::Color::from_u32(0xff0000ee);
static constexpr auto MAGENTA = ui::Color::from_u32(0xffcd00cd);
static constexpr auto CYAN = ui::Color::from_u32(0xff00cdcd);
static constexpr auto GRAY = ui::Color::from_u32(0xffe5e5e5);
static constexpr auto BRIGHT_BLACK = ui::Color::from_u32(0xff7f7f7f);
static constexpr auto BRIGHT_RED = ui::Color::from_u32(0xffff0000);
static constexpr auto BRIGHT_GREEN = ui::Color::from_u32(0xff00ff00);
static constexpr auto BRIGHT_YELLOW = ui::Color::from_u32(0xffffff00);
static constexpr auto BRIGHT_BLUE = ui::Color::from_u32(0xff5c5cff);
static constexpr auto BRIGHT_MAGENTA = ui::Color::from_u32(0xffff00ff);
static constexpr auto BRIGHT_CYAN = ui::Color::from_u32(0xff00ffff);
static constexpr auto BRIGHT_GRAY = ui::Color::from_u32(0xffffffff);
static void sigchld_handler(int)
{
wait(NULL);
ui::App::the().set_should_close(true);
}
Result<void> TerminalWidget::init(char* const* args)
{
m_font = ui::Font::default_font();
m_bold_font = ui::Font::default_bold_font();
m_terminal_canvas = window()->canvas();
m_terminal_canvas.fill(ui::BLACK);
m_cursor_timer = TRY(os::Timer::create_repeating(500, [this]() { this->tick_cursor(); }));
signal(SIGCHLD, sigchld_handler);
int master;
pid_t child = forkpty(&master, nullptr, nullptr, nullptr);
if (child < 0) return err(errno);
if (child == 0)
{
execv(args[0], args);
_exit(127);
}
m_pty = master;
os::EventLoop::the().register_fd_listener(m_pty, [this](int, int) { this->process(); });
m_child_pid = child;
return {};
}
Result<ui::EventResult> TerminalWidget::handle_key_event(const ui::KeyEventRequest& request)
{
// Avoid handling "key released" events
if (!request.pressed) return ui::EventResult::DidNotHandle;
// Non-printable key or key that has no special character (unlike Tab or Enter). We exit early to avoid inserting an
// invalid zero byte into the terminal input (this would also happen on Shift or Ctrl keypresses).
if (request.letter == '\0') return ui::EventResult::DidNotHandle;
write(m_pty, &request.letter, 1);
return ui::EventResult::DidHandle;
}
Result<void> TerminalWidget::draw(ui::Canvas&)
{
return {};
}
Result<void> TerminalWidget::process()
{
char buffer[BUFSIZ];
ssize_t nread = read(m_pty, buffer, BUFSIZ);
if (nread < 0)
{
if (errno == EAGAIN) nread = 0;
else
return err(errno);
}
ssize_t drawn = 0;
for (ssize_t i = 0; i < nread; i++)
{
bool did_draw = TRY(putchar(buffer[i]));
if (did_draw) drawn++;
}
if (drawn > 0) window()->draw();
return {};
}
void TerminalWidget::tick_cursor()
{
if (!m_cursor_enabled) return;
m_cursor_activated = !m_cursor_activated;
if (m_cursor_activated) draw_cursor();
else
erase_current_char();
window()->draw();
}
void TerminalWidget::draw_glyph(wchar_t c, int x, int y)
{
auto subcanvas = m_terminal_canvas.subcanvas({ x, y, m_font->width(), m_font->height() });
subcanvas.fill(m_background_color);
(m_bold ? m_bold_font : m_font)->render(c, m_foreground_color, subcanvas);
}
void TerminalWidget::erase_current_line()
{
m_terminal_canvas.subcanvas({ 0, m_y_position, m_rect.width, m_font->height() }).fill(ui::BLACK);
}
void TerminalWidget::scroll()
{
memcpy(m_terminal_canvas.ptr, m_terminal_canvas.ptr + (m_rect.width * sizeof(u32) * m_font->height()),
(m_rect.width * m_rect.height * sizeof(u32)) - (m_rect.width * sizeof(u32) * m_font->height()));
m_y_position -= m_font->height();
erase_current_line();
}
bool TerminalWidget::should_scroll()
{
return m_y_position >= m_rect.height;
}
void TerminalWidget::next_line()
{
m_x_position = 0;
m_y_position += m_font->height();
}
void TerminalWidget::next_char()
{
m_x_position += m_font->width();
}
void TerminalWidget::prev_char()
{
m_x_position -= m_font->width();
}
void TerminalWidget::erase_current_char()
{
m_terminal_canvas.subcanvas({ m_x_position, m_y_position, m_font->width(), m_font->height() }).fill(ui::BLACK);
}
void TerminalWidget::draw_cursor()
{
m_terminal_canvas.subcanvas({ m_x_position, m_y_position, m_font->width(), m_font->height() }).fill(ui::WHITE);
}
bool TerminalWidget::at_end_of_screen()
{
return (m_x_position + m_font->width()) > m_rect.width;
}
bool TerminalWidget::handle_escape_sequence(wchar_t c)
{
auto rc = m_escape_parser->advance(static_cast<u8>(c));
if (rc.has_error())
{
m_escape_parser = Option<EscapeSequenceParser> {};
return false;
}
if (!rc.value()) return true;
if (!m_escape_parser->valid())
{
m_escape_parser = Option<EscapeSequenceParser> {};
return false;
}
const auto& params = m_escape_parser->parameters();
switch (m_escape_parser->code())
{
case EscapeCode::CursorUp: {
int lines = params.size() ? params[0] : 1;
int pixels = lines * m_font->height();
if (pixels > m_y_position) m_y_position = 0;
else
m_y_position -= pixels;
};
break;
case EscapeCode::CursorDown: {
int lines = params.size() ? params[0] : 1;
int pixels = lines * m_font->height();
if (pixels + m_y_position >= m_rect.height) m_y_position = m_rect.height - m_font->height();
else
m_y_position += pixels;
};
break;
case EscapeCode::CursorBack: {
int chars = params.size() ? params[0] : 1;
int pixels = chars * m_font->width();
if (pixels > m_x_position) m_x_position = 0;
else
m_x_position -= pixels;
};
break;
case EscapeCode::CursorForward: {
int chars = params.size() ? params[0] : 1;
int pixels = chars * m_font->width();
if (pixels + m_x_position >= m_rect.width) m_x_position = m_rect.width - m_font->width();
else
m_x_position += pixels;
};
break;
case EscapeCode::CursorNextLine: {
int lines = params.size() ? params[0] : 1;
int pixels = lines * m_font->height();
if (pixels > m_y_position) m_y_position = 0;
else
m_y_position -= pixels;
m_x_position = 0;
};
break;
case EscapeCode::CursorPreviousLine: {
int lines = params.size() ? params[0] : 1;
int pixels = lines * m_font->height();
if (pixels + m_y_position >= m_rect.height) m_y_position = m_rect.height - m_font->height();
else
m_y_position += pixels;
m_x_position = 0;
};
break;
case EscapeCode::CursorHorizontalAbsolute: {
int line = (params.size() ? params[0] : 1) - 1;
if (line < 0) break;
int position = line * m_font->height();
if (position >= m_rect.height) position = m_rect.height - m_font->height();
m_y_position = position;
};
break;
case EscapeCode::SetCursorPosition: {
int x = (params.size() ? params[0] : 1) - 1;
int y = (params.size() > 1 ? params[1] : 1) - 1;
if (x < 0 || y < 0) break;
int x_position = x * m_font->width();
if (x_position >= m_rect.width) x_position = m_rect.width - m_font->height();
m_x_position = x_position;
int y_position = y * m_font->height();
if (y_position >= m_rect.height) y_position = m_rect.height - m_font->height();
m_y_position = y_position;
};
break;
case EscapeCode::SelectGraphicRendition: {
if (!params.size())
{
m_foreground_color = ui::WHITE;
m_background_color = ui::BLACK;
m_bold = false;
break;
}
for (usize i = 0; i < params.size(); i++)
{
int arg = params[i];
switch (arg)
{
case 0: {
m_foreground_color = ui::BLACK;
m_background_color = ui::WHITE;
m_bold = false;
break;
}
case 1: {
m_bold = true;
break;
}
case 22: {
m_bold = false;
break;
}
case 30: {
m_foreground_color = m_bold ? BRIGHT_BLACK : ui::BLACK;
break;
}
case 31: {
m_foreground_color = m_bold ? BRIGHT_RED : RED;
break;
}
case 32: {
m_foreground_color = m_bold ? BRIGHT_GREEN : GREEN;
break;
}
case 33: {
m_foreground_color = m_bold ? BRIGHT_YELLOW : YELLOW;
break;
}
case 34: {
m_foreground_color = m_bold ? BRIGHT_BLUE : BLUE;
break;
}
case 35: {
m_foreground_color = m_bold ? BRIGHT_MAGENTA : MAGENTA;
break;
}
case 36: {
m_foreground_color = m_bold ? BRIGHT_CYAN : CYAN;
break;
}
case 37: {
m_foreground_color = m_bold ? BRIGHT_GRAY : GRAY;
break;
}
case 39: {
m_foreground_color = ui::WHITE;
break;
}
case 40: {
m_background_color = m_bold ? BRIGHT_BLACK : ui::BLACK;
break;
}
case 41: {
m_background_color = m_bold ? BRIGHT_RED : RED;
break;
}
case 42: {
m_background_color = m_bold ? BRIGHT_GREEN : GREEN;
break;
}
case 43: {
m_background_color = m_bold ? BRIGHT_YELLOW : YELLOW;
break;
}
case 44: {
m_background_color = m_bold ? BRIGHT_BLUE : BLUE;
break;
}
case 45: {
m_background_color = m_bold ? BRIGHT_MAGENTA : MAGENTA;
break;
}
case 46: {
m_background_color = m_bold ? BRIGHT_CYAN : CYAN;
break;
}
case 47: {
m_background_color = m_bold ? BRIGHT_GRAY : GRAY;
break;
}
case 49: {
m_background_color = ui::BLACK;
break;
}
default: break;
}
}
}
break;
default: break;
}
m_escape_parser = Option<EscapeSequenceParser> {};
return true;
}
Result<bool> TerminalWidget::putchar(char c)
{
auto guard = make_scope_guard([this] { m_decoder.reset(); });
bool is_ready = TRY(m_decoder.feed(c));
bool result = false;
if (is_ready) result = put_code_point(TRY(m_decoder.extract()));
guard.deactivate();
return result;
}
bool TerminalWidget::put_code_point(wchar_t c)
{
if (c > (wchar_t)255) c = (wchar_t)256;
if (m_escape_parser.has_value())
{
if (handle_escape_sequence(c)) return false;
}
// Erase the current cursor.
if (m_cursor_activated) erase_current_char();
bool should_draw_cursor = m_cursor_enabled;
bool did_draw = false;
switch (c)
{
case L'\n': {
next_line();
if (should_scroll()) scroll();
break;
}
case L'\t': {
for (int i = 0; i < 4; i++) { put_code_point(L' '); }
did_draw = true;
break;
}
case L'\r': m_x_position = 0; break;
case L'\b':
if (m_x_position != 0)
{
prev_char();
erase_current_char();
did_draw = true;
}
break;
case L'\x1b':
case L'\x9b':
case L'\x90':
case L'\x9d':
m_escape_parser = EscapeSequenceParser { (u8)c };
should_draw_cursor = false;
did_draw = true;
break;
default: {
if (iscntrl(c)) return false;
draw_glyph(c, m_x_position, m_y_position);
next_char();
if (at_end_of_screen())
{
next_line();
if (should_scroll()) scroll();
}
break;
}
}
if (should_draw_cursor)
{
m_cursor_timer->restart();
m_cursor_activated = true;
draw_cursor();
}
return did_draw;
}

View File

@ -0,0 +1,64 @@
#pragma once
#include <luna/EscapeSequence.h>
#include <luna/Utf8.h>
#include <luna/Vector.h>
#include <os/Timer.h>
#include <stdio.h>
#include <termios.h>
#include <ui/Font.h>
#include <ui/Widget.h>
class TerminalWidget : public ui::Widget
{
public:
Result<void> init(char* const* args);
Result<ui::EventResult> handle_key_event(const ui::KeyEventRequest& request) override;
Result<void> draw(ui::Canvas& canvas) override;
private:
ui::Canvas m_terminal_canvas;
Vector<u8> m_line_buffer;
int m_pty;
pid_t m_child_pid;
struct termios m_settings;
SharedPtr<ui::Font> m_font;
SharedPtr<ui::Font> m_bold_font;
OwnedPtr<os::Timer> m_cursor_timer;
bool m_cursor_activated = false;
bool m_cursor_enabled = true;
long m_last_cursor_tick;
int m_x_position { 0 };
int m_y_position { 0 };
bool m_bold { false };
ui::Color m_foreground_color { ui::WHITE };
ui::Color m_background_color { ui::BLACK };
void tick_cursor();
Utf8StateDecoder m_decoder;
Option<EscapeSequenceParser> m_escape_parser;
void draw_glyph(wchar_t c, int x, int y);
void erase_current_line();
void scroll();
bool should_scroll();
void next_line();
void next_char();
void prev_char();
void erase_current_char();
void draw_cursor();
bool at_end_of_screen();
bool handle_escape_sequence(wchar_t c);
Result<bool> putchar(char c);
bool put_code_point(wchar_t c);
Result<void> process();
};

View File

@ -0,0 +1,24 @@
#include "TerminalWidget.h"
#include <os/ArgumentParser.h>
#include <ui/App.h>
#include <unistd.h>
Result<int> luna_main(int, char**)
{
ui::App app;
TRY(app.init());
auto* window = TRY(ui::Window::create(ui::Rect { 150, 150, 640, 400 }));
app.set_main_window(window);
window->set_title("Terminal");
TerminalWidget terminal;
window->set_main_widget(terminal);
char* args[] = { "/bin/sh", nullptr };
TRY(terminal.init(args));
window->draw();
return app.run();
}

109
gui/execd.cpp Normal file
View File

@ -0,0 +1,109 @@
/**
* @file execd.cpp
* @author apio (cloudapio.eu)
* @brief Background process that handles detached launching of apps.
*
* @copyright Copyright (c) 2024, the Luna authors.
*
*/
#include <errno.h>
#include <os/ArgumentParser.h>
#include <os/File.h>
#include <os/IPC.h>
#include <os/LocalServer.h>
#include <os/Process.h>
#include <os/Security.h>
#include <os/ipc/Launcher.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
Result<void> handle_launch_detached_message(os::IPC::ClientConnection& client)
{
os::Launcher::LaunchDetachedRequest request;
if (!TRY(client.read_message(request))) return {};
auto path = COPY_IPC_STRING(request.command);
StringView args[] = { path.view() };
os::Process::spawn(args[0], { args, 1 }, request.search_in_path);
return {};
}
void handle_ipc_message(os::IPC::ClientConnection& client, u8 id, void*)
{
switch (id)
{
case os::Launcher::LAUNCH_DETACHED_ID: handle_launch_detached_message(client); break;
default: os::eprintln("execd: Invalid IPC message from client!"); return;
}
}
void sigchld_handler(int)
{
os::Process::wait(os::Process::ANY_CHILD, nullptr, WNOHANG);
}
Result<int> luna_main(int argc, char** argv)
{
TRY(os::Security::pledge("stdio wpath cpath unix proc exec", NULL));
StringView socket_path = "/tmp/execd.sock";
os::ArgumentParser parser;
parser.add_description("Background process that handles detached launching of apps."_sv);
parser.add_system_program_info("execd"_sv);
parser.parse(argc, argv);
signal(SIGCHLD, sigchld_handler);
auto server = TRY(os::LocalServer::create(socket_path, false));
TRY(server->listen(20));
// We're ready now.
os::IPC::notify_parent();
Vector<OwnedPtr<os::IPC::ClientConnection>> clients;
Vector<struct pollfd> fds;
TRY(fds.try_append({ .fd = server->fd(), .events = POLLIN, .revents = 0 }));
TRY(os::Security::pledge("stdio unix proc exec", NULL));
while (1)
{
for (auto& pfd : fds) { pfd.revents = 0; }
int rc = poll(fds.data(), fds.size(), 1000);
if (!rc) continue;
if (rc < 0 && errno != EINTR) { os::println("poll: error: %s", strerror(errno)); }
if (fds[0].revents & POLLIN)
{
auto client = TRY(server->accept());
os::println("execd: New client connected!");
TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 }));
auto connection = TRY(os::IPC::ClientConnection::adopt_connection(move(client)));
connection->set_message_handler(handle_ipc_message, nullptr);
TRY(clients.try_append(move(connection)));
}
for (usize i = 0; i < clients.size(); i++)
{
if (fds[i + 1].revents & POLLIN) clients[i]->check_for_messages();
if (fds[i + 1].revents & POLLHUP)
{
os::println("execd: Client %zu disconnected", i);
fds.remove_at(i + 1);
auto client = clients.remove_at(i);
client->disconnect();
}
}
}
}

34
gui/libui/CMakeLists.txt Normal file
View File

@ -0,0 +1,34 @@
# The UI and graphics library for Luna.
file(GLOB HEADERS include/ui/*.h)
set(SOURCES
${HEADERS}
include/ui/ipc/Server.h
include/ui/ipc/Client.h
src/Canvas.cpp
src/Rect.cpp
src/Font.cpp
src/Image.cpp
src/App.cpp
src/Window.cpp
src/Layout.cpp
src/Alignment.cpp
src/Container.cpp
src/Button.cpp
src/Label.cpp
src/InputField.cpp
src/TextInput.cpp
src/Dialog.cpp
)
add_library(ui ${SOURCES})
target_compile_options(ui PRIVATE ${COMMON_FLAGS} -fno-threadsafe-statics)
target_include_directories(ui PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/)
target_include_directories(ui PUBLIC ${LUNA_BASE}/usr/include)
target_link_libraries(ui PUBLIC os)
add_custom_command(
TARGET ui
COMMAND "${CMAKE_COMMAND}" -E copy ${CMAKE_CURRENT_BINARY_DIR}/libui.a ${LUNA_BASE}/usr/lib/libui.a
)

View File

@ -0,0 +1,30 @@
/**
* @file Alignment.h
* @author apio (cloudapio.eu)
* @brief UI component alignment.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <ui/Rect.h>
namespace ui
{
enum class VerticalAlignment
{
Top,
Center,
Bottom
};
enum class HorizontalAlignment
{
Left,
Center,
Right
};
Rect align(Rect container, Rect contained, VerticalAlignment valign, HorizontalAlignment halign);
}

View File

@ -0,0 +1,76 @@
/**
* @file App.h
* @author apio (cloudapio.eu)
* @brief UI application event loop.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/HashMap.h>
#include <luna/StringView.h>
#include <os/EventLoop.h>
#include <os/IPC.h>
#include <ui/Window.h>
namespace ui
{
class App
{
public:
App();
~App();
Result<void> init(StringView socket_path = "/tmp/wind.sock");
Result<int> run();
Rect screen_rect();
os::IPC::Client& client()
{
return *m_client;
}
void set_should_close(bool b)
{
m_should_close = b;
if (b) m_loop.quit();
}
void set_main_window(Window* window)
{
check(!m_main_window);
m_main_window = window;
}
Window* main_window()
{
return m_main_window;
}
void pledge(i16 pledges);
Result<void> register_window(OwnedPtr<Window>&& window, Badge<Window>);
void unregister_window(Window* window, Badge<Window>);
static App& the();
private:
static App* s_app;
OwnedPtr<os::IPC::Client> m_client;
Window* m_main_window { nullptr };
HashMap<int, OwnedPtr<Window>> m_windows;
bool m_should_close { false };
os::EventLoop m_loop;
Vector<int> m_window_clear_queue;
bool process_events();
Window* find_window(int id);
Result<void> handle_ipc_event(os::IPC::Client&, u8 id, void*);
friend void handle_socket_event(int, int);
};
}

View File

@ -0,0 +1,37 @@
/**
* @file Button.h
* @author apio (cloudapio.eu)
* @brief A clickable component that triggers an action when pressed.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/Action.h>
#include <ui/Widget.h>
namespace ui
{
class Button : public Widget
{
public:
Button(Rect rect);
void set_widget(Widget& widget);
void set_action(Action&& action);
Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<EventResult> handle_key_event(const ui::KeyEventRequest& request) override;
Result<void> draw(Canvas& canvas) override;
private:
bool m_hovered { false };
bool m_clicked { false };
Widget* m_child;
Action m_action;
};
}

View File

@ -0,0 +1,81 @@
/**
* @file Canvas.h
* @author apio (cloudapio.eu)
* @brief Drawable surfaces.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/Result.h>
#include <luna/Types.h>
#include <ui/Color.h>
#include <ui/Point.h>
#include <ui/Rect.h>
namespace ui
{
/**
* @brief A drawable surface.
*/
struct Canvas
{
int width;
int height;
int stride;
u8* ptr;
/**
* @brief Create a new Canvas object.
*
* @param ptr The memory to use for the canvas. It must be of at least width * height * 4 bytes of length.
* @param width The width of the canvas.
* @param height The height of the canvas.
* @return Canvas The new Canvas object.
*/
static Canvas create(u8* ptr, int width, int height);
/**
* @brief Return a new Canvas that represents a subsection of the current one.
*
* @param rect The dimensions of the new canvas. If these exceed the bounds of the current canvas, they will be
* clamped.
* @return Canvas The new Canvas object.
*/
Canvas subcanvas(Rect rect);
/**
* @brief Return the dimensions of the current canvas.
*
* @return Rect This canvas's dimensions, as a Rect object.
*/
Rect rect()
{
return Rect { .pos = { 0, 0 }, .width = width, .height = height };
}
/**
* @brief Fill the entire canvas with one color.
*
* @param color The color to use.
*/
void fill(Color color);
/**
* @brief Fill the canvas with pixels.
*
* @param pixels The array of pixels (must be at least width*height).
* @param stride The number of pixels to skip to go to the next line.
*/
void fill(u32* pixels, int stride);
/**
* @brief Fill the canvas with pixels, without doing any extra processing.
*
* @param pixels The array of pixels (must be at least width*height).
* @param stride The number of pixels to skip to go to the next line.
*/
void copy(u32* pixels, int stride);
};
};

View File

@ -0,0 +1,113 @@
/**
* @file Color.h
* @author apio (cloudapio.eu)
* @brief RGBA colors.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/Types.h>
namespace ui
{
/**
* @brief A 32-bit ARGB color.
*/
struct Color
{
union {
u32 raw;
u8 colors[4];
};
/**
* @brief Return the blue value of this color.
*
* @return constexpr u8 The blue value.
*/
constexpr u8 red() const
{
return colors[2];
}
/**
* @brief Return the green value of this color.
*
* @return constexpr u8 The green value.
*/
constexpr u8 green() const
{
return colors[1];
}
/**
* @brief Return the blue value of this color.
*
* @return constexpr u8 The blue value.
*/
constexpr u8 blue() const
{
return colors[0];
}
/**
* @brief Return the alpha value of this color.
*
* @return constexpr u8 The alpha value.
*/
constexpr u8 alpha() const
{
return colors[3];
}
/**
* @brief Construct a new color from a 32-bit ARGB integer.
*
* @param raw The integer representing the color.
* @return constexpr Color The new color.
*/
static constexpr Color from_u32(u32 raw)
{
return Color { .raw = raw };
}
/**
* @brief Construct a new color from its separate RGBA values (from 0 to 255).
*
* @param red The red value.
* @param green The green value.
* @param blue The blue value.
* @param alpha The alpha value.
* @return constexpr Color The new color.
*/
static constexpr Color from_rgba(u8 red, u8 green, u8 blue, u8 alpha)
{
return Color { .colors = { blue, green, red, alpha } };
}
/**
* @brief Construct a new color from its separate RGB values (from 0 to 255).
*
* @param red The red value.
* @param green The green value.
* @param blue The blue value.
* @return constexpr Color The new color.
*/
static constexpr Color from_rgb(u8 red, u8 green, u8 blue)
{
return from_rgba(red, green, blue, 0xff);
}
};
static constexpr Color WHITE = Color::from_rgb(0xff, 0xff, 0xff);
static constexpr Color BLACK = Color::from_rgb(0x00, 0x00, 0x00);
static constexpr Color GRAY = Color::from_rgb(0x80, 0x80, 0x80);
static constexpr Color BLUE = Color::from_rgb(0x00, 0x00, 0xff);
static constexpr Color GREEN = Color::from_rgb(0x00, 0xff, 0x00);
static constexpr Color RED = Color::from_rgb(0xff, 0x00, 0x00);
static constexpr Color CYAN = Color::from_rgb(0x00, 0xff, 0xff);
};

View File

@ -0,0 +1,35 @@
/**
* @file Container.h
* @author apio (cloudapio.eu)
* @brief A container widget to pad and align objects inside it.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <ui/Alignment.h>
#include <ui/Widget.h>
namespace ui
{
class Container : public Widget
{
public:
Container(Rect rect, VerticalAlignment valign, HorizontalAlignment halign);
void set_widget(Widget& widget);
Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<EventResult> handle_key_event(const ui::KeyEventRequest& request) override;
Result<void> draw(Canvas& canvas) override;
private:
Widget* m_widget;
VerticalAlignment m_valign;
HorizontalAlignment m_halign;
};
}

View File

@ -0,0 +1,22 @@
/**
* @file Window.h
* @author apio (cloudapio.eu)
* @brief UI window dialogs.
*
* @copyright Copyright (c) 2024, the Luna authors.
*
*/
#pragma once
#include <luna/Action.h>
#include <ui/Window.h>
namespace ui
{
namespace Dialog
{
Result<void> show_message(StringView title, StringView message);
Result<void> show_input_dialog(StringView title, StringView message, Function<StringView> callback);
}
}

123
gui/libui/include/ui/Font.h Normal file
View File

@ -0,0 +1,123 @@
/**
* @file Font.h
* @author apio (cloudapio.eu)
* @brief PSF font loading and rendering.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/Buffer.h>
#include <luna/SharedPtr.h>
#include <os/Path.h>
#include <ui/Canvas.h>
#define PSF_FONT_MAGIC 0x864ab572
namespace ui
{
/**
* @brief A class holding PSF font data, used for low-level direct rendering of glyphs into a canvas.
*
* This class does not handle special characters such as tabs or newlines. For those, you should be using a more
* high-level component such as ui::Label instead.
*/
class Font : public Shareable
{
public:
/**
* @brief An enum used to select a font weight when loading a font.
*/
enum FontWeight
{
Regular,
Bold,
};
/**
* @brief Load a Font object from a font file.
*
* @param path The full path to the font file.
* @return Result<SharedPtr<Font>> An error, or the loaded Font object.
*/
static Result<SharedPtr<Font>> load(const os::Path& path);
/**
* @brief Load a system font by name.
*
* @param name The name of the font to load (the default system font is "Tamsyn").
* @param weight The weight of the font (regular or bold).
* @return Result<SharedPtr<Font>> An error, or the loaded Font object.
*/
static Result<SharedPtr<Font>> load_builtin(StringView name, FontWeight weight);
/**
* @brief Return a pointer to the system's default font.
*
* @return SharedPtr<Font> The default font.
*/
static SharedPtr<Font> default_font();
/**
* @brief Return a pointer to the system's default bold font.
*
* @return SharedPtr<Font> The default bold font.
*/
static SharedPtr<Font> default_bold_font();
/**
* @brief Render a single Unicode code point onto a canvas, using this font's glyphs.
*
* @param codepoint The code point to render.
* @param color The color to draw the code point in.
* @param canvas The canvas to use.
*/
void render(wchar_t codepoint, ui::Color color, ui::Canvas& canvas);
/**
* @brief Render a Unicode text string onto a canvas, using this font's glyphs.
*
* @param text The string to render (must be null-terminated).
* @param color The color to draw the code point in.
* @param canvas The canvas to use.
*/
void render(const wchar_t* text, ui::Color color, ui::Canvas& canvas);
/**
* @brief Return the width of this font's glyphs.
*
* @return int The width.
*/
int width() const
{
return m_psf_header.width;
}
/**
* @brief Return the height of this font's glyphs.
*
* @return int The height.
*/
int height() const
{
return m_psf_header.height;
}
private:
struct PSFHeader
{
u32 magic;
u32 version; // zero
u32 headersize;
u32 flags; // 0 if there's no unicode table
u32 numglyph;
u32 bytesperglyph;
int height;
int width;
};
PSFHeader m_psf_header;
Buffer m_font_data;
};
};

View File

@ -0,0 +1,92 @@
/**
* @file Image.h
* @author apio (cloudapio.eu)
* @brief TGA image loading and rendering.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/Buffer.h>
#include <luna/SharedPtr.h>
#include <os/Path.h>
#include <ui/Widget.h>
namespace ui
{
/**
* @brief An image in the TGA file format.
*/
class Image : public Shareable
{
public:
/**
* @brief Load a new TGA image from a file.
*
* @param path The path to open.
* @return Result<SharedPtr<Image>> An error, or a new Image object.
*/
static Result<SharedPtr<Image>> load(const os::Path& path);
/**
* @brief Return the array of pixels contained in the image.
*
* @return u32* The array of pixels.
*/
u32* pixels()
{
return (u32*)m_image_data.data();
}
/**
* @brief Return the width of the image.
*
* @return u16 The width.
*/
u16 width()
{
return m_tga_header.w;
}
/**
* @brief Return the height of the image.
*
* @return u16 The height.
*/
u16 height()
{
return m_tga_header.h;
}
private:
struct [[gnu::packed]] TGAHeader
{
u8 idlen;
u8 colormap;
u8 encoding;
u16 cmaporig, cmaplen;
u8 cmapent;
u16 x;
u16 y;
u16 w;
u16 h;
u8 bpp;
u8 pixeltype;
};
TGAHeader m_tga_header;
Buffer m_image_data;
};
class ImageWidget final : public Widget
{
public:
static Result<OwnedPtr<ImageWidget>> load(const os::Path& path);
Result<void> draw(Canvas& canvas) override;
private:
SharedPtr<Image> m_image;
};
}

View File

@ -0,0 +1,42 @@
/**
* @file InputField.h
* @author apio (cloudapio.eu)
* @brief Single line text input widget.
*
* @copyright Copyright (c) 2024, the Luna authors.
*
*/
#pragma once
#include <luna/Action.h>
#include <ui/Font.h>
#include <ui/TextInput.h>
namespace ui
{
class InputField final : public ui::TextInput
{
public:
InputField(SharedPtr<ui::Font> font);
Result<ui::EventResult> handle_key_event(const ui::KeyEventRequest& request) override;
Result<void> draw(ui::Canvas& canvas) override;
void clear();
StringView data();
void on_submit(Function<StringView>&& action)
{
m_on_submit_action = move(action);
m_has_on_submit_action = true;
}
private:
SharedPtr<ui::Font> m_font;
Function<StringView> m_on_submit_action;
bool m_has_on_submit_action { false };
};
}

View File

@ -0,0 +1,14 @@
#pragma once
#include <moon/Keyboard.h>
namespace ui
{
enum Modifier
{
Mod_Shift = (1 << 0),
Mod_Alt = (1 << 1),
Mod_Super = (1 << 2),
Mod_AltGr = (1 << 3),
Mod_Ctrl = (1 << 4)
};
}

View File

@ -0,0 +1,57 @@
/**
* @file Label.h
* @author apio (cloudapio.eu)
* @brief A simple one-line text widget.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <ui/Alignment.h>
#include <ui/Font.h>
#include <ui/Widget.h>
namespace ui
{
/**
* @brief Displays one line of text.
*
* This component does not handle newlines.
*/
class Label final : public Widget
{
public:
Label(StringView text);
void set_alignment(VerticalAlignment valign, HorizontalAlignment halign)
{
m_valign = valign;
m_halign = halign;
}
void set_color(ui::Color color)
{
m_color = color;
}
void set_font(SharedPtr<ui::Font> font)
{
m_font = font;
}
void set_text(StringView text)
{
m_text = text;
}
Result<void> draw(Canvas& canvas) override;
private:
StringView m_text;
VerticalAlignment m_valign = VerticalAlignment::Center;
HorizontalAlignment m_halign = HorizontalAlignment::Center;
ui::Color m_color = ui::WHITE;
SharedPtr<Font> m_font;
};
}

View File

@ -0,0 +1,83 @@
/**
* @file Layout.h
* @author apio (cloudapio.eu)
* @brief Layout widgets to organize content.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/Vector.h>
#include <ui/Widget.h>
namespace ui
{
enum class AdjustHeight
{
No,
Yes
};
enum class AdjustWidth
{
No,
Yes
};
struct Margins
{
int left;
int right;
int top;
int bottom;
};
class HorizontalLayout final : public Widget
{
public:
HorizontalLayout(Margins margins = Margins { 0, 0, 0, 0 }, AdjustHeight adjust_height = AdjustHeight::Yes,
AdjustWidth adjust_width = AdjustWidth::Yes);
Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<EventResult> handle_key_event(const ui::KeyEventRequest& request) override;
Result<void> draw(Canvas& canvas) override;
Result<void> add_widget(Widget& widget);
private:
Vector<Widget*> m_widgets;
Margins m_margins;
AdjustHeight m_adjust_height;
AdjustWidth m_adjust_width;
int m_used_width { 0 };
};
class VerticalLayout final : public Widget
{
public:
VerticalLayout(Margins margins = Margins { 0, 0, 0, 0 }, AdjustHeight adjust_height = AdjustHeight::Yes,
AdjustWidth adjust_width = AdjustWidth::Yes);
Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<EventResult> handle_key_event(const ui::KeyEventRequest& request) override;
Result<void> draw(Canvas& canvas) override;
Result<void> add_widget(Widget& widget);
private:
Vector<Widget*> m_widgets;
Margins m_margins;
AdjustHeight m_adjust_height;
AdjustWidth m_adjust_width;
int m_used_height { 0 };
};
}

View File

@ -0,0 +1,21 @@
/**
* @file Mouse.h
* @author apio (cloudapio.eu)
* @brief Mouse buttons.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <moon/Mouse.h>
namespace ui
{
enum MouseButtons
{
LEFT = moon::Left,
MIDDLE = moon::Middle,
RIGHT = moon::Right,
};
}

View File

@ -0,0 +1,22 @@
/**
* @file Point.h
* @author apio (cloudapio.eu)
* @brief 2D space points.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
namespace ui
{
/**
* @brief A point in 2D space.
*/
struct Point
{
int x { 0 };
int y { 0 };
};
}

View File

@ -0,0 +1,81 @@
/**
* @file Rect.h
* @author apio (cloudapio.eu)
* @brief A simple 2D rectangle representation.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <ui/Point.h>
namespace ui
{
/**
* @brief A simple rectangle.
*/
struct Rect
{
Point pos;
int width;
int height;
/**
* @brief Check if a point is contained in this rectangle.
*
* @param point The point to check.
* @return true The point is contained inside the rectangle.
* @return false The point is not contained inside the rectangle.
*/
bool contains(Point point);
/**
* @brief Check if another rectangle is contained in this one.
*
* @param point The rectangle to check.
* @return true The other rectangle is contained inside this one.
* @return false The other rectangle is not contained inside this one.
*/
bool contains(Rect rect);
/**
* @brief Normalize a point to fit inside this rectangle.
*
* @param point The original point.
* @return Point The normalized point.
*/
Point normalize(Point point);
/**
* @brief Transform an absolute position to a position relative to this rectangle.
*
* @param pos The original absolute position.
* @return Point The position relative to this rectangle.
*/
Point relative(Point pos);
/**
* @brief Transform a position relative to this rectangle to an absolute position.
*
* @param pos The original relative position.
* @return Point The absolute position.
*/
Point absolute(Point pos);
/**
* @brief Transform another rectangle relative to this one to an absolute rectangle.
*
* @param rect The original relative rectangle.
* @return Point The absolute rectangle.
*/
Rect absolute(Rect rect);
/**
* @brief Return a copy of this rectangle with no negative values (normalized to 0).
*
* @return Rect The new rectangle.
*/
Rect normalized();
};
}

View File

@ -0,0 +1,41 @@
/**
* @file TextInput.h
* @author apio (cloudapio.eu)
* @brief Base class for text inputs.
*
* @copyright Copyright (c) 2024, the Luna authors.
*
*/
#pragma once
#include <luna/Buffer.h>
#include <os/Timer.h>
#include <ui/Widget.h>
namespace ui
{
class TextInput : public Widget
{
public:
TextInput();
virtual Result<ui::EventResult> handle_key_event(const ui::KeyEventRequest& request) = 0;
virtual Result<void> draw(ui::Canvas& canvas) = 0;
protected:
Buffer m_data;
usize m_cursor { 0 };
ui::Point m_cursor_position { 0, 0 };
OwnedPtr<os::Timer> m_cursor_timer;
bool m_cursor_activated = true;
void tick_cursor();
void update_cursor();
Result<void> delete_current_character();
Result<void> insert_character(char c);
};
}

View File

@ -0,0 +1,94 @@
/**
* @file Widget.h
* @author apio (cloudapio.eu)
* @brief Abstract widget class.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/Ignore.h>
#include <luna/Result.h>
#include <ui/Canvas.h>
#include <ui/Point.h>
#include <ui/Rect.h>
#include <ui/ipc/Client.h>
namespace ui
{
class Window;
enum class EventResult
{
DidHandle,
DidNotHandle,
};
class Widget
{
public:
virtual Result<EventResult> handle_mouse_move(Point position)
{
ignore(position);
return EventResult::DidNotHandle;
}
virtual Result<EventResult> handle_mouse_down(Point position, int buttons)
{
ignore(position, buttons);
return EventResult::DidNotHandle;
}
virtual Result<EventResult> handle_mouse_up(Point position, int buttons)
{
ignore(position, buttons);
return EventResult::DidNotHandle;
}
virtual Result<EventResult> handle_mouse_leave()
{
return EventResult::DidNotHandle;
}
virtual Result<EventResult> handle_key_event(const ui::KeyEventRequest& request)
{
ignore(request);
return EventResult::DidNotHandle;
}
virtual Result<void> draw(Canvas& canvas);
void set_window(Window* window, Rect rect, Badge<Window>)
{
m_window = window;
m_rect = rect;
}
void set_parent(Widget* parent)
{
m_parent = parent;
m_window = parent->m_window;
}
Widget* parent()
{
return m_parent;
}
Window* window()
{
return m_window;
}
Rect& rect()
{
return m_rect;
}
protected:
Widget* m_parent { nullptr };
Window* m_window;
Rect m_rect { 0, 0, 50, 50 };
};
}

View File

@ -0,0 +1,115 @@
/**
* @file Window.h
* @author apio (cloudapio.eu)
* @brief UI windows.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <luna/OwnedPtr.h>
#include <luna/String.h>
#include <luna/StringView.h>
#include <ui/Canvas.h>
#include <ui/Mouse.h>
#include <ui/Rect.h>
#include <ui/Widget.h>
#include <ui/ipc/Server.h>
namespace ui
{
enum class WindowType : u8
{
Normal,
NotDecorated,
System,
};
struct [[gnu::packed]] Shortcut
{
moon::KeyCode key;
int modifiers;
bool operator==(const Shortcut& other) const
{
return key == other.key && modifiers == other.modifiers;
}
};
class Window
{
public:
static Result<Window*> create(Rect rect, WindowType type = WindowType::Normal);
void set_title(StringView title);
void set_background(Color color)
{
m_background = color;
}
void set_main_widget(Widget& widget)
{
check(!m_main_widget);
widget.set_window(this, m_window_canvas.rect(), {});
m_main_widget = &widget;
}
Canvas& canvas()
{
return m_window_canvas;
}
void update();
void close();
void set_layer(Layer layer);
Result<void> draw();
Result<ui::EventResult> handle_mouse_leave();
Result<ui::EventResult> handle_mouse_move(ui::Point position);
Result<ui::EventResult> handle_mouse_buttons(ui::Point position, int buttons);
Result<ui::EventResult> handle_key_event(const ui::KeyEventRequest& request);
Result<void> add_keyboard_shortcut(ui::Shortcut shortcut, bool intercept, Function<ui::Shortcut>&& action);
int id() const
{
return m_id;
}
void on_close(Action&& action)
{
m_on_close_action = move(action);
m_has_on_close_action = true;
}
~Window();
private:
int m_id;
Canvas m_canvas;
Canvas m_titlebar_canvas;
Canvas m_window_canvas;
String m_name;
Widget* m_main_widget { nullptr };
Option<Color> m_background {};
Option<int> m_old_mouse_buttons;
bool m_decorated { false };
Action m_on_close_action;
bool m_has_on_close_action { false };
struct ShortcutAction
{
bool intercept;
Function<Shortcut> action;
};
HashMap<Shortcut, ShortcutAction> m_shortcuts;
Result<void> draw_titlebar();
};
}

View File

@ -0,0 +1,72 @@
/**
* @file ipc/Client.h
* @author apio (cloudapio.eu)
* @brief IPC message definitions for UI messages sent to the client.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <os/IPC.h>
#include <ui/Key.h>
#include <ui/Point.h>
#include <ui/Rect.h>
namespace ui
{
enum ClientMessages : u8
{
IPC_ENUM_CLIENT(ui),
CREATE_WINDOW_RESPONSE_ID,
MOUSE_EVENT_REQUEST_ID,
MOUSE_LEAVE_REQUEST_ID,
GET_SCREEN_RECT_RESPONSE_ID,
KEY_EVENT_REQUEST_ID,
};
struct CreateWindowResponse
{
static constexpr u8 ID = CREATE_WINDOW_RESPONSE_ID;
int window;
IPC_STRING(shm_path);
};
struct MouseEventRequest
{
static constexpr u8 ID = MOUSE_EVENT_REQUEST_ID;
int window;
Point position;
int buttons;
};
struct MouseLeaveRequest
{
static constexpr u8 ID = MOUSE_LEAVE_REQUEST_ID;
int window;
};
struct GetScreenRectResponse
{
static constexpr u8 ID = GET_SCREEN_RECT_RESPONSE_ID;
Rect rect;
};
struct KeyEventRequest
{
static constexpr u8 ID = KEY_EVENT_REQUEST_ID;
int window;
bool pressed;
char letter;
char key;
moon::KeyCode code;
int modifiers;
};
}

View File

@ -0,0 +1,113 @@
/**
* @file ipc/Server.h
* @author apio (cloudapio.eu)
* @brief IPC message definitions for UI messages sent to the server.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#pragma once
#include <os/IPC.h>
#include <ui/Color.h>
#include <ui/Rect.h>
#include <ui/ipc/Client.h>
namespace ui
{
enum ServerMessages : u8
{
IPC_ENUM_SERVER(ui),
CREATE_WINDOW_ID,
REMOVE_SHM_ID,
SET_WINDOW_TITLE_ID,
INVALIDATE_ID,
CLOSE_WINDOW_ID,
GET_SCREEN_RECT_ID,
SET_TITLEBAR_HEIGHT_ID,
SET_WINDOW_LAYER_ID,
UPDATE_PLEDGE_REQUEST_ID,
};
struct CreateWindowRequest
{
using ResponseType = CreateWindowResponse;
static constexpr u8 ID = CREATE_WINDOW_ID;
ui::Rect rect;
};
struct RemoveSharedMemoryRequest
{
static constexpr u8 ID = REMOVE_SHM_ID;
int window;
};
struct SetWindowTitleRequest
{
static constexpr u8 ID = SET_WINDOW_TITLE_ID;
int window;
IPC_STRING(title);
};
struct InvalidateRequest
{
static constexpr u8 ID = INVALIDATE_ID;
int window;
};
struct CloseWindowRequest
{
static constexpr u8 ID = CLOSE_WINDOW_ID;
int window;
};
struct GetScreenRectRequest
{
using ResponseType = GetScreenRectResponse;
static constexpr u8 ID = GET_SCREEN_RECT_ID;
int _shadow; // Unused.
};
struct SetTitlebarHeightRequest
{
static constexpr u8 ID = SET_TITLEBAR_HEIGHT_ID;
int window;
int height;
};
enum Layer : u8
{
Background,
Global,
GlobalTop,
System,
Lock
};
struct SetWindowLayer
{
static constexpr u8 ID = SET_WINDOW_LAYER_ID;
int window;
Layer layer;
};
enum Pledge : i16
{
ExtendedLayers = 1,
};
struct UpdatePledgeRequest
{
static constexpr u8 ID = UPDATE_PLEDGE_REQUEST_ID;
i16 pledges;
};
}

View File

@ -0,0 +1,40 @@
/**
* @file Alignment.cpp
* @author apio (cloudapio.eu)
* @brief UI component alignment.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include <ui/Alignment.h>
namespace ui
{
Rect align(Rect container, Rect contained, VerticalAlignment valign, HorizontalAlignment halign)
{
Rect result;
result.width = contained.width;
result.height = contained.height;
result.pos.y = container.pos.y;
result.pos.x = container.pos.x;
switch (valign)
{
case VerticalAlignment::Top: break;
case VerticalAlignment::Center: result.pos.y += (container.height - contained.height) / 2; break;
case VerticalAlignment::Bottom: result.pos.y += container.height - contained.height; break;
default: break;
}
switch (halign)
{
case HorizontalAlignment::Left: break;
case HorizontalAlignment::Center: result.pos.x += (container.width - contained.width) / 2; break;
case HorizontalAlignment::Right: result.pos.x += container.width - contained.width; break;
default: break;
}
return result;
}
}

145
gui/libui/src/App.cpp Normal file
View File

@ -0,0 +1,145 @@
/**
* @file App.cpp
* @author apio (cloudapio.eu)
* @brief UI application event loop.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include <os/ArgumentParser.h>
#include <os/File.h>
#include <os/IPC.h>
#include <ui/App.h>
#include <ui/ipc/Client.h>
#include <ui/ipc/Server.h>
namespace ui
{
void handle_socket_event(int, int status)
{
if (status & POLLHUP) ui::App::the().set_should_close(true);
if (status & POLLIN) { ui::App::the().process_events(); }
}
App* App::s_app { nullptr };
App::App()
{
s_app = this;
}
App::~App()
{
s_app = nullptr;
}
Result<void> App::init(StringView socket_path)
{
m_client = TRY(os::IPC::Client::connect(socket_path, false));
m_client->set_message_handler(
[this](os::IPC::Client& client, u8 id, void* arg) { this->handle_ipc_event(client, id, arg); }, nullptr);
TRY(m_loop.register_fd_listener(m_client->fd(), handle_socket_event));
return {};
}
Result<int> App::run()
{
TRY(m_main_window->draw());
return m_loop.run();
}
App& App::the()
{
check(s_app);
return *s_app;
}
Rect App::screen_rect()
{
ui::GetScreenRectRequest request {};
auto response = m_client->send_sync<ui::GetScreenRectResponse>(request).release_value();
return response.rect;
}
Result<void> App::register_window(OwnedPtr<Window>&& window, Badge<Window>)
{
int id = window->id();
check(TRY(m_windows.try_set(id, move(window))));
return {};
}
void App::unregister_window(Window* window, Badge<Window>)
{
int id = window->id();
m_window_clear_queue.try_append(id);
}
Window* App::find_window(int id)
{
auto* window = m_windows.try_get_ref(id);
check(window);
return window->ptr();
}
Result<void> App::handle_ipc_event(os::IPC::Client&, u8 id, void*)
{
switch (id)
{
case MOUSE_EVENT_REQUEST_ID: {
MouseEventRequest request;
if (!TRY(m_client->read_message(request))) return {};
auto* window = find_window(request.window);
auto move_result = window->handle_mouse_move(request.position).value_or(ui::EventResult::DidNotHandle);
auto button_result =
window->handle_mouse_buttons(request.position, request.buttons).value_or(ui::EventResult::DidNotHandle);
if (move_result == ui::EventResult::DidHandle || button_result == ui::EventResult::DidHandle)
window->draw();
return {};
}
case MOUSE_LEAVE_REQUEST_ID: {
MouseLeaveRequest request;
if (!TRY(m_client->read_message(request))) return {};
auto* window = find_window(request.window);
if (window->handle_mouse_leave().value_or(ui::EventResult::DidNotHandle) == ui::EventResult::DidHandle)
window->draw();
return {};
}
case KEY_EVENT_REQUEST_ID: {
KeyEventRequest request;
if (!TRY(m_client->read_message(request))) return {};
auto* window = find_window(request.window);
if (window->handle_key_event(request).value_or(ui::EventResult::DidNotHandle) == ui::EventResult::DidHandle)
window->draw();
return {};
}
default: fail("Unexpected IPC request from server!");
}
}
bool App::process_events()
{
check(m_main_window);
m_client->check_for_messages().release_value();
for (int id : m_window_clear_queue)
{
check(m_windows.try_remove(id));
ui::CloseWindowRequest request;
request.window = id;
client().send_async(request);
}
m_window_clear_queue.clear_data();
return !m_should_close;
}
void App::pledge(i16 pledges)
{
ui::UpdatePledgeRequest request;
request.pledges = pledges;
client().send_async(request);
}
}

73
gui/libui/src/Button.cpp Normal file
View File

@ -0,0 +1,73 @@
/**
* @file Button.cpp
* @author apio (cloudapio.eu)
* @brief A clickable component that triggers an action when pressed.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include <ui/Button.h>
#include <ui/Mouse.h>
namespace ui
{
Button::Button(Rect rect)
{
m_rect = rect;
}
void Button::set_widget(Widget& widget)
{
widget.rect() = m_rect;
m_child = &widget;
widget.set_parent(this);
}
void Button::set_action(Action&& action)
{
m_action = move(action);
}
Result<EventResult> Button::handle_mouse_move(Point position)
{
m_hovered = true;
return m_child->handle_mouse_move(position);
}
Result<EventResult> Button::handle_mouse_leave()
{
m_hovered = m_clicked = false;
return m_child->handle_mouse_leave();
}
Result<EventResult> Button::handle_mouse_down(Point position, int buttons)
{
auto result = TRY(m_child->handle_mouse_down(position, buttons));
if (result == EventResult::DidNotHandle)
{
if (!m_clicked && (buttons == ui::MouseButtons::LEFT))
{
m_clicked = true;
m_action();
}
}
return EventResult::DidHandle;
}
Result<EventResult> Button::handle_mouse_up(Point position, int buttons)
{
if (buttons & ui::MouseButtons::LEFT) m_clicked = false;
return m_child->handle_mouse_up(position, buttons);
}
Result<EventResult> Button::handle_key_event(const ui::KeyEventRequest& request)
{
return m_child->handle_key_event(request);
}
Result<void> Button::draw(Canvas& canvas)
{
return m_child->draw(canvas);
}
}

75
gui/libui/src/Canvas.cpp Normal file
View File

@ -0,0 +1,75 @@
/**
* @file Canvas.cpp
* @author apio (cloudapio.eu)
* @brief Drawable surfaces.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include <luna/CString.h>
#include <ui/Canvas.h>
namespace ui
{
Canvas Canvas::create(u8* ptr, int width, int height)
{
return Canvas { .width = width, .height = height, .stride = width, .ptr = ptr };
}
Canvas Canvas::subcanvas(Rect rect)
{
if (rect.pos.x < 0) rect.pos.x = 0;
if (rect.pos.y < 0) rect.pos.y = 0;
if (rect.pos.x + rect.width > width) rect.width = width - rect.pos.x;
if (rect.pos.y + rect.height > height) rect.height = height - rect.pos.y;
u8* p = ptr + rect.pos.x * sizeof(Color) + (rect.pos.y * sizeof(Color) * stride);
return Canvas { .width = rect.width, .height = rect.height, .stride = stride, .ptr = p };
}
void Canvas::fill(Color color)
{
u8* p = ptr;
for (int i = 0; i < height; i++)
{
u32* colorp = (u32*)p;
for (int j = 0; j < width; j++)
{
*colorp = color.raw;
colorp++;
}
p += stride * sizeof(Color);
}
}
void Canvas::fill(u32* pixels, int _stride)
{
u8* p = ptr;
for (int i = 0; i < height; i++)
{
u32* colorp = (u32*)p;
for (int j = 0; j < width; j++)
{
u32 pix = pixels[j];
if (Color::from_u32(pix).alpha() == 0xff) *colorp = pix;
colorp++;
}
pixels += _stride;
p += stride * sizeof(Color);
}
}
void Canvas::copy(u32* pixels, int _stride)
{
u8* p = ptr;
for (int i = 0; i < height; i++)
{
u32* colorp = (u32*)p;
memcpy(colorp, pixels, width * sizeof(u32));
pixels += _stride;
p += stride * sizeof(Color);
}
}
}

Some files were not shown because too many files have changed in this diff Show More