Compare commits
No commits in common. "81e1fdf81e6e2ca3a7045d2dab1884a69715dda9" and "10917981954b83c58f7cbd6b2ca806196d4f5079" have entirely different histories.
81e1fdf81e
...
1091798195
@ -1,10 +1,7 @@
|
|||||||
#include <bits/termios.h>
|
|
||||||
#include <luna/String.h>
|
#include <luna/String.h>
|
||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
#include <os/File.h>
|
#include <os/File.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
Result<int> luna_main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
@ -29,14 +26,6 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
if (username.is_empty())
|
if (username.is_empty())
|
||||||
{
|
{
|
||||||
signal(SIGTTOU, SIG_IGN);
|
|
||||||
|
|
||||||
if (isatty(STDIN_FILENO))
|
|
||||||
{
|
|
||||||
pid_t pgid = getpgid(0);
|
|
||||||
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto input = os::File::standard_input();
|
auto input = os::File::standard_input();
|
||||||
|
|
||||||
os::print("Username: ");
|
os::print("Username: ");
|
||||||
|
48
apps/sh.cpp
48
apps/sh.cpp
@ -1,4 +1,3 @@
|
|||||||
#include <bits/termios.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <luna/String.h>
|
#include <luna/String.h>
|
||||||
#include <luna/Vector.h>
|
#include <luna/Vector.h>
|
||||||
@ -12,7 +11,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -33,11 +31,6 @@ static Result<void> execute_command(StringView command)
|
|||||||
return os::Process::exec(args[0].view(), args.slice());
|
return os::Process::exec(args[0].view(), args.slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do nothing, but we need a handler so read() returns EINTR.
|
|
||||||
static void sigint_handler(int)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
struct utsname g_sysinfo;
|
struct utsname g_sysinfo;
|
||||||
|
|
||||||
const char* hostname = "";
|
const char* hostname = "";
|
||||||
@ -48,6 +41,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
StringView path;
|
StringView path;
|
||||||
StringView command;
|
StringView command;
|
||||||
|
bool interactive { false };
|
||||||
|
|
||||||
SharedPtr<File> input_file;
|
SharedPtr<File> input_file;
|
||||||
|
|
||||||
@ -60,15 +54,17 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
if (!command.is_empty()) TRY(execute_command(command));
|
if (!command.is_empty()) TRY(execute_command(command));
|
||||||
|
|
||||||
if (path == "-") { input_file = File::standard_input(); }
|
if (path == "-")
|
||||||
|
{
|
||||||
|
input_file = File::standard_input();
|
||||||
|
interactive = true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
input_file = TRY(File::open(path, File::ReadOnly));
|
input_file = TRY(File::open(path, File::ReadOnly));
|
||||||
input_file->set_close_on_exec();
|
input_file->set_close_on_exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool interactive = isatty(input_file->fd());
|
|
||||||
|
|
||||||
if (interactive)
|
if (interactive)
|
||||||
{
|
{
|
||||||
// Set up everything to form a prompt.
|
// Set up everything to form a prompt.
|
||||||
@ -81,12 +77,6 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
if (pw) { username = pw->pw_name; }
|
if (pw) { username = pw->pw_name; }
|
||||||
else { username = getenv("USER"); }
|
else { username = getenv("USER"); }
|
||||||
endpwent();
|
endpwent();
|
||||||
|
|
||||||
signal(SIGTTOU, SIG_IGN);
|
|
||||||
signal(SIGINT, sigint_handler);
|
|
||||||
|
|
||||||
pid_t pgid = getpgid(0);
|
|
||||||
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -97,14 +87,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
os::print("%s@%s:%s%c ", username, hostname, cwd.chars(), prompt_end);
|
os::print("%s@%s:%s%c ", username, hostname, cwd.chars(), prompt_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto maybe_cmd = input_file->read_line();
|
auto cmd = TRY(input_file->read_line());
|
||||||
if (maybe_cmd.has_error())
|
|
||||||
{
|
|
||||||
if (maybe_cmd.error() == EINTR) continue;
|
|
||||||
return maybe_cmd.release_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cmd = maybe_cmd.release_value();
|
|
||||||
if (cmd.is_empty())
|
if (cmd.is_empty())
|
||||||
{
|
{
|
||||||
if (interactive) puts("exit");
|
if (interactive) puts("exit");
|
||||||
@ -133,26 +116,11 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
pid_t child = TRY(os::Process::fork());
|
pid_t child = TRY(os::Process::fork());
|
||||||
|
|
||||||
if (child == 0)
|
if (child == 0) { TRY(execute_command(cmd.view())); }
|
||||||
{
|
|
||||||
if (interactive)
|
|
||||||
{
|
|
||||||
setpgid(0, 0);
|
|
||||||
pid_t pgid = getpgid(0);
|
|
||||||
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
|
|
||||||
}
|
|
||||||
TRY(execute_command(cmd.view()));
|
|
||||||
}
|
|
||||||
|
|
||||||
int status;
|
int status;
|
||||||
TRY(os::Process::wait(child, &status));
|
TRY(os::Process::wait(child, &status));
|
||||||
|
|
||||||
if (interactive)
|
|
||||||
{
|
|
||||||
pid_t pgid = getpgid(0);
|
|
||||||
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WIFSIGNALED(status))
|
if (WIFSIGNALED(status))
|
||||||
{
|
{
|
||||||
int sig = WTERMSIG(status);
|
int sig = WTERMSIG(status);
|
||||||
|
26
apps/su.cpp
26
apps/su.cpp
@ -1,7 +1,6 @@
|
|||||||
#include <bits/termios.h>
|
#include <bits/termios.h>
|
||||||
#include <os/ArgumentParser.h>
|
#include <os/ArgumentParser.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@ -14,24 +13,8 @@ void restore_terminal()
|
|||||||
ioctl(fileno(stdin), TCSETS, &orig);
|
ioctl(fileno(stdin), TCSETS, &orig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sigint_handler(int)
|
|
||||||
{
|
|
||||||
restore_terminal();
|
|
||||||
raise(SIGINT);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* getpass()
|
char* getpass()
|
||||||
{
|
{
|
||||||
if (!isatty(STDIN_FILENO))
|
|
||||||
{
|
|
||||||
// FIXME: Just read from /dev/tty (the controlling terminal). Problem: that doesn't exist yet.
|
|
||||||
fprintf(stderr, "error: password must be read from a terminal!");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid_t pgid = getpgid(0);
|
|
||||||
ioctl(STDIN_FILENO, TIOCSPGRP, &pgid);
|
|
||||||
|
|
||||||
fputs("Password: ", stdout);
|
fputs("Password: ", stdout);
|
||||||
|
|
||||||
if (ioctl(fileno(stdin), TCGETS, &orig) < 0)
|
if (ioctl(fileno(stdin), TCGETS, &orig) < 0)
|
||||||
@ -40,12 +23,6 @@ char* getpass()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sigaction sa;
|
|
||||||
sa.sa_handler = sigint_handler;
|
|
||||||
sigemptyset(&sa.sa_mask);
|
|
||||||
sa.sa_flags = SA_RESETHAND;
|
|
||||||
sigaction(SIGINT, &sa, NULL);
|
|
||||||
|
|
||||||
atexit(restore_terminal);
|
atexit(restore_terminal);
|
||||||
|
|
||||||
struct termios tc = orig;
|
struct termios tc = orig;
|
||||||
@ -105,8 +82,6 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
if ((prompt_password || getuid() != geteuid()) && *entry->pw_passwd)
|
if ((prompt_password || getuid() != geteuid()) && *entry->pw_passwd)
|
||||||
{
|
{
|
||||||
signal(SIGTTOU, SIG_IGN);
|
|
||||||
|
|
||||||
char* pass = getpass();
|
char* pass = getpass();
|
||||||
if (!pass) return 1;
|
if (!pass) return 1;
|
||||||
|
|
||||||
@ -127,7 +102,6 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
chdir(entry->pw_dir);
|
chdir(entry->pw_dir);
|
||||||
clearenv();
|
clearenv();
|
||||||
setenv("PATH", "/bin:/sbin", 1);
|
setenv("PATH", "/bin:/sbin", 1);
|
||||||
setpgid(0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (login || entry->pw_uid != 0) setenv("USER", entry->pw_name, 1);
|
if (login || entry->pw_uid != 0) setenv("USER", entry->pw_name, 1);
|
||||||
|
@ -186,7 +186,6 @@ extern "C" void arch_interrupt_entry(Registers* regs)
|
|||||||
{
|
{
|
||||||
SyscallArgs args = { regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9 };
|
SyscallArgs args = { regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8, regs->r9 };
|
||||||
regs->rax = (u64)invoke_syscall(regs, args, regs->rax);
|
regs->rax = (u64)invoke_syscall(regs, args, regs->rax);
|
||||||
Scheduler::current()->process_pending_signals(regs);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -15,42 +15,15 @@
|
|||||||
static Buffer g_console_input;
|
static Buffer g_console_input;
|
||||||
static bool g_eof { false };
|
static bool g_eof { false };
|
||||||
static bool g_echo { true };
|
static bool g_echo { true };
|
||||||
static bool g_stop_background_output { false };
|
|
||||||
|
|
||||||
static Option<pid_t> g_foreground_process_group;
|
|
||||||
|
|
||||||
Result<void> ConsoleDevice::create()
|
Result<void> ConsoleDevice::create()
|
||||||
{
|
{
|
||||||
auto device = (SharedPtr<Device>)TRY(make_shared<ConsoleDevice>());
|
auto device = (SharedPtr<Device>)TRY(make_shared<ConsoleDevice>());
|
||||||
g_foreground_process_group = {};
|
|
||||||
return DeviceRegistry::register_special_device(DeviceRegistry::Console, 0, device);
|
return DeviceRegistry::register_special_device(DeviceRegistry::Console, 0, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result<void> handle_background_process_group(bool can_succeed, int signo)
|
|
||||||
{
|
|
||||||
if (!g_foreground_process_group.has_value()) return {};
|
|
||||||
|
|
||||||
auto foreground_pgrp = g_foreground_process_group.value();
|
|
||||||
|
|
||||||
auto* current = Scheduler::current();
|
|
||||||
if ((pid_t)current->pgid == foreground_pgrp) return {};
|
|
||||||
|
|
||||||
if ((current->signal_mask & (1 << (signo - 1))) || (current->signal_handlers[signo - 1].sa_handler == SIG_IGN))
|
|
||||||
{
|
|
||||||
if (can_succeed) return {};
|
|
||||||
return err(EIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
current->send_signal(signo);
|
|
||||||
|
|
||||||
if (can_succeed) return err(EINTR);
|
|
||||||
return err(EIO);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<usize> ConsoleDevice::read(u8* buf, usize, usize length) const
|
Result<usize> ConsoleDevice::read(u8* buf, usize, usize length) const
|
||||||
{
|
{
|
||||||
TRY(handle_background_process_group(false, SIGTTIN));
|
|
||||||
|
|
||||||
if (length > g_console_input.size()) length = g_console_input.size();
|
if (length > g_console_input.size()) length = g_console_input.size();
|
||||||
|
|
||||||
memcpy(buf, g_console_input.data(), length);
|
memcpy(buf, g_console_input.data(), length);
|
||||||
@ -66,8 +39,6 @@ Result<usize> ConsoleDevice::read(u8* buf, usize, usize length) const
|
|||||||
|
|
||||||
Result<usize> ConsoleDevice::write(const u8* buf, usize, usize length)
|
Result<usize> ConsoleDevice::write(const u8* buf, usize, usize length)
|
||||||
{
|
{
|
||||||
if (g_stop_background_output) TRY(handle_background_process_group(true, SIGTTOU));
|
|
||||||
|
|
||||||
TextConsole::write((const char*)buf, length);
|
TextConsole::write((const char*)buf, length);
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
@ -92,36 +63,19 @@ void ConsoleDevice::did_press_key(char key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ctrl+D
|
// Ctrl+D
|
||||||
if (key == 'd' && (Keyboard::modifiers() == Keyboard::LeftControl))
|
if (key == 'd' && (Keyboard::modifiers() & Keyboard::LeftControl))
|
||||||
{
|
{
|
||||||
if (g_temp_input.size() == 0) g_eof = true;
|
if (g_temp_input.size() == 0) g_eof = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == 'c' && (Keyboard::modifiers() == Keyboard::LeftControl))
|
if (key == 'e' && (Keyboard::modifiers() & (Keyboard::LeftAlt | Keyboard::LeftControl)))
|
||||||
{
|
|
||||||
g_temp_input.clear();
|
|
||||||
|
|
||||||
if (g_echo) TextConsole::wprintln(L"^C");
|
|
||||||
|
|
||||||
if (g_foreground_process_group.has_value())
|
|
||||||
{
|
|
||||||
Scheduler::for_each_in_process_group(g_foreground_process_group.value(), [](Thread* thread) {
|
|
||||||
thread->send_signal(SIGINT);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key == 'e' && (Keyboard::modifiers() == (Keyboard::LeftAlt | Keyboard::LeftControl)))
|
|
||||||
{
|
{
|
||||||
Scheduler::dump_state();
|
Scheduler::dump_state();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == 'm' && (Keyboard::modifiers() == (Keyboard::LeftAlt | Keyboard::LeftControl)))
|
if (key == 'm' && (Keyboard::modifiers() & (Keyboard::LeftAlt | Keyboard::LeftControl)))
|
||||||
{
|
{
|
||||||
kinfoln("Total memory: %s", to_dynamic_unit(MemoryManager::total()).release_value().chars());
|
kinfoln("Total memory: %s", to_dynamic_unit(MemoryManager::total()).release_value().chars());
|
||||||
kinfoln("Free memory: %s", to_dynamic_unit(MemoryManager::free()).release_value().chars());
|
kinfoln("Free memory: %s", to_dynamic_unit(MemoryManager::free()).release_value().chars());
|
||||||
@ -130,7 +84,7 @@ void ConsoleDevice::did_press_key(char key)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == 'h' && (Keyboard::modifiers() == (Keyboard::LeftAlt | Keyboard::LeftControl)))
|
if (key == 'h' && (Keyboard::modifiers() & (Keyboard::LeftAlt | Keyboard::LeftControl)))
|
||||||
{
|
{
|
||||||
dump_heap_usage();
|
dump_heap_usage();
|
||||||
return;
|
return;
|
||||||
@ -159,38 +113,15 @@ Result<u64> ConsoleDevice::ioctl(int request, void* arg)
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (g_echo) tc.c_lflag |= ECHO;
|
if (g_echo) tc.c_lflag |= ECHO;
|
||||||
if (g_stop_background_output) tc.c_lflag |= TOSTOP;
|
|
||||||
return MemoryManager::copy_to_user_typed((struct termios*)arg, &tc) ? 0 : err(EFAULT);
|
return MemoryManager::copy_to_user_typed((struct termios*)arg, &tc) ? 0 : err(EFAULT);
|
||||||
}
|
}
|
||||||
case TCSETS: {
|
case TCSETS: {
|
||||||
TRY(handle_background_process_group(true, SIGTTOU));
|
|
||||||
|
|
||||||
struct termios tc;
|
struct termios tc;
|
||||||
if (!MemoryManager::copy_from_user_typed((const struct termios*)arg, &tc)) return err(EFAULT);
|
if (!MemoryManager::copy_from_user_typed((const struct termios*)arg, &tc)) return err(EFAULT);
|
||||||
if (tc.c_lflag & ECHO) g_echo = true;
|
if (tc.c_lflag & ECHO) g_echo = true;
|
||||||
else
|
else
|
||||||
g_echo = false;
|
g_echo = false;
|
||||||
|
|
||||||
if (tc.c_lflag & TOSTOP) g_stop_background_output = true;
|
|
||||||
else
|
|
||||||
g_stop_background_output = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case TIOCSPGRP: {
|
|
||||||
TRY(handle_background_process_group(true, SIGTTOU));
|
|
||||||
|
|
||||||
pid_t pgid;
|
|
||||||
if (!MemoryManager::copy_from_user_typed((const pid_t*)arg, &pgid)) return err(EFAULT);
|
|
||||||
|
|
||||||
bool pgid_exists = false;
|
|
||||||
Scheduler::for_each_in_process_group(pgid, [&pgid_exists](Thread*) {
|
|
||||||
pgid_exists = true;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
if (!pgid_exists) return err(EPERM);
|
|
||||||
|
|
||||||
g_foreground_process_group = pgid;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default: return err(EINVAL);
|
default: return err(EINVAL);
|
||||||
|
@ -15,6 +15,8 @@ i64 invoke_syscall(Registers* regs, SyscallArgs args, u64 syscall)
|
|||||||
|
|
||||||
auto rc = syscalls[syscall](regs, args);
|
auto rc = syscalls[syscall](regs, args);
|
||||||
|
|
||||||
|
Scheduler::current()->process_pending_signals(regs);
|
||||||
|
|
||||||
if (rc.has_error()) return -rc.error();
|
if (rc.has_error()) return -rc.error();
|
||||||
return (i64)rc.value();
|
return (i64)rc.value();
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <luna/SafeArithmetic.h>
|
#include <luna/SafeArithmetic.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
Result<u64> sys_read(Registers* regs, SyscallArgs args)
|
Result<u64> sys_read(Registers*, SyscallArgs args)
|
||||||
{
|
{
|
||||||
int fd = (int)args[0];
|
int fd = (int)args[0];
|
||||||
u8* buf = (u8*)args[1];
|
u8* buf = (u8*)args[1];
|
||||||
@ -31,13 +31,6 @@ Result<u64> sys_read(Registers* regs, SyscallArgs args)
|
|||||||
if (descriptor.should_block()) kernel_sleep(10);
|
if (descriptor.should_block()) kernel_sleep(10);
|
||||||
else
|
else
|
||||||
return err(EAGAIN);
|
return err(EAGAIN);
|
||||||
|
|
||||||
if (current->interrupted)
|
|
||||||
{
|
|
||||||
kdbgln("signal: read interrupted by signal");
|
|
||||||
if (current->will_invoke_signal_handler()) return err(EINTR);
|
|
||||||
current->process_pending_signals(regs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usize nread = TRY(descriptor.inode->read(buf, descriptor.offset, size));
|
usize nread = TRY(descriptor.inode->read(buf, descriptor.offset, size));
|
||||||
|
@ -128,20 +128,6 @@ Result<u64> sys_setpgid(Registers*, SyscallArgs args)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<u64> sys_getpgid(Registers*, SyscallArgs args)
|
|
||||||
{
|
|
||||||
pid_t pid = (pid_t)args[0];
|
|
||||||
|
|
||||||
auto* current = Scheduler::current();
|
|
||||||
if (pid == 0) pid = (pid_t)current->id;
|
|
||||||
|
|
||||||
if (pid < 0) return err(EINVAL);
|
|
||||||
|
|
||||||
auto* thread = TRY(Result<Thread*>::from_option(Scheduler::find_by_pid(pid), ESRCH));
|
|
||||||
|
|
||||||
return (u64)thread->pgid;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<u64> sys_fchmodat(Registers*, SyscallArgs args)
|
Result<u64> sys_fchmodat(Registers*, SyscallArgs args)
|
||||||
{
|
{
|
||||||
int dirfd = (int)args[0];
|
int dirfd = (int)args[0];
|
||||||
|
@ -11,7 +11,5 @@ Result<u64> sys_usleep(Registers*, SyscallArgs args)
|
|||||||
|
|
||||||
kernel_sleep(us / 1000);
|
kernel_sleep(us / 1000);
|
||||||
|
|
||||||
auto* current = Scheduler::current();
|
return 0;
|
||||||
|
|
||||||
return current->sleep_ticks_left;
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#include "Log.h"
|
|
||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
#include "sys/Syscall.h"
|
#include "sys/Syscall.h"
|
||||||
#include "thread/Scheduler.h"
|
#include "thread/Scheduler.h"
|
||||||
#include <bits/waitpid.h>
|
#include <bits/waitpid.h>
|
||||||
|
|
||||||
Result<u64> sys_waitpid(Registers* regs, SyscallArgs args)
|
Result<u64> sys_waitpid(Registers*, SyscallArgs args)
|
||||||
{
|
{
|
||||||
pid_t pid = (pid_t)args[0];
|
pid_t pid = (pid_t)args[0];
|
||||||
int* status_ptr = (int*)args[1];
|
int* status_ptr = (int*)args[1];
|
||||||
@ -22,16 +21,7 @@ Result<u64> sys_waitpid(Registers* regs, SyscallArgs args)
|
|||||||
|
|
||||||
if (options & WNOHANG) return err(EAGAIN);
|
if (options & WNOHANG) return err(EAGAIN);
|
||||||
|
|
||||||
wait_for_child:
|
|
||||||
if (thread->state != ThreadState::Exited) kernel_wait(pid);
|
if (thread->state != ThreadState::Exited) kernel_wait(pid);
|
||||||
if (current->interrupted)
|
|
||||||
{
|
|
||||||
kdbgln("signal: waitpid interrupted by signal");
|
|
||||||
if (current->will_invoke_signal_handler()) return err(EINTR);
|
|
||||||
current->process_pending_signals(regs);
|
|
||||||
goto wait_for_child;
|
|
||||||
}
|
|
||||||
|
|
||||||
check(thread->state == ThreadState::Exited);
|
check(thread->state == ThreadState::Exited);
|
||||||
}
|
}
|
||||||
else if (pid == -1)
|
else if (pid == -1)
|
||||||
@ -43,16 +33,7 @@ Result<u64> sys_waitpid(Registers* regs, SyscallArgs args)
|
|||||||
{
|
{
|
||||||
if (options & WNOHANG) return err(EAGAIN);
|
if (options & WNOHANG) return err(EAGAIN);
|
||||||
|
|
||||||
wait_for_any_child:
|
|
||||||
kernel_wait(pid);
|
kernel_wait(pid);
|
||||||
if (current->interrupted)
|
|
||||||
{
|
|
||||||
kdbgln("signal: waitpid interrupted by signal");
|
|
||||||
if (current->will_invoke_signal_handler()) return err(EINTR);
|
|
||||||
current->process_pending_signals(regs);
|
|
||||||
goto wait_for_any_child;
|
|
||||||
}
|
|
||||||
|
|
||||||
check(current->child_being_waited_for.value_or(-1) != -1);
|
check(current->child_being_waited_for.value_or(-1) != -1);
|
||||||
|
|
||||||
thread = TRY(Result<Thread*>::from_option(Scheduler::find_by_pid(*current->child_being_waited_for), ESRCH));
|
thread = TRY(Result<Thread*>::from_option(Scheduler::find_by_pid(*current->child_being_waited_for), ESRCH));
|
||||||
|
@ -135,7 +135,6 @@ namespace Scheduler
|
|||||||
thread->state = ThreadState::None;
|
thread->state = ThreadState::None;
|
||||||
thread->is_kernel = false;
|
thread->is_kernel = false;
|
||||||
thread->id = 1;
|
thread->id = 1;
|
||||||
thread->pgid = 1;
|
|
||||||
thread->name = name;
|
thread->name = name;
|
||||||
thread->auth = Credentials { .uid = 0, .euid = 0, .suid = 0, .gid = 0, .egid = 0, .sgid = 0 };
|
thread->auth = Credentials { .uid = 0, .euid = 0, .suid = 0, .gid = 0, .egid = 0, .sgid = 0 };
|
||||||
|
|
||||||
|
@ -110,7 +110,6 @@ enum class DefaultSignalAction
|
|||||||
Terminate,
|
Terminate,
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Implement coredumps for some signals.
|
|
||||||
static constexpr DefaultSignalAction default_actions[] = {
|
static constexpr DefaultSignalAction default_actions[] = {
|
||||||
DefaultSignalAction::Terminate, // SIGHUP
|
DefaultSignalAction::Terminate, // SIGHUP
|
||||||
DefaultSignalAction::Terminate, // SIGINT
|
DefaultSignalAction::Terminate, // SIGINT
|
||||||
@ -127,13 +126,10 @@ static constexpr DefaultSignalAction default_actions[] = {
|
|||||||
DefaultSignalAction::Terminate, // SIGPIPE
|
DefaultSignalAction::Terminate, // SIGPIPE
|
||||||
DefaultSignalAction::Terminate, // SIGALRM
|
DefaultSignalAction::Terminate, // SIGALRM
|
||||||
DefaultSignalAction::Terminate, // SIGTERM
|
DefaultSignalAction::Terminate, // SIGTERM
|
||||||
DefaultSignalAction::Terminate, // SIGTTIN
|
|
||||||
DefaultSignalAction::Terminate, // SIGTTOU
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void Thread::process_pending_signals(Registers* current_regs)
|
void Thread::process_pending_signals(Registers* current_regs)
|
||||||
{
|
{
|
||||||
interrupted = false;
|
|
||||||
for (int i = 0; i < NSIG; i++)
|
for (int i = 0; i < NSIG; i++)
|
||||||
{
|
{
|
||||||
int signo = i + 1;
|
int signo = i + 1;
|
||||||
@ -176,33 +172,10 @@ void Thread::process_pending_signals(Registers* current_regs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thread::will_invoke_signal_handler()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NSIG; i++)
|
|
||||||
{
|
|
||||||
if (pending_signals & (1 << i))
|
|
||||||
{
|
|
||||||
int signo = i + 1;
|
|
||||||
if (signo != SIGKILL && signo != SIGSTOP && signal_mask & (1 << i)) continue;
|
|
||||||
auto handler = signal_handlers[i];
|
|
||||||
if (handler.sa_handler == SIG_IGN || handler.sa_handler == SIG_DFL) return false;
|
|
||||||
if (signo == SIGKILL || signo == SIGSTOP) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Thread::send_signal(int signo)
|
void Thread::send_signal(int signo)
|
||||||
{
|
{
|
||||||
check(signo > 0 && signo <= NSIG);
|
check(signo > 0 && signo <= NSIG);
|
||||||
pending_signals |= 1 << (signo - 1);
|
pending_signals |= 1 << (signo - 1);
|
||||||
|
|
||||||
if (state == ThreadState::Waiting || state == ThreadState::Sleeping)
|
|
||||||
{
|
|
||||||
interrupted = true;
|
|
||||||
wake_up();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileDescriptor::should_append()
|
bool FileDescriptor::should_append()
|
||||||
|
@ -84,7 +84,6 @@ struct Thread : public LinkedListNode<Thread>
|
|||||||
struct sigaction signal_handlers[NSIG];
|
struct sigaction signal_handlers[NSIG];
|
||||||
sigset_t signal_mask { 0 };
|
sigset_t signal_mask { 0 };
|
||||||
sigset_t pending_signals { 0 };
|
sigset_t pending_signals { 0 };
|
||||||
bool interrupted { false };
|
|
||||||
|
|
||||||
FPData fp_data;
|
FPData fp_data;
|
||||||
|
|
||||||
@ -140,8 +139,6 @@ struct Thread : public LinkedListNode<Thread>
|
|||||||
|
|
||||||
void process_pending_signals(Registers* current_regs);
|
void process_pending_signals(Registers* current_regs);
|
||||||
|
|
||||||
bool will_invoke_signal_handler();
|
|
||||||
|
|
||||||
bool deliver_signal(int signo, Registers* current_regs);
|
bool deliver_signal(int signo, Registers* current_regs);
|
||||||
void sigreturn(Registers* current_regs);
|
void sigreturn(Registers* current_regs);
|
||||||
|
|
||||||
|
@ -49,8 +49,6 @@ enum __signals
|
|||||||
SIGPIPE = 13,
|
SIGPIPE = 13,
|
||||||
SIGALRM = 14,
|
SIGALRM = 14,
|
||||||
SIGTERM = 15,
|
SIGTERM = 15,
|
||||||
SIGTTIN = 16,
|
|
||||||
SIGTTOU = 17,
|
|
||||||
// FIXME: Add the remaining signals.
|
// FIXME: Add the remaining signals.
|
||||||
__NSIG,
|
__NSIG,
|
||||||
};
|
};
|
||||||
|
@ -13,11 +13,9 @@ struct termios
|
|||||||
|
|
||||||
// Values for c_lflag.
|
// Values for c_lflag.
|
||||||
#define ECHO 1
|
#define ECHO 1
|
||||||
#define TOSTOP 2
|
|
||||||
|
|
||||||
// termios ioctl() requests.
|
// termios ioctl() requests.
|
||||||
#define TCGETS 0
|
#define TCGETS 0
|
||||||
#define TCSETS 1
|
#define TCSETS 1
|
||||||
#define TIOCSPGRP 2
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -45,9 +45,6 @@ extern "C"
|
|||||||
/* Return the current process' effective group ID. */
|
/* Return the current process' effective group ID. */
|
||||||
gid_t getegid(void);
|
gid_t getegid(void);
|
||||||
|
|
||||||
/* Return a process' process group ID. */
|
|
||||||
pid_t getpgid(pid_t pid);
|
|
||||||
|
|
||||||
/* Set the current process' user IDs. */
|
/* Set the current process' user IDs. */
|
||||||
int setuid(uid_t uid);
|
int setuid(uid_t uid);
|
||||||
|
|
||||||
|
@ -33,8 +33,6 @@ extern "C"
|
|||||||
case SIGPIPE: return "Broken pipe";
|
case SIGPIPE: return "Broken pipe";
|
||||||
case SIGALRM: return "Alarm signal";
|
case SIGALRM: return "Alarm signal";
|
||||||
case SIGTERM: return "Terminated";
|
case SIGTERM: return "Terminated";
|
||||||
case SIGTTIN: return "Background process stopped (terminal input)";
|
|
||||||
case SIGTTOU: return "Background process stopped (terminal output)";
|
|
||||||
default: return "Unknown signal";
|
default: return "Unknown signal";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,12 +120,6 @@ extern "C"
|
|||||||
return (gid_t)syscall(SYS_getegid);
|
return (gid_t)syscall(SYS_getegid);
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t getpgid(pid_t pid)
|
|
||||||
{
|
|
||||||
long rc = syscall(SYS_getpgid, pid);
|
|
||||||
__errno_return(rc, pid_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
int setuid(uid_t uid)
|
int setuid(uid_t uid)
|
||||||
{
|
{
|
||||||
long rc = syscall(SYS_setuid, uid);
|
long rc = syscall(SYS_setuid, uid);
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
_e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \
|
_e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) _e(ioctl) \
|
||||||
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
||||||
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \
|
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \
|
||||||
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask) _e(setpgid) _e(isatty) \
|
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask) _e(setpgid) _e(isatty)
|
||||||
_e(getpgid)
|
|
||||||
|
|
||||||
enum Syscalls
|
enum Syscalls
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user