mirror of
https://github.com/BoredDevNL/BoredOS.git
synced 2026-05-15 18:58:40 +00:00
Introduce process lifecycle and POSIX-like features: add parent_pid, pgid, exited/exit_status, signal state and handlers, waitpid/reap, and an exec-replace function. Refactor file descriptor handling to use fd_kind/fd_flags with reference-counted file refs and in-process pipes; implement open/read/write/close/seek/tell/size/dup/dup2/pipe/fcntl semantics and O_* flags. Add syscall handlers for exec, waitpid, kill/signal, sigaction, sigprocmask, sigpending, meminfo/ticks and map many SYSTEM_CMD_* constants; deliver signals from the syscall path. Cleanup/terminate logic updated to free resources correctly and initialize kernel/user processes with new state. Misc: minor syscall/table renames (wallpaper), helper utilities (process_close_fd_inner, process_init_signal_state) and paging/stack handling for exec.
224 lines
4.6 KiB
C
224 lines
4.6 KiB
C
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
|
|
#include "errno.h"
|
|
#include "stdio.h"
|
|
#include "string.h"
|
|
#include "sys/types.h"
|
|
#include "sys/wait.h"
|
|
#include "syscall.h"
|
|
#include "unistd.h"
|
|
|
|
static int _b_is_space(char c) {
|
|
return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v';
|
|
}
|
|
|
|
static int _b_path_exists(const char *path) {
|
|
return path && path[0] && sys_exists(path);
|
|
}
|
|
|
|
static const char *_b_resolve_exec_path(const char *file, char *out, size_t cap) {
|
|
if (!file || !file[0]) {
|
|
return NULL;
|
|
}
|
|
|
|
if (file[0] == '/') {
|
|
return _b_path_exists(file) ? file : NULL;
|
|
}
|
|
|
|
snprintf(out, cap, "/bin/%s", file);
|
|
if (_b_path_exists(out)) {
|
|
return out;
|
|
}
|
|
|
|
snprintf(out, cap, "/bin/%s.elf", file);
|
|
if (_b_path_exists(out)) {
|
|
return out;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static int _b_join_argv(char *buf, size_t cap, char *const argv[]) {
|
|
size_t used = 0;
|
|
|
|
if (!argv || !argv[0]) {
|
|
if (cap) {
|
|
buf[0] = '\0';
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
for (int i = 1; argv[i]; i++) {
|
|
const char *a = argv[i];
|
|
size_t len = strlen(a);
|
|
int need_quote = 0;
|
|
|
|
for (size_t j = 0; j < len; j++) {
|
|
if (_b_is_space(a[j]) || a[j] == '"') {
|
|
need_quote = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (used && used + 1 < cap) {
|
|
buf[used++] = ' ';
|
|
}
|
|
|
|
if (need_quote && used + 1 < cap) {
|
|
buf[used++] = '"';
|
|
}
|
|
|
|
for (size_t j = 0; j < len; j++) {
|
|
if (a[j] == '"' && used + 2 < cap) {
|
|
buf[used++] = '\\';
|
|
}
|
|
if (used + 1 < cap) {
|
|
buf[used++] = a[j];
|
|
}
|
|
}
|
|
|
|
if (need_quote && used + 1 < cap) {
|
|
buf[used++] = '"';
|
|
}
|
|
|
|
if (used >= cap) {
|
|
errno = E2BIG;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (cap) {
|
|
buf[used < cap ? used : cap - 1] = '\0';
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int _b_exec_common(const char *path, char *const argv[]) {
|
|
char resolved[260];
|
|
char args[512];
|
|
const char *exec_path = _b_resolve_exec_path(path, resolved, sizeof(resolved));
|
|
|
|
if (!exec_path) {
|
|
errno = ENOENT;
|
|
return -1;
|
|
}
|
|
|
|
if (_b_join_argv(args, sizeof(args), argv) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
if (sys_exec(exec_path, args[0] ? args : NULL) < 0) {
|
|
errno = EIO;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
__attribute__((weak)) int execv(const char *path, char *const argv[]) {
|
|
return _b_exec_common(path, argv);
|
|
}
|
|
|
|
__attribute__((weak)) int execve(const char *path, char *const argv[], char *const envp[]) {
|
|
(void)envp;
|
|
return _b_exec_common(path, argv);
|
|
}
|
|
|
|
__attribute__((weak)) int execvp(const char *file, char *const argv[]) {
|
|
return _b_exec_common(file, argv);
|
|
}
|
|
|
|
__attribute__((weak)) int execl(const char *path, const char *arg, ...) {
|
|
va_list ap;
|
|
char *argv[64];
|
|
int i = 0;
|
|
|
|
argv[i++] = (char *)arg;
|
|
va_start(ap, arg);
|
|
while (i < 63) {
|
|
char *v = va_arg(ap, char *);
|
|
argv[i++] = v;
|
|
if (!v) {
|
|
break;
|
|
}
|
|
}
|
|
va_end(ap);
|
|
|
|
if (argv[i - 1] != NULL) {
|
|
argv[63] = NULL;
|
|
}
|
|
|
|
return execv(path, argv);
|
|
}
|
|
|
|
__attribute__((weak)) int execlp(const char *file, const char *arg, ...) {
|
|
va_list ap;
|
|
char *argv[64];
|
|
int i = 0;
|
|
|
|
argv[i++] = (char *)arg;
|
|
va_start(ap, arg);
|
|
while (i < 63) {
|
|
char *v = va_arg(ap, char *);
|
|
argv[i++] = v;
|
|
if (!v) {
|
|
break;
|
|
}
|
|
}
|
|
va_end(ap);
|
|
|
|
if (argv[i - 1] != NULL) {
|
|
argv[63] = NULL;
|
|
}
|
|
|
|
return execvp(file, argv);
|
|
}
|
|
|
|
__attribute__((weak)) int execle(const char *path, const char *arg, ...) {
|
|
va_list ap;
|
|
char *argv[64];
|
|
int i = 0;
|
|
char *envp;
|
|
|
|
argv[i++] = (char *)arg;
|
|
va_start(ap, arg);
|
|
while (i < 63) {
|
|
char *v = va_arg(ap, char *);
|
|
argv[i++] = v;
|
|
if (!v) {
|
|
break;
|
|
}
|
|
}
|
|
envp = va_arg(ap, char *);
|
|
va_end(ap);
|
|
(void)envp;
|
|
|
|
if (argv[i - 1] != NULL) {
|
|
argv[63] = NULL;
|
|
}
|
|
|
|
return execv(path, argv);
|
|
}
|
|
|
|
__attribute__((weak)) pid_t waitpid(pid_t pid, int *status, int options) {
|
|
int st = 0;
|
|
|
|
for (;;) {
|
|
int rc = sys_waitpid((int)pid, &st, options);
|
|
if (rc > 0) {
|
|
if (status) {
|
|
*status = st;
|
|
}
|
|
return (pid_t)rc;
|
|
}
|
|
if (rc == 0 && (options & WNOHANG)) {
|
|
return 0;
|
|
}
|
|
if (rc < 0) {
|
|
errno = ECHILD;
|
|
return -1;
|
|
}
|
|
sys_yield();
|
|
}
|
|
}
|