Compare commits

..

18 commits

Author SHA1 Message Date
Lluciocc
d74deb0702
Merge 29e1b362ff into 5d0e828b41 2026-05-13 07:22:49 +00:00
Lluciocc
29e1b362ff replacing with strcmp && Adding comments && adding helper when the command don't exist 2026-05-13 09:17:08 +02:00
Lluciocc
5d0e828b41
asking testing platform and env in the PR template 2026-05-13 08:36:30 +02:00
Lluciocc
69d5f8feff Update header 2026-05-13 08:11:00 +02:00
Lluciocc
9574b99f40
Merge branch 'BoredDevNL:main' into cmds 2026-05-13 08:06:03 +02:00
Lluciocc
c66bfa62cf
Merge pull request #36 from zeyadhost/main
Some checks are pending
Nightly Build / build-and-release (push) Waiting to run
Add du command for disk usage reporting
2026-05-12 23:07:45 +02:00
Lluciocc
4b169b92de Update headers 2026-05-12 23:01:43 +02:00
zeyad
e75952e510 fix(cli): correct du usage format and replace -h with -H 2026-05-12 20:58:53 +00:00
boreddevnl
f6141dfcaf Merge branch 'main' of https://github.com/BoredDevNL/BoredOS 2026-05-12 22:48:59 +02:00
boreddevnl
e813a6cdfd docs: add section for issue tags in bug report and feature request templates 2026-05-12 22:48:49 +02:00
zeyad
a6118e8d21 feat(cli): add du command for disk usage reporting 2026-05-12 20:33:09 +00:00
Chris
1ccc86ea41
doc: Add requirement for comments in PR template 2026-05-12 20:06:50 +02:00
Lluciocc
642dc7f8c9
Update toolchain.md with qemu-img PATH instruction
Some checks are pending
Nightly Build / build-and-release (push) Waiting to run
2026-05-12 19:28:28 +02:00
boreddevnl
43a62b025d Merge branch 'main' of https://github.com/BoredDevNL/BoredOS 2026-05-12 19:18:06 +02:00
boreddevnl
52b6532700 brand: add orbital.png
Co-Authored-By: Target <71287126+toiletalphamale@users.noreply.github.com>
2026-05-12 19:18:04 +02:00
Lluciocc
1655f1cf22
Add 'git' to required development tools installation 2026-05-12 19:17:00 +02:00
Lluciocc
5e3ba70730
Revise Windows toolchain installation instructions 2026-05-12 19:13:29 +02:00
boreddevnl
8d4ffd8a09 kernel: prevent infinite loop in process termination 2026-05-12 19:11:17 +02:00
23 changed files with 431 additions and 46 deletions

View file

@ -27,3 +27,5 @@ A clear and concise description of what the bug is. What did you expect to happe
**5. Additional Context:**
Add any other context about the problem here (e.g., "This only happens when my mouse is moving").
**6. Please add tags to your issue to help with organization.**

View file

@ -21,3 +21,5 @@ Let us know if this is just an idea you'd like to see, or if you plan on submitt
**5. Additional Context:**
Add any other context, mockup screenshots, or links to technical documentation (e.g., OSDev Wiki links) here.
**6. Please add tags to your issue to help with organization.**

View file

@ -9,12 +9,20 @@ Describe the changes made in this PR.
- [ ] Code has been tested
- [ ] Existing tests pass
### Platform / Environment
What platform and environment were used for development and testing?
Examples:
- Windows 11 / macOS / Linux
- MSYS2 / WSL2 / Debian
Notes:
<!-- Add anything relevant about testing -->
---
## Documentation
- [ ] Code contains appropriate comments (REQUIRED for medium to large PR's.)
- [ ] Documentation updated if needed

View file

@ -74,13 +74,14 @@ x86_64-elf-gcc --version
> **Note**: Building the cross-compiler can take 20-30 minutes depending on system performance. This is a one-time setup cost.
## Installing the Toolchain on Windows
### Recommended Environment: MSYS2
On Windows, the recommended way to build BoredOS is using **MSYS2**.
MSYS2 provides a Unix-like environment with the `pacman` package manager, making it easy to install the required development tools and the `x86_64-elf` cross-toolchain directly from the repositories.
MSYS2 provides a Unix-like environment with the `pacman` package manager, making it easy to install the required development tools.
### 1. Install MSYS2
---
## 1. Install MSYS2
Download and install MSYS2 from the official website:
@ -90,7 +91,7 @@ After installation, launch the **MSYS2 UCRT64** terminal.
---
### 2. Update MSYS2
## 2. Update MSYS2
Before installing packages, fully update the environment:
@ -99,6 +100,7 @@ pacman -Syu
```
You may be asked to close the terminal after the first update.
If so:
1. Close the MSYS2 window
@ -113,35 +115,80 @@ Repeat until no further updates are available.
---
### 3. Install Required Packages
## 3. Install Required Packages
Install the required development tools:
```bash
pacman -S \
make \
git \
nasm \
xorriso \
qemu-system-x86_64
pacman -S make nasm xorriso git
```
---
### 4. Install the x86_64 ELF Toolchain
## 4. Install QEMU for Windows
MSYS2 provides the full `x86_64-elf` cross-compilation toolchain directly through `pacman`.
Download the Windows version of QEMU from:
Install it with:
- https://qemu.weilnetz.de/w64/
Install QEMU normally and make sure the installation directory is added to your Windows `PATH`.
Note that if it breaks when building, you need too add `qemu-img` to your `PATH`:
`export PATH="/c/Program Files/qemu:$PATH"`
You can verify the installation with:
```bash
pacman -S \
mingw-w64-ucrt-x86_64-x86_64-elf-gcc \
mingw-w64-ucrt-x86_64-x86_64-elf-binutils
qemu-system-x86_64 --version
```
This installs:
---
## 5. Install the x86_64 ELF Cross Toolchain
Download the prebuilt `x86_64-elf` toolchain for Windows:
- https://github.com/lordmilko/i686-elf-tools/releases/download/15.2.0/x86_64-elf-tools-windows.zip
Extract the archive somewhere convenient.
---
## 6. Add the Toolchain to PATH
Inside the **MSYS2 UCRT64** terminal, add the toolchain binaries to your `PATH`:
```bash
export PATH="/c/Users/your/path/to/the/binaries/x86_64-elf-tools-windows/bin:$PATH"
```
To make this permanent, add the line to your `~/.bashrc` file:
```bash
echo 'export PATH="/c/Users/your/path/to/the/binaries/x86_64-elf-tools-windows/bin:$PATH"' >> ~/.bashrc
```
Then reload the shell:
```bash
source ~/.bashrc
```
---
## 7. Verify the Installation
Verify that the cross compiler is available:
```bash
x86_64-elf-gcc --version
```
You should also verify NASM and QEMU:
```bash
nasm -v
qemu-system-x86_64 --version
```
If all commands work, the development environment is correctly configured.
- `x86_64-elf-gcc`
- `x86_64-elf-ld`
- other required ELF binutils

90
docs/usage/commands/du.md Normal file
View file

@ -0,0 +1,90 @@
# du
`du` (disk usage) reports the disk space used by files and directories.
## Usage
```sh
du [OPTIONS]... [FILE]...
```
## Description
By default, `du` prints human-readable sizes for each file and directory it encounters, starting from the current directory (`.`) if no path is given.
## Options
| Option | Description |
| :--- | :--- |
| `-s, --summarize` | Show only a total for each argument, suppressing per-entry output. |
| `-a, --all` | Write counts for all files, not just directories. |
| `-d, --max-depth=N` | Stop at depth N; show only entries at or above depth N. |
| `-c, --total` | Print a grand total after all arguments have been processed. |
| `-b, --bytes` | Print sizes in exact bytes instead of human-readable units. |
| `-H, --human-readable` | Accepted for compatibility; human-readable is the default. |
| `--help` | Display usage information and exit. |
## Output Format
Each line shows a size followed by the path:
```
SIZE PATH
```
Sizes are formatted as `B`, `KB`, `MB`, or `GB` by default, with one decimal place when appropriate (e.g., `1.5 GB`). The `-b` option overrides this to show exact byte counts.
## Examples
Show disk usage for the current directory:
```sh
du
```
Show disk usage for a specific path:
```sh
du /bin
```
Show only totals per argument (`-s`):
```sh
du -s /bin /home
```
Show all files and directories recursively (`-a`):
```sh
du -a /bin
```
Limit output to depth 1 (`-d`):
```sh
du -d 1 /
```
Print a grand total after processing (`-c`):
```sh
du -c /bin /home
```
Show exact byte counts (`-b`):
```sh
du -b /bin
```
## How It Works
`du` uses `sys_get_file_info()` to read file sizes and `sys_list()` to enumerate directory contents recursively. The command skips the synthetic `.` and `..` entries and continues processing remaining paths if one path is inaccessible, printing an error for the failed path.
The size reported is the **apparent file size** (the logical size stored in the directory entry), not the allocated disk blocks. This is consistent with how BoredOS reports file sizes through the filesystem API.
## Exit Status
- `0`: Success
- `1`: One or more paths could not be accessed or listed

View file

@ -54,6 +54,7 @@ Below are some of the most used commands available in `/bin`:
| `mkdir` | Create a new directory. |
| `man` | View the manual for a specific command (e.g., `man ls`). |
| `lsblk` | List block devices and partitions with size, type, filesystem, label, and flags. |
| `du` | Report disk usage for files and directories, recursively. |
| `sysfetch` | Display system and hardware information. |

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include "keyboard.h"
#include "keymap.h"
#include "../core/io.h"

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#ifndef KEYBOARD_H
#define KEYBOARD_H

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#ifndef KEYCODES_H
#define KEYCODES_H

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include "keymap.h"
#define DEAD_NORMAL 0x01

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#ifndef KEYMAP_H
#define KEYMAP_H

View file

@ -691,7 +691,9 @@ void process_kill_by_tty(int tty_id) {
if (tty_id < 0) return;
for (int i = 0; i < MAX_PROCESSES; i++) {
if (processes[i].pid != 0xFFFFFFFF && processes[i].pid != 0 && processes[i].tty_id == tty_id) {
process_terminate(&processes[i]);
if (!processes[i].exited && !processes[i].kill_pending) {
process_terminate(&processes[i]);
}
}
}
}
@ -735,6 +737,7 @@ void process_terminate(process_t *to_delete) {
void process_terminate_with_status(process_t *to_delete, int status) {
if (!to_delete || to_delete->pid == 0xFFFFFFFF || to_delete->pid == 0) return;
if (to_delete->exited || to_delete->kill_pending) return;
uint32_t cpu_count = smp_cpu_count();
for (uint32_t c = 0; c < cpu_count && c < MAX_CPUS_SCHED; c++) {

203
src/userland/cli/du.c Normal file
View file

@ -0,0 +1,203 @@
// Copyright (c) 2026 zeyadhost (https://github.com/zeyadhost)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syscall.h>
#include <stdint.h>
#define MAX_ENTRIES 1024
#define DU_KB 1024ULL
#define DU_MB (1024ULL * 1024ULL)
#define DU_GB (1024ULL * 1024ULL * 1024ULL)
static int opt_summarize = 0;
static int opt_all = 0;
static int opt_max_depth = -1;
static int opt_total = 0;
static int opt_bytes = 0;
static uint64_t grand_total = 0;
static void usage(void) {
printf("Usage: du [options]..[file]\n");
printf("Summarize disk usage of the set of FILEs, recursively for directories.\n\n");
printf("Options:\n");
printf(" -s, --summarize display only a total for each argument\n");
printf(" -a, --all write counts for all files, not just directories\n");
printf(" -d, --max-depth=N print the total for a directory only if it is N or\n");
printf(" fewer levels below the command line argument\n");
printf(" -c, --total produce a grand total\n");
printf(" -b, --bytes print sizes in bytes\n");
printf(" -H, --human-readable print sizes in human readable format (default)\n");
printf(" --help display this help and exit\n");
}
static void print_size(uint64_t bytes, const char *path) {
if (opt_bytes) {
printf("%llu\t%s\n", (unsigned long long)bytes, path);
return;
}
char size_str[32];
uint64_t unit = 1;
const char *suffix = "B";
if (bytes >= DU_GB) {
unit = DU_GB;
suffix = "GB";
} else if (bytes >= DU_MB) {
unit = DU_MB;
suffix = "MB";
} else if (bytes >= DU_KB) {
unit = DU_KB;
suffix = "KB";
}
if (unit == 1) {
snprintf(size_str, sizeof(size_str), "%llu%s", (unsigned long long)bytes, suffix);
} else {
// Round to one decimal place
uint64_t whole = bytes / unit;
uint64_t rem = bytes % unit;
uint64_t tenth = (rem * 10ULL + unit / 2ULL) / unit;
if (tenth >= 10ULL) {
whole++;
tenth = 0;
}
if (tenth == 0) {
snprintf(size_str, sizeof(size_str), "%llu%s", (unsigned long long)whole, suffix);
} else {
snprintf(size_str, sizeof(size_str), "%llu.%llu%s", (unsigned long long)whole, (unsigned long long)tenth, suffix);
}
}
printf("%s\t%s\n", size_str, path);
}
static void join_path(char *dest, size_t size, const char *p1, const char *p2) {
if (strcmp(p1, "/") == 0) {
snprintf(dest, size, "/%s", p2);
} else if (p1[strlen(p1) - 1] == '/') {
snprintf(dest, size, "%s%s", p1, p2);
} else {
snprintf(dest, size, "%s/%s", p1, p2);
}
}
static uint64_t do_du(const char *path, int depth) {
FAT32_FileInfo info;
if (sys_get_file_info(path, &info) < 0) {
printf("du: cannot access '%s'\n", path);
return 0;
}
if (!info.is_directory) {
if (opt_all || (depth == 0)) {
if (opt_max_depth == -1 || depth <= opt_max_depth) {
if (!opt_summarize || depth == 0) {
print_size(info.size, path);
}
}
}
return info.size;
}
uint64_t total_size = info.size;
FAT32_FileInfo *entries = malloc(sizeof(FAT32_FileInfo) * MAX_ENTRIES);
if (!entries) {
printf("du: out of memory for '%s'\n", path);
return total_size;
}
int count = sys_list(path, entries, MAX_ENTRIES);
if (count < 0) {
printf("du: cannot read directory '%s'\n", path);
free(entries);
return total_size;
}
// Recurse into subdirectories
for (int i = 0; i < count; i++) {
if (strcmp(entries[i].name, ".") == 0 || strcmp(entries[i].name, "..") == 0) {
continue;
}
char child_path[1024];
join_path(child_path, sizeof(child_path), path, entries[i].name);
total_size += do_du(child_path, depth + 1);
}
free(entries);
// Print directory size at this depth
if (!opt_summarize) {
if (opt_max_depth == -1 || depth <= opt_max_depth) {
print_size(total_size, path);
}
} else if (depth == 0) {
// With -s, only print the root of each requested path
print_size(total_size, path);
}
return total_size;
}
int main(int argc, char **argv) {
char **paths = malloc(sizeof(char*) * argc);
int num_paths = 0;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--summarize") == 0) {
opt_summarize = 1;
} else if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--all") == 0) {
opt_all = 1;
} else if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--total") == 0) {
opt_total = 1;
} else if (strcmp(argv[i], "-b") == 0 || strcmp(argv[i], "--bytes") == 0) {
opt_bytes = 1;
} else if (strcmp(argv[i], "-H") == 0 || strcmp(argv[i], "--human-readable") == 0) {
// No-op: human-readable is the default
} else if (strcmp(argv[i], "-d") == 0) {
if (i + 1 < argc) {
opt_max_depth = atoi(argv[++i]);
} else {
printf("du: option requires an argument -- '-d'\n");
return 1;
}
} else if (strncmp(argv[i], "--max-depth=", 12) == 0) {
opt_max_depth = atoi(argv[i] + 12);
} else if (strcmp(argv[i], "--help") == 0) {
usage();
free(paths);
return 0;
} else if (argv[i][0] == '-') {
printf("du: invalid option -- '%s'\n", argv[i]);
usage();
free(paths);
return 1;
} else {
paths[num_paths++] = argv[i];
}
}
if (num_paths == 0) {
grand_total += do_du(".", 0);
} else {
for (int i = 0; i < num_paths; i++) {
grand_total += do_du(paths[i], 0);
}
}
if (opt_total) {
print_size(grand_total, "total");
}
free(paths);
return 0;
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023-2026 Chris (boreddevnl)
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
// BOREDOS_APP_DESC: Display file contents in hexadecimal.

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023-2026 Chris (boreddevnl)
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
// BOREDOS_APP_DESC: List running processes.

View file

@ -1,21 +1,16 @@
// Copyright (c) 2023-2026 Chris (boreddevnl)
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include "stdlib.h"
#include "syscall.h"
// CMDLINE_MAX includes the trailing NUL, so at most 511 command-line bytes can
// be reconstructed here. Unchecked concatenation can overflow CMDLINE_MAX; all
// command-line construction in this file must go through the checked append
// helpers below.
#define CMDLINE_MAX 512
static int sc_strcmp(const char *a, const char *b) {
while (*a && *a == *b) {
a++;
b++;
}
return (unsigned char)*a - (unsigned char)*b;
}
static int has_slash(const char *s) {
while (s && *s) {
if (*s == '/')
@ -37,7 +32,7 @@ static int ends_with_elf(const char *s) {
if (len < 4)
return 0;
return sc_strcmp(s + len - 4, ".elf") == 0;
return strcmp(s + len - 4, ".elf") == 0;
}
static void print_usage(void) {
@ -113,8 +108,8 @@ int main(int argc, char **argv) {
return 1;
}
if (sc_strcmp(argv[1], "-h") == 0 ||
sc_strcmp(argv[1], "--help") == 0) {
if (strcmp(argv[1], "-h") == 0 ||
strcmp(argv[1], "--help") == 0) {
print_usage();
return 0;
}
@ -135,7 +130,15 @@ int main(int argc, char **argv) {
printf("\n");
printf("Command: %s\n", cmdline);
printf("Exit code: %d\n", ret);
if (ret == -1) {
printf("Command failed with non-zero exit code, not reporting time.\n");
return ret;
}
printf("Elapsed: %llu ms\n", elapsed);
sys_system(SYSTEM_CMD_SLEEP, 1, 0, 0, 0);
return ret;
}

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
// BOREDOS_APP_DESC: 2048 number puzzle game.
// BOREDOS_APP_ICONS: /Library/images/icons/colloid/applications-games.png
#include "libc/syscall.h"

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
// BOREDOS_APP_DESC: Classic snake arcade game.
// BOREDOS_APP_ICONS: /Library/images/icons/colloid/cartridges.png
#include "libc/syscall.h"

View file

@ -1,16 +1,12 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include "libc/syscall.h"
#include "libc/libui.h"
#include "libc/stdlib.h"
#include <stdint.h>
#include <stdbool.h>
/*
@Lluciocc
The most SIMPLE keylogger for debug
FEAT:
- Log every key pressed in the terminal and gives their keycode
*/
#define WINDOW_W 400
#define WINDOW_H 200

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include "utf-8.h"
static int utf8_write_replacement(char *out) {

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#ifndef UTF_8_H
#define UTF_8_H

View file

@ -1,3 +1,6 @@
// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#ifndef UTF_8_H
#define UTF_8_H