Compare commits

..

59 commits

Author SHA1 Message Date
Jonas 'Sortie' Termansen
c6c285a414 fixup! Add init groups. 2024-06-18 23:23:36 +02:00
Jonas 'Sortie' Termansen
b9c49648c4 fixup! Add init groups. 2024-06-18 23:03:47 +02:00
Jonas 'Sortie' Termansen
e2a55139ad fixup! Add init groups. 2024-06-18 22:55:26 +02:00
Jonas 'Sortie' Termansen
870cfa3668 Fix ppoll(2) EINTR handling. 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
d7ab7c552e Add pstree(1) -is options. 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
d1632a9706 Add chroot(8) -I option. 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
bd3d7df078 Modernize chroot(8). 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
9c3ed11e09 Prevent init(8) from using the tty when a daemon uses it. 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
cacb2e9c8e Run daemons in their own session. 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
d07beee30a Add init groups.
Every process now has an init process like it has a session, and each
session belong to an init. Orphaned processes are reparented to its init
process. All descendent processes are SIGKILL'd when an init process exits
and creating additional processes/threads fails.

Add setinit(2) for becoming the init process for your child processes and
add getinit(2) for locating your init process.

Add TIOCSCTTY force flag that releases a terminal from its current session
and makes it the controlling terminal for the current session. This ioctl
is essential to transferring the controlling terminal to a nested init,
which has its own session.

Add TIOCUCTTY that releases the terminal as the controlling terminal for
its current session.

Remove INIT_PID as it is replaced by getinit(2).
2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
2d221e1ff1 Add service(8). 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
bb7bd58ea8 Add checksum(1) --cache option. 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
c14c3c2e99 Add php port. 2024-06-18 22:17:07 +02:00
Jonas 'Sortie' Termansen
d4115c424a Revert "Update to perl-5.39.5."
This reverts commit 781ff8880f3e2d29e31460427bccf50cc1ec436e.

File/Spec was no longer being installed when --all-static, breaking
texinfo.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
c3c5463e61 Update to perl-5.39.5. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
cd9da4da59 Revert "Update to python-3.12.1."
This reverts commit 8ae8363167cc195f92803489e2f97391e2527c5f.

The libglib build broke due to no distutils module.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
f757228bd8 Update to python-3.12.1. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
0b2c6b91a0 Revert "Update to texinfo-7.1."
This reverts commit 9813bb1d13c625d48ecd950bfaafc274383ca049.

ffmpeg fails to build natively with the new makeinfo:

perl ./doc/texidep.pl . doc/ffmpeg-utils.texi doc/ffmpeg-utils.html >doc/ffmpeg-utils.html.d
makeinfo --html -I doc --no-split -D config-not-all --init-file=./doc/t2h.pm --output doc/ffmpeg-utils.html doc/ffmpeg-utils.texi
makeinfo: error parsing ./doc/t2h.pm: Undefined subroutine &Texinfo::Config::set_from_init_file called at ./doc/t2h.pm line 24.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
c741dc1863 Update to texinfo-7.1. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
5abfe83b3a Revert "Update to dash-0.5.12."
This reverts commit 16bedfc9630779c01ebae5513fd307e969c329de.

Something is wrong with the case pattern matching, maybe fnmatch?
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
70d133ca8a Update to dash-0.5.12. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
f549ab4b77 Revert "Update to freetype-2.13.2."
This reverts commit 5ad1e5f6054dd1e44ecb955b9326c1198ef17ff0.

configure runs make and crashes on a stack overflow in make.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
f287d7298a Update to freetype-2.13.2. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
824df667b2 Revert "Update to bison-3.8.2."
This reverts commit b82fae810b42c5426d21c4dc153b32f086dd7fde.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
9c23917c11 Update to bison-3.8.2. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
5b61b05fec Revert "Schedule interactive threads fairly under load."
This reverts commit 47731b91c37933943a73010c5a4494101cce52dc.

There is a rare freeze when the scheduler fails to run anything.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
2883ecb5ff Schedule interactive threads fairly under load.
Preempted threads are now removed from the runnable list until every
other thread has been preempted or the system goes idle. This ensures
threads that roundtrip to other threads get a full chance to perform
their work cooperatively without being starved by CPU intensive threads
whenever they yield.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
2710f60690 Kinda fix pager(1) man bullet points. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
c4e0a79bc1 Fix ESP endian. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
8f466ecc13 Support booting with EFI. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
d1574c1682 Add kernel(7) --firmware option. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
9a0670f055 Add fatfs(8). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
18aab49cad Add getty(8). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
5a877ea44b Add terminal and interrupt support to com(4). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
365ada713e Add nyan(1). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
3ba95b7415 Work around pty deadlock. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
1e4acb7401 Add cdrom mounting live environment. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
1e9cd96738 Revert "Parallelize driver initialization."
This reverts commit 0fef08bbc4.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
e0d5ebc747 Parallelize driver initialization. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
762f4feb75 Speed up ata(4) 400 ns waits.
Waiting for any non-zero duration currently waits for at least one timer
cycle (10 ms), which is especially expensive during early boot.

The current workaround of simply reading the status 14 times seems really
suspicious although the osdev wiki documents it, but let's see how well it
works on real hardware, it's probably good enough.

Try to determine the initial selected drive to save one drive selection.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
8bb8718327 Decrease PS/2 timeouts. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
0e12ffcf60 Add uptime(1) -pr options. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
eef9932761 Add iso9660 filesystem implementation. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
0135f8a6fa Add kernel virtual address space usage debug information. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
59c69f4ee9 Debug TCP socket state listing. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
718fae5b87 Add kernel heap allocation tracing debug facility. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
56517529c0 Trianglix 4. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
e664dd5998 Add tix-check(8). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
561771df54 Volatile release. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
4e56ca101c Add tix-upgrade(8). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
c9ca26f108 Add tix-repository(8).
Support renaming, splitting, and deleting ports via RENAMES.

Unify on RUNTIME_DEPS for runtime dependencies.
2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
ea2e033ad6 Add signify port. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
07694a1ee1 Add pty(1). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
74aa386f39 Add getaddrinfo(1). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
36d95209dc Enable stack smash protection by default. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
359b1a8642 Enable undefined behavior sanitization by default. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
77ad36cda8 Handle SIGWINCH in editor(1). 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
faf0acef59 Implement SIGWINCH. 2024-06-18 22:17:06 +02:00
Jonas 'Sortie' Termansen
1f840b1e36 Separate filesystem socket namespace inside chroots. 2024-06-18 22:17:06 +02:00
33 changed files with 355 additions and 791 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, 2016, 2023, 2024 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2023 Juhani 'nortti' Krekelä.
*
* Permission to use, copy, modify, and distribute this software for any
@ -149,15 +149,15 @@ CONNECTION_MESSAGE_HANDLER_NO_AUX(shutdown)
{
(void) connection;
if ( msg->code == 0 )
display_exit(server->display, 0);
exit(0);
else if ( msg->code == 1 )
display_exit(server->display, 1);
exit(1);
else if ( msg->code == 2 )
display_exit(server->display, 2);
exit(2);
else if ( msg->code == 3 )
display_exit(server->display, 3);
exit(3);
else
display_exit(server->display, 0);
exit(0);
}
CONNECTION_MESSAGE_HANDLER_NO_AUX(create_window)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, 2016, 2024 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -25,7 +25,6 @@
#include <display-protocol.h>
#include "display.h"
#include "server.h"
#include "window.h"

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2016, 2018, 2022-2024 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2016, 2018, 2022, 2023 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -23,8 +23,6 @@
#include <assert.h>
#include <err.h>
#include <inttypes.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@ -49,43 +47,6 @@ void display_initialize(struct display* display)
{
memset(display, 0, sizeof(*display));
display->redraw = true;
display->running = true;
}
static int get_init_exit_plan(void)
{
FILE* fp = popen("/sbin/service default exit-code", "r");
if ( !fp )
return -1;
int result = -1;
char buffer[sizeof(int) * 3];
if ( fgets(buffer, sizeof(buffer), fp) && buffer[0] )
result = atoi(buffer);
pclose(fp);
return result;
}
void display_exit(struct display* display, int exit_code)
{
display->running = false;
display->exit_code = exit_code;
int plan = exit_code == -1 ? get_init_exit_plan() : exit_code;
display->announcement = "Exiting...";
if ( plan == 0 )
display->announcement = "Powering off...";
else if ( plan == 1 )
display->announcement = "Rebooting...";
else if ( plan == 2 )
display->announcement = "Halting...";
else if ( plan == 3 )
display->announcement = "Reinitializing operating system...";
else if ( getenv("LOGIN_PID") ) // TODO: display -l?
{
intmax_t login_pid = strtoimax(getenv("LOGIN_PID"), NULL, 10);
if ( login_pid == getppid() )
display->announcement = "Logging out...";
}
display->redraw = true;
}
void assert_is_well_formed_display_list(struct display* display)
@ -320,31 +281,6 @@ static void wallpaper(struct framebuffer fb)
}
}
static void display_render_exit(struct display* display, struct framebuffer fb)
{
for ( int yoff = -1; yoff <= 1; yoff++ )
{
for ( int xoff = -1; xoff <= 1; xoff++ )
{
struct framebuffer msgfb = fb;
int y = (fb.yres - FONT_HEIGHT) / 2 + yoff;
msgfb = framebuffer_cut_top_y(msgfb, y);
int w = strlen(display->announcement) * (FONT_WIDTH+1);
int x = (fb.xres - w) / 2 + xoff;
msgfb = framebuffer_cut_left_x(msgfb, x);
render_text(msgfb, display->announcement, make_color_a(0, 0, 0, 64));
}
}
struct framebuffer msgfb = fb;
int y = (fb.yres - FONT_HEIGHT) / 2;
msgfb = framebuffer_cut_top_y(msgfb, y);
int w = strlen(display->announcement) * (FONT_WIDTH+1);
int x = (fb.xres - w) / 2;
msgfb = framebuffer_cut_left_x(msgfb, x);
render_text(msgfb, display->announcement, make_color(255, 255, 255));
}
void display_composit(struct display* display, struct framebuffer fb)
{
struct damage_rect damage_rect = display->damage_rect;
@ -365,12 +301,6 @@ void display_composit(struct display* display, struct framebuffer fb)
framebuffer_copy_to_framebuffer(fb, display->wallpaper);
if ( display->announcement )
{
display_render_exit(display, fb);
return;
}
for ( struct window* window = display->bottom_window;
window;
window = window->above_window )
@ -552,15 +482,11 @@ void display_keyboard_event(struct display* display, uint32_t codepoint)
case KBKEY_RSUPER: display->key_rsuper = kbkey > 0; break;
}
if ( display->key_lctrl && display->key_lalt && kbkey == KBKEY_DELETE )
display_exit(display, -1);
exit(0);
if ( display->key_lctrl && display->key_lalt && kbkey == KBKEY_T )
{
if ( !fork() )
{
sigset_t sigterm;
sigemptyset(&sigterm);
sigaddset(&sigterm, SIGTERM);
sigprocmask(SIG_UNBLOCK, &sigterm, NULL);
execlp("terminal", "terminal", (char*) NULL);
_exit(127);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2017, 2022-2024 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2016, 2017, 2022, 2023 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -119,5 +119,5 @@ int main(int argc, char* argv[])
server_mainloop(&server);
return display.exit_code;
return 0;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, 2016, 2022, 2023, 2024 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2016, 2022, 2023 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -68,19 +68,14 @@ struct display
bool key_rsuper;
bool codepoint_discard;
bool redraw;
bool running;
int pointer_x;
int pointer_y;
enum mouse_state mouse_state;
size_t mouse_byte_count;
uint8_t mouse_bytes[MOUSE_PACKET_SIZE];
const char* announcement;
int exit_code;
};
void display_initialize(struct display* display);
void display_exit(struct display* display, int exit_code);
void assert_is_well_formed_display_list(struct display* display);
void assert_is_well_formed_display(struct display* display);
void display_link_window_at_top(struct display* display, struct window* window);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, 2016, 2023, 2024 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2016, 2023 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -28,7 +28,6 @@
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@ -41,14 +40,6 @@
#include "server.h"
#include "vgafont.h"
static volatile sig_atomic_t got_sigterm;
static void on_sigterm(int signum)
{
(void) signum;
got_sigterm = 1;
}
static int open_local_server_socket(const char* path, int flags)
{
size_t path_length = strlen(path);
@ -205,24 +196,9 @@ void server_poll(struct server* server)
}
size_t pfds_used = cpfd_off + connections_polled;
sigset_t mask;
sigprocmask(SIG_SETMASK, NULL, &mask);
sigdelset(&mask, SIGTERM);
int num_events = ppoll(pfds, pfds_used, NULL, &mask);
if ( got_sigterm )
{
display_exit(server->display, -1);
got_sigterm = 0;
}
int num_events = ppoll(pfds, pfds_used, NULL, NULL);
if ( num_events < 0 )
{
if ( errno == EINTR )
return;
err(1, "poll");
}
if ( pfds[0].revents )
{
@ -297,20 +273,9 @@ void server_poll(struct server* server)
void server_mainloop(struct server* server)
{
sigset_t sigterm, oldset;
sigemptyset(&sigterm);
sigaddset(&sigterm, SIGTERM);
sigprocmask(SIG_BLOCK, &sigterm, &oldset);
struct sigaction sa = { .sa_handler = on_sigterm }, old_sa;
sigaction(SIGTERM, &sa, &old_sa);
while ( server->display->running )
while ( true )
{
display_render(server->display);
server_poll(server);
}
display_render(server->display);
sigaction(SIGTERM, &old_sa, NULL);
sigprocmask(SIG_SETMASK, &oldset, NULL);
}

View file

@ -3256,9 +3256,6 @@ static void init(void)
DAEMON_STATE_FINISHING);
default_daemon_exit_code =
WCONSTRUCT(WNATURE_EXITED, caught_exit_signal, 0);
default_daemon->exit_code = default_daemon_exit_code;
default_daemon->exit_code_meaning =
EXIT_CODE_MEANING_POWEROFF_REBOOT;
}
caught_exit_signal = -1;

View file

@ -23,8 +23,6 @@
|
.Sy enable
|
.Sy exit-code
|
.Sy kill
|
.Sy pid
@ -179,10 +177,6 @@ command.
The daemon only starts if the
.Ar source-daemon
is running.
.It Sy exit-code
Write the exit code of the
.Ar daemon ,
or the empty string if it has not exited.
.It Sy kill
Kill the
.Ar daemon

View file

@ -521,8 +521,6 @@ int main(int argc, char* argv[])
fprintf(fp, "status %s\n", daemon);
else if ( !strcmp(command, "pid") )
fprintf(fp, "status %s\n", daemon);
else if ( !strcmp(command, "exit-code") )
fprintf(fp, "status %s\n", daemon);
else if ( !strcmp(command, "requirements") ||
!strcmp(command, "dependents") ||
!strcmp(command, "edges") )
@ -564,19 +562,6 @@ int main(int argc, char* argv[])
}
}
}
else if ( !strcmp(command, "exit-code") )
{
for ( size_t i = 1; i < tokens_count; i++ )
{
if ( !strncmp(tokens[i], "exit=", strlen("exit=")) )
{
const char* arg = tokens[i] + strlen("exit=");
if ( strcmp(arg, "n/a") )
puts(arg);
break;
}
}
}
else if ( !strcmp(command, "requirements") ||
!strcmp(command, "dependents") ||
!strcmp(command, "edges") )

View file

@ -250,7 +250,6 @@ int DevCOMPort::ioctl(ioctx_t* ctx, int cmd, uintptr_t arg)
const struct winsize* user_ws = (const struct winsize*) arg;
if ( !ctx->copy_from_src(&ws, user_ws, sizeof(ws)) )
return -1;
winch();
return 0;
}
lock.Reset();

View file

@ -679,9 +679,9 @@ Ref<Descriptor> Descriptor::open(ioctx_t* ctx, const char* filename, int flags,
mode_t mode)
{
Process* process = CurrentProcess();
kthread_mutex_lock(&process->id_lock);
kthread_mutex_lock(&process->idlock);
mode &= ~process->umask;
kthread_mutex_unlock(&process->id_lock);
kthread_mutex_unlock(&process->idlock);
if ( !filename[0] )
return errno = ENOENT, Ref<Descriptor>();
@ -840,9 +840,9 @@ Ref<Descriptor> Descriptor::open_elem(ioctx_t* ctx, const char* filename,
int Descriptor::mkdir(ioctx_t* ctx, const char* filename, mode_t mode)
{
Process* process = CurrentProcess();
kthread_mutex_lock(&process->id_lock);
kthread_mutex_lock(&process->idlock);
mode &= ~process->umask;
kthread_mutex_unlock(&process->id_lock);
kthread_mutex_unlock(&process->idlock);
char* final;
Ref<Descriptor> dir = OpenDirContainingPath(ctx, Ref<Descriptor>(this),

View file

@ -29,14 +29,14 @@ namespace Sortix {
uid_t sys_getuid()
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
return process->uid;
}
int sys_setuid(uid_t uid)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
// TODO: Implement security checks in many place across the operating system
// and until then allow anyone to do this to not pretend to be secure.
process->uid = uid;
@ -47,14 +47,14 @@ int sys_setuid(uid_t uid)
gid_t sys_getgid()
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
return process->gid;
}
int sys_setgid(gid_t gid)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
// TODO: Implement security checks in many place across the operating system
// and until then allow anyone to do this to not pretend to be secure.
process->gid = gid;
@ -65,14 +65,14 @@ int sys_setgid(gid_t gid)
uid_t sys_geteuid()
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
return process->euid;
}
int sys_seteuid(uid_t euid)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
// TODO: Implement security checks in many place across the operating system
// and until then allow anyone to do this to not pretend to be secure.
process->euid = euid;
@ -82,14 +82,14 @@ int sys_seteuid(uid_t euid)
gid_t sys_getegid()
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
return process->egid;
}
int sys_setegid(gid_t egid)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
// TODO: Implement security checks in many place across the operating system
// and until then allow anyone to do this to not pretend to be secure.
process->egid = egid;

View file

@ -66,17 +66,17 @@ public:
pid_t pid;
public:
kthread_mutex_t nice_lock;
kthread_mutex_t nicelock;
int nice;
public:
kthread_mutex_t id_lock;
kthread_mutex_t idlock;
uid_t uid, euid;
gid_t gid, egid;
mode_t umask;
private:
kthread_mutex_t ptr_lock;
kthread_mutex_t ptrlock;
Ref<Descriptor> tty;
Ref<Descriptor> root;
Ref<Descriptor> cwd;
@ -112,34 +112,34 @@ public:
public:
Process* parent;
Process* prev_sibling;
Process* next_sibling;
Process* first_child;
Process* zombie_child;
Process* prevsibling;
Process* nextsibling;
Process* firstchild;
Process* zombiechild;
Process* group;
Process* group_prev;
Process* group_next;
Process* group_first;
Process* groupprev;
Process* groupnext;
Process* groupfirst;
Process* session;
Process* session_prev;
Process* session_next;
Process* session_first;
Process* sessionprev;
Process* sessionnext;
Process* sessionfirst;
Process* init;
Process* init_prev;
Process* init_next;
Process* init_first;
kthread_mutex_t child_lock;
kthread_mutex_t parent_lock;
kthread_cond_t zombie_cond;
bool is_zombie;
bool no_zombify;
Process* initprev;
Process* initnext;
Process* initfirst;
kthread_mutex_t childlock;
kthread_mutex_t parentlock;
kthread_cond_t zombiecond;
bool iszombie;
bool nozombify;
bool limbo;
bool is_init_exiting;
int exit_code;
public:
Thread* first_thread;
kthread_mutex_t thread_lock;
Thread* firstthread;
kthread_mutex_t threadlock;
size_t threads_not_exiting_count;
bool threads_exiting;

View file

@ -79,8 +79,8 @@ public:
struct thread_registers registers;
size_t id;
Process* process;
Thread* prev_sibling;
Thread* next_sibling;
Thread* prevsibling;
Thread* nextsibling;
Thread* scheduler_list_prev;
Thread* scheduler_list_next;
volatile ThreadState state;
@ -88,12 +88,12 @@ public:
sigset_t signal_mask;
sigset_t saved_signal_mask;
stack_t signal_stack;
addr_t kernel_stack_pos;
size_t kernel_stack_size;
addr_t kernelstackpos;
size_t kernelstacksize;
size_t signal_count;
uintptr_t signal_single_frame;
uintptr_t signal_canary;
bool kernel_stack_malloced;
bool kernelstackmalloced;
bool pledged_destruction;
bool force_no_signals;
bool signal_single;

View file

@ -27,7 +27,7 @@ namespace Sortix {
void SetupUserIOCtx(ioctx_t* ctx)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
ctx->uid = ctx->auth_uid = process->uid;
ctx->gid = ctx->auth_gid = process->gid;
ctx->copy_to_dest = CopyToUser;
@ -39,7 +39,7 @@ void SetupUserIOCtx(ioctx_t* ctx)
void SetupKernelIOCtx(ioctx_t* ctx)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
ctx->uid = ctx->auth_uid = process->uid;
ctx->gid = ctx->auth_gid = process->gid;
ctx->copy_to_dest = CopyToKernel;

View file

@ -374,17 +374,17 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo_p)
ptable.Reset();
system->addrspace = Memory::GetAddressSpace();
system->group = system;
system->group_prev = NULL;
system->group_next = NULL;
system->group_first = system;
system->groupprev = NULL;
system->groupnext = NULL;
system->groupfirst = system;
system->session = system;
system->session_prev = NULL;
system->session_next = NULL;
system->session_first = system;
system->sessionprev = NULL;
system->sessionnext = NULL;
system->sessionfirst = system;
system->init = NULL;
system->init_prev = NULL;
system->init_next = NULL;
system->init_first = NULL;
system->initprev = NULL;
system->initnext = NULL;
system->initfirst = NULL;
if ( !(system->program_image_path = String::Clone("<kernel process>")) )
Panic("Unable to clone string for system process name");
@ -396,10 +396,10 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo_p)
Thread* idlethread = new Thread();
idlethread->name = "idle";
idlethread->process = system;
idlethread->kernel_stack_pos = (addr_t) stack;
idlethread->kernel_stack_size = STACK_SIZE;
idlethread->kernel_stack_malloced = false;
system->first_thread = idlethread;
idlethread->kernelstackpos = (addr_t) stack;
idlethread->kernelstacksize = STACK_SIZE;
idlethread->kernelstackmalloced = false;
system->firstthread = idlethread;
system->threads_not_exiting_count = 1;
Scheduler::SetIdleThread(idlethread);
@ -667,23 +667,23 @@ static void BootThread(void* /*user*/)
kthread_mutex_lock(&process_family_lock);
Process* kernel_process = CurrentProcess();
init->parent = kernel_process;
init->next_sibling = kernel_process->first_child;
init->prev_sibling = NULL;
if ( kernel_process->first_child )
kernel_process->first_child->prev_sibling = init;
kernel_process->first_child = init;
init->nextsibling = kernel_process->firstchild;
init->prevsibling = NULL;
if ( kernel_process->firstchild )
kernel_process->firstchild->prevsibling = init;
kernel_process->firstchild = init;
init->group = init;
init->group_prev = NULL;
init->group_next = NULL;
init->group_first = init;
init->groupprev = NULL;
init->groupnext = NULL;
init->groupfirst = init;
init->session = init;
init->session_prev = NULL;
init->session_next = NULL;
init->session_first = init;
init->sessionprev = NULL;
init->sessionnext = NULL;
init->sessionfirst = init;
init->init = init;
init->init_prev = NULL;
init->init_next = NULL;
init->init_first = init;
init->initprev = NULL;
init->initnext = NULL;
init->initfirst = init;
kthread_mutex_unlock(&process_family_lock);
// TODO: Why don't we fork from pid=0 and this is done for us?

View file

@ -258,9 +258,9 @@ void kthread_exit()
// only threads in this process, except the initial thread. Otherwise more
// threads may appear, and we can't conclude whether this is the last thread
// in the process to exit.
kthread_mutex_lock(&process->thread_lock);
kthread_mutex_lock(&process->threadlock);
bool is_last_to_exit = --process->threads_not_exiting_count == 0;
kthread_mutex_unlock(&process->thread_lock);
kthread_mutex_unlock(&process->threadlock);
// All other threads in the process have committed to exiting, though they
// might not have exited yet. However, we know they are only running the
// below code that schedules thread termination. It's therefore safe to run

View file

@ -202,10 +202,10 @@ PingSocket::PingSocket(int af)
dev = (dev_t) this;
ino = (ino_t) this;
type = S_IFSOCK;
kthread_mutex_lock(&process->id_lock);
kthread_mutex_lock(&process->idlock);
stat_uid = process->uid;
stat_gid = process->gid;
kthread_mutex_unlock(&process->id_lock);
kthread_mutex_unlock(&process->idlock);
stat_mode = 0600 | this->type;
supports_iovec = true;
socket_lock = KTHREAD_MUTEX_INITIALIZER;

View file

@ -2417,10 +2417,10 @@ TCPSocketNode::TCPSocketNode(TCPSocket* socket)
dev = (dev_t) this;
ino = (ino_t) this;
type = S_IFSOCK;
kthread_mutex_lock(&process->id_lock);
kthread_mutex_lock(&process->idlock);
stat_uid = process->uid;
stat_gid = process->gid;
kthread_mutex_unlock(&process->id_lock);
kthread_mutex_unlock(&process->idlock);
stat_mode = 0600 | this->type;
}

View file

@ -175,10 +175,10 @@ UDPSocket::UDPSocket(int af)
dev = (dev_t) this;
ino = (ino_t) this;
type = S_IFSOCK;
kthread_mutex_lock(&process->id_lock);
kthread_mutex_lock(&process->idlock);
stat_uid = process->uid;
stat_gid = process->gid;
kthread_mutex_unlock(&process->id_lock);
kthread_mutex_unlock(&process->idlock);
stat_mode = 0600 | this->type;
supports_iovec = true;
socket_lock = KTHREAD_MUTEX_INITIALIZER;

View file

@ -79,15 +79,15 @@ Process::Process()
addrspace = 0;
pid = 0;
nice_lock = KTHREAD_MUTEX_INITIALIZER;
nicelock = KTHREAD_MUTEX_INITIALIZER;
nice = 0;
id_lock = KTHREAD_MUTEX_INITIALIZER;
idlock = KTHREAD_MUTEX_INITIALIZER;
uid = euid = 0;
gid = egid = 0;
umask = 0022;
ptr_lock = KTHREAD_MUTEX_INITIALIZER;
ptrlock = KTHREAD_MUTEX_INITIALIZER;
// tty set to null reference in the member constructor.
// root set to null reference in the member constructor.
// cwd set to null reference in the member constructor.
@ -116,31 +116,31 @@ Process::Process()
sigreturn = NULL;
parent = NULL;
prev_sibling = NULL;
next_sibling = NULL;
first_child = NULL;
zombie_child = NULL;
prevsibling = NULL;
nextsibling = NULL;
firstchild = NULL;
zombiechild = NULL;
group = NULL;
group_prev = NULL;
group_next = NULL;
group_first = NULL;
groupprev = NULL;
groupnext = NULL;
groupfirst = NULL;
session = NULL;
session_prev = NULL;
session_next = NULL;
session_first = NULL;
sessionprev = NULL;
sessionnext = NULL;
sessionfirst = NULL;
init = NULL;
init_prev = NULL;
init_next = NULL;
init_first = NULL;
zombie_cond = KTHREAD_COND_INITIALIZER;
is_zombie = false;
no_zombify = false;
initprev = NULL;
initnext = NULL;
initfirst = NULL;
zombiecond = KTHREAD_COND_INITIALIZER;
iszombie = false;
nozombify = false;
limbo = false;
is_init_exiting = false;
exit_code = -1;
first_thread = NULL;
thread_lock = KTHREAD_MUTEX_INITIALIZER;
firstthread = NULL;
threadlock = KTHREAD_MUTEX_INITIALIZER;
threads_not_exiting_count = 0;
threads_exiting = false;
@ -170,15 +170,15 @@ Process::~Process() // process_family_lock taken
if ( alarm_timer.IsAttached() )
alarm_timer.Detach();
delete[] program_image_path;
assert(!zombie_child);
assert(!zombiechild);
assert(!init);
assert(!session);
assert(!group);
assert(!parent);
assert(!init_first);
assert(!session_first);
assert(!group_first);
assert(!first_child);
assert(!initfirst);
assert(!sessionfirst);
assert(!groupfirst);
assert(!firstchild);
assert(!addrspace);
assert(!segments);
assert(!dtable);
@ -195,7 +195,7 @@ Process::~Process() // process_family_lock taken
void Process::BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtable)
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(!this->dtable);
assert(!this->mtable);
this->dtable = dtable;
@ -204,7 +204,7 @@ void Process::BootstrapTables(Ref<DescriptorTable> dtable, Ref<MountTable> mtabl
void Process::BootstrapDirectories(Ref<Descriptor> root)
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(!this->root);
assert(!this->cwd);
this->root = root;
@ -223,43 +223,43 @@ void Process::OnLastThreadExit()
// Forbid any more processes and threads from being created, so this
// loop will always terminate.
is_init_exiting = true;
Process* process = first_child;
Process* process = firstchild;
while ( process )
{
if ( process->pid != 0 )
process->DeliverSignal(SIGKILL);
if ( process->init == process )
process->is_init_exiting = true;
if ( process->first_child )
process = process->first_child;
while ( process && process != this && !process->next_sibling )
if ( process->firstchild )
process = process->firstchild;
while ( process && process != this && !process->nextsibling )
process = process->parent;
if ( process == this )
break;
process = process->next_sibling;
process = process->nextsibling;
}
// NotifyChildExit always signals zombie_cond for init when
// NotifyChildExit always signals zombiecond for init when
// is_init_exiting is true.
while ( first_child )
kthread_cond_wait(&zombie_cond, &process_family_lock);
while ( firstchild )
kthread_cond_wait(&zombiecond, &process_family_lock);
}
}
void Process::OnThreadDestruction(Thread* thread)
{
assert(thread->process == this);
kthread_mutex_lock(&thread_lock);
if ( thread->prev_sibling )
thread->prev_sibling->next_sibling = thread->next_sibling;
if ( thread->next_sibling )
thread->next_sibling->prev_sibling = thread->prev_sibling;
if ( thread == first_thread )
first_thread = thread->next_sibling;
if ( first_thread )
first_thread->prev_sibling = NULL;
thread->prev_sibling = thread->next_sibling = NULL;
bool threadsleft = first_thread;
kthread_mutex_unlock(&thread_lock);
kthread_mutex_lock(&threadlock);
if ( thread->prevsibling )
thread->prevsibling->nextsibling = thread->nextsibling;
if ( thread->nextsibling )
thread->nextsibling->prevsibling = thread->prevsibling;
if ( thread == firstthread )
firstthread = thread->nextsibling;
if ( firstthread )
firstthread->prevsibling = NULL;
thread->prevsibling = thread->nextsibling = NULL;
bool threadsleft = firstthread;
kthread_mutex_unlock(&threadlock);
// We are called from the threads destructor, let it finish before we
// we handle the situation by killing ourselves.
@ -275,7 +275,7 @@ void Process__AfterLastThreadExit(void* user)
void Process::ScheduleDeath()
{
// All our threads must have exited at this point.
assert(!first_thread);
assert(!firstthread);
Worker::Schedule(Process__AfterLastThreadExit, this);
}
@ -284,7 +284,7 @@ void Process::ScheduleDeath()
// process after this call as another thread may garbage collect it.
void Process::AbortConstruction()
{
no_zombify = true;
nozombify = true;
ScheduleDeath();
}
@ -311,7 +311,7 @@ void Process::LastPrayer()
{
assert(this);
// This must never be called twice.
assert(!is_zombie);
assert(!iszombie);
// This must be called from a thread using another address space as the
// address space of this process is about to be destroyed.
@ -319,7 +319,7 @@ void Process::LastPrayer()
assert(curthread->process != this);
// This can't be called if the process is still alive.
assert(!first_thread);
assert(!firstthread);
// Disarm and detach all the timers in the process.
DeleteTimers();
@ -348,7 +348,7 @@ void Process::LastPrayer()
ScopedLock family_lock(&process_family_lock);
is_zombie = true;
iszombie = true;
// Init is nice and will gladly raise our orphaned children and zombies.
// Child processes can't be reparented away if we're init. OnLastThreadExit
@ -358,33 +358,33 @@ void Process::LastPrayer()
if ( init == this )
{
assert(is_init_exiting);
assert(!first_child);
assert(!firstchild);
}
while ( first_child )
while ( firstchild )
{
Process* process = first_child;
first_child = process->next_sibling;
Process* process = firstchild;
firstchild = process->nextsibling;
process->parent = init;
process->prev_sibling = NULL;
process->next_sibling = init->first_child;
if ( init->first_child )
init->first_child->prev_sibling = process;
init->first_child = process;
process->no_zombify = true;
process->prevsibling = NULL;
process->nextsibling = init->firstchild;
if ( init->firstchild )
init->firstchild->prevsibling = process;
init->firstchild = process;
process->nozombify = true;
}
// Since we have no more children (they are with init now), we don't
// have to worry about new zombie processes showing up, so just collect
// those that are left. Then we satisfiy the invariant !zombie_child that
// those that are left. Then we satisfiy the invariant !zombiechild that
// applies on process termination.
while ( zombie_child )
while ( zombiechild )
{
Process* zombie = zombie_child;
zombie_child = zombie->next_sibling;
zombie->next_sibling = NULL;
if ( zombie_child )
zombie_child->prev_sibling = NULL;
zombie->no_zombify = true;
Process* zombie = zombiechild;
zombiechild = zombie->nextsibling;
zombie->nextsibling = NULL;
if ( zombiechild )
zombiechild->prevsibling = NULL;
zombie->nozombify = true;
zombie->WaitedFor();
}
// Remove ourself from our process group.
@ -397,7 +397,7 @@ void Process::LastPrayer()
if ( init )
init->InitRemoveMember(this);
bool zombify = !no_zombify;
bool zombify = !nozombify;
// This class instance will be destroyed by our parent process when it
// has received and acknowledged our death.
@ -413,7 +413,7 @@ void Process::WaitedFor() // process_family_lock taken
{
parent = NULL;
limbo = false;
if ( group_first || session_first || init_first )
if ( groupfirst || sessionfirst || initfirst )
limbo = true;
if ( !limbo )
delete this;
@ -439,12 +439,12 @@ void Process::ResetAddressSpace()
void Process::GroupRemoveMember(Process* child) // process_family_lock taken
{
assert(child->group == this);
if ( child->group_prev )
child->group_prev->group_next = child->group_next;
if ( child->groupprev )
child->groupprev->groupnext = child->groupnext;
else
group_first = child->group_next;
if ( child->group_next )
child->group_next->group_prev = child->group_prev;
groupfirst = child->groupnext;
if ( child->groupnext )
child->groupnext->groupprev = child->groupprev;
child->group = NULL;
if ( IsLimboDone() )
delete this;
@ -453,17 +453,17 @@ void Process::GroupRemoveMember(Process* child) // process_family_lock taken
void Process::SessionRemoveMember(Process* child) // process_family_lock taken
{
assert(child->session == this);
if ( child->session_prev )
child->session_prev->session_next = child->session_next;
if ( child->sessionprev )
child->sessionprev->sessionnext = child->sessionnext;
else
session_first = child->session_next;
if ( child->session_next )
child->session_next->session_prev = child->session_prev;
sessionfirst = child->sessionnext;
if ( child->sessionnext )
child->sessionnext->sessionprev = child->sessionprev;
child->session = NULL;
if ( !session_first )
if ( !sessionfirst )
{
// Remove reference to tty when session is empty.
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
tty.Reset();
}
if ( IsLimboDone() )
@ -473,12 +473,12 @@ void Process::SessionRemoveMember(Process* child) // process_family_lock taken
void Process::InitRemoveMember(Process* child) // process_family_lock taken
{
assert(child->init == this);
if ( child->init_prev )
child->init_prev->init_next = child->init_next;
if ( child->initprev )
child->initprev->initnext = child->initnext;
else
init_first = child->init_next;
if ( child->init_next )
child->init_next->init_prev = child->init_prev;
initfirst = child->initnext;
if ( child->initnext )
child->initnext->initprev = child->initprev;
child->init = NULL;
if ( IsLimboDone() )
delete this;
@ -486,28 +486,28 @@ void Process::InitRemoveMember(Process* child) // process_family_lock taken
bool Process::IsLimboDone() // process_family_lock taken
{
return limbo && !group_first && !session_first && !init_first;
return limbo && !groupfirst && !sessionfirst && !initfirst;
}
// process_family_lock taken
void Process::NotifyChildExit(Process* child, bool zombify)
{
if ( child->prev_sibling )
child->prev_sibling->next_sibling = child->next_sibling;
if ( child->next_sibling )
child->next_sibling->prev_sibling = child->prev_sibling;
if ( first_child == child )
first_child = child->next_sibling;
if ( first_child )
first_child->prev_sibling = NULL;
if ( child->prevsibling )
child->prevsibling->nextsibling = child->nextsibling;
if ( child->nextsibling )
child->nextsibling->prevsibling = child->prevsibling;
if ( firstchild == child )
firstchild = child->nextsibling;
if ( firstchild )
firstchild->prevsibling = NULL;
if ( zombify )
{
if ( zombie_child )
zombie_child->prev_sibling = child;
child->prev_sibling = NULL;
child->next_sibling = zombie_child;
zombie_child = child;
if ( zombiechild )
zombiechild->prevsibling = child;
child->prevsibling = NULL;
child->nextsibling = zombiechild;
zombiechild = child;
}
// Notify this parent process about the child exiting if it's meant to
@ -516,7 +516,7 @@ void Process::NotifyChildExit(Process* child, bool zombify)
// every child exiting.
DeliverSignal(SIGCHLD);
if ( zombify || is_init_exiting )
kthread_cond_broadcast(&zombie_cond);
kthread_cond_broadcast(&zombiecond);
}
pid_t Process::Wait(pid_t thepid, int* status_ptr, int options)
@ -528,7 +528,7 @@ pid_t Process::Wait(pid_t thepid, int* status_ptr, int options)
ScopedLock lock(&process_family_lock);
// A process can only wait if it has children.
if ( !first_child && !zombie_child )
if ( !firstchild && !zombiechild )
return errno = ECHILD, -1;
// Processes can only wait for their own children to exit.
@ -537,11 +537,11 @@ pid_t Process::Wait(pid_t thepid, int* status_ptr, int options)
// TODO: This is a slow but multithread safe way to verify that the
// target process has the correct parent.
bool found = false;
for ( Process* p = first_child; !found && p; p = p->next_sibling )
if ( p->pid == thepid && !p->no_zombify )
for ( Process* p = firstchild; !found && p; p = p->nextsibling )
if ( p->pid == thepid && !p->nozombify )
found = true;
for ( Process* p = zombie_child; !found && p; p = p->next_sibling )
if ( p->pid == thepid && !p->no_zombify )
for ( Process* p = zombiechild; !found && p; p = p->nextsibling )
if ( p->pid == thepid && !p->nozombify )
found = true;
if ( !found )
return errno = ECHILD, -1;
@ -550,26 +550,26 @@ pid_t Process::Wait(pid_t thepid, int* status_ptr, int options)
Process* zombie = NULL;
while ( !zombie )
{
for ( zombie = zombie_child; zombie; zombie = zombie->next_sibling )
if ( (thepid == -1 || thepid == zombie->pid) && !zombie->no_zombify )
for ( zombie = zombiechild; zombie; zombie = zombie->nextsibling )
if ( (thepid == -1 || thepid == zombie->pid) && !zombie->nozombify )
break;
if ( zombie )
break;
if ( options & WNOHANG )
return 0;
if ( !kthread_cond_wait_signal(&zombie_cond, &process_family_lock) )
if ( !kthread_cond_wait_signal(&zombiecond, &process_family_lock) )
return errno = EINTR, -1;
}
// Remove from the list of zombies.
if ( zombie->prev_sibling )
zombie->prev_sibling->next_sibling = zombie->next_sibling;
if ( zombie->next_sibling )
zombie->next_sibling->prev_sibling = zombie->prev_sibling;
if ( zombie_child == zombie )
zombie_child = zombie->next_sibling;
if ( zombie_child )
zombie_child->prev_sibling = NULL;
if ( zombie->prevsibling )
zombie->prevsibling->nextsibling = zombie->nextsibling;
if ( zombie->nextsibling )
zombie->nextsibling->prevsibling = zombie->prevsibling;
if ( zombiechild == zombie )
zombiechild = zombie->nextsibling;
if ( zombiechild )
zombiechild->prevsibling = NULL;
thepid = zombie->pid;
@ -608,7 +608,7 @@ void Process::ExitThroughSignal(int signal)
void Process::ExitWithCode(int requested_exit_code)
{
ScopedLock lock(&thread_lock);
ScopedLock lock(&threadlock);
if ( exit_code == -1 )
exit_code = requested_exit_code;
@ -616,74 +616,74 @@ void Process::ExitWithCode(int requested_exit_code)
// of process termination. We simply can't stop the threads as they may
// be running in kernel mode doing dangerous stuff. This thread will be
// destroyed by SIGKILL once the system call returns.
for ( Thread* t = first_thread; t; t = t->next_sibling )
for ( Thread* t = firstthread; t; t = t->nextsibling )
t->DeliverSignal(SIGKILL);
}
Ref<MountTable> Process::GetMTable()
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(mtable);
return mtable;
}
Ref<DescriptorTable> Process::GetDTable()
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(dtable);
return dtable;
}
Ref<ProcessTable> Process::GetPTable()
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(ptable);
return ptable;
}
Ref<Descriptor> Process::GetTTY()
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
return tty;
}
Ref<Descriptor> Process::GetRoot()
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(root);
return root;
}
Ref<Descriptor> Process::GetCWD()
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(cwd);
return cwd;
}
void Process::SetTTY(Ref<Descriptor> newtty)
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
tty = newtty;
}
void Process::SetRoot(Ref<Descriptor> newroot)
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(newroot);
root = newroot;
}
void Process::SetCWD(Ref<Descriptor> newcwd)
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(newcwd);
cwd = newcwd;
}
Ref<Descriptor> Process::GetDescriptor(int fd)
{
ScopedLock lock(&ptr_lock);
ScopedLock lock(&ptrlock);
assert(dtable);
return dtable->Get(fd);
}
@ -745,32 +745,32 @@ Process* Process::Fork()
// Remember the relation to the child process.
clone->parent = this;
clone->next_sibling = first_child;
clone->prev_sibling = NULL;
if ( first_child )
first_child->prev_sibling = clone;
first_child = clone;
clone->nextsibling = firstchild;
clone->prevsibling = NULL;
if ( firstchild )
firstchild->prevsibling = clone;
firstchild = clone;
// Add the new process to the current process group.
clone->group = group;
clone->group_prev = NULL;
if ( (clone->group_next = group->group_first) )
group->group_first->group_prev = clone;
group->group_first = clone;
clone->groupprev = NULL;
if ( (clone->groupnext = group->groupfirst) )
group->groupfirst->groupprev = clone;
group->groupfirst = clone;
// Add the new process to the current session.
clone->session = session;
clone->session_prev = NULL;
if ( (clone->session_next = session->session_first) )
session->session_first->session_prev = clone;
session->session_first = clone;
clone->sessionprev = NULL;
if ( (clone->sessionnext = session->sessionfirst) )
session->sessionfirst->sessionprev = clone;
session->sessionfirst = clone;
// Add the new process to the current init.
clone->init = init;
clone->init_prev = NULL;
if ( (clone->init_next = init->init_first) )
init->init_first->init_prev = clone;
init->init_first = clone;
clone->initprev = NULL;
if ( (clone->initnext = init->initfirst) )
init->initfirst->initprev = clone;
init->initfirst = clone;
kthread_mutex_unlock(&process_family_lock);
@ -780,22 +780,22 @@ Process* Process::Fork()
clone->resource_limits[i] = resource_limits[i];
kthread_mutex_unlock(&resource_limits_lock);
kthread_mutex_lock(&nice_lock);
kthread_mutex_lock(&nicelock);
clone->nice = nice;
kthread_mutex_unlock(&nice_lock);
kthread_mutex_unlock(&nicelock);
kthread_mutex_lock(&ptr_lock);
kthread_mutex_lock(&ptrlock);
clone->root = root;
clone->cwd = cwd;
kthread_mutex_unlock(&ptr_lock);
kthread_mutex_unlock(&ptrlock);
kthread_mutex_lock(&id_lock);
kthread_mutex_lock(&idlock);
clone->uid = uid;
clone->gid = gid;
clone->euid = euid;
clone->egid = egid;
clone->umask = umask;
kthread_mutex_unlock(&id_lock);
kthread_mutex_unlock(&idlock);
kthread_mutex_lock(&signal_lock);
memcpy(&clone->signal_actions, &signal_actions, sizeof(signal_actions));
@ -806,13 +806,13 @@ Process* Process::Fork()
// Initialize things that can fail and abort if needed.
bool failure = false;
kthread_mutex_lock(&ptr_lock);
kthread_mutex_lock(&ptrlock);
if ( !(clone->dtable = dtable->Fork()) )
failure = true;
//if ( !(clone->mtable = mtable->Fork()) )
// failure = true;
clone->mtable = mtable;
kthread_mutex_unlock(&ptr_lock);
kthread_mutex_unlock(&ptrlock);
if ( !(clone->program_image_path = String::Clone(program_image_path)) )
failure = true;
@ -1506,13 +1506,13 @@ pid_t sys_tfork(int flags, struct tfork* user_regs)
// TODO: Is it a hack to create a new kernel stack here?
Thread* curthread = CurrentThread();
size_t newkernel_stack_size = curthread->kernel_stack_size;
uint8_t* newkernelstack = new uint8_t[newkernel_stack_size + stack_alignment];
size_t newkernelstacksize = curthread->kernelstacksize;
uint8_t* newkernelstack = new uint8_t[newkernelstacksize + stack_alignment];
if ( !newkernelstack )
return -1;
uintptr_t stack_aligned = (uintptr_t) newkernelstack;
size_t stack_aligned_size = newkernel_stack_size;
size_t stack_aligned_size = newkernelstacksize;
if ( ((uintptr_t) stack_aligned) & (stack_alignment-1) )
stack_aligned = (stack_aligned + 16) & ~(stack_alignment-1);
@ -1594,9 +1594,9 @@ pid_t sys_tfork(int flags, struct tfork* user_regs)
return -1;
}
thread->kernel_stack_pos = (addr_t) newkernelstack;
thread->kernel_stack_size = newkernel_stack_size;
thread->kernel_stack_malloced = true;
thread->kernelstackpos = (addr_t) newkernelstack;
thread->kernelstacksize = newkernelstacksize;
thread->kernelstackmalloced = true;
memcpy(&thread->signal_mask, &regs.sigmask, sizeof(sigset_t));
memcpy(&thread->signal_stack, &regs.altstack, sizeof(stack_t));
@ -1689,13 +1689,13 @@ int sys_setpgid(pid_t pid, pid_t pgid)
return errno = EPERM, -1;
// The process must not be a process group leader.
// TODO: Maybe POSIX actually allows this.
if ( process->group_first )
if ( process->groupfirst )
return errno = EPERM, -1;
// The process must not be a session leader.
if ( process->session_first )
if ( process->sessionfirst )
return errno = EPERM, -1;
// The group must either exist or be the process itself.
if ( !group->group_first && group != process )
if ( !group->groupfirst && group != process )
return errno = EPERM, -1;
// Exit early if this is a noop.
@ -1707,11 +1707,11 @@ int sys_setpgid(pid_t pid, pid_t pgid)
process->group->GroupRemoveMember(process);
// Insert the process into its new process group.
process->group_prev = NULL;
process->group_next = group->group_first;
if ( group->group_first )
group->group_first->group_prev = process;
group->group_first = process;
process->groupprev = NULL;
process->groupnext = group->groupfirst;
if ( group->groupfirst )
group->groupfirst->groupprev = process;
group->groupfirst = process;
process->group = group;
return 0;
@ -1736,15 +1736,15 @@ pid_t sys_setsid(void)
process->session->SessionRemoveMember(process);
// Insert the process into its new session.
process->session_prev = NULL;
process->session_next = NULL;
process->session_first = process;
process->sessionprev = NULL;
process->sessionnext = NULL;
process->sessionfirst = process;
process->session = process;
// Insert the process into its new process group.
process->group_prev = NULL;
process->group_next = NULL;
process->group_first = process;
process->groupprev = NULL;
process->groupnext = NULL;
process->groupfirst = process;
process->group = process;
return process->pid;
@ -1773,21 +1773,21 @@ int sys_setinit(void)
process->init->InitRemoveMember(process);
// Insert the process into its new init.
process->init_prev = NULL;
process->init_next = NULL;
process->init_first = process;
process->initprev = NULL;
process->initnext = NULL;
process->initfirst = process;
process->init = process;
// Insert the process into its new session.
process->session_prev = NULL;
process->session_next = NULL;
process->session_first = process;
process->sessionprev = NULL;
process->sessionnext = NULL;
process->sessionfirst = process;
process->session = process;
// Insert the process into its new process group.
process->group_prev = NULL;
process->group_next = NULL;
process->group_first = process;
process->groupprev = NULL;
process->groupnext = NULL;
process->groupfirst = process;
process->group = process;
return process->pid;
@ -1801,7 +1801,7 @@ size_t sys_getpagesize(void)
mode_t sys_umask(mode_t newmask)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
mode_t oldmask = process->umask;
process->umask = newmask & 0666;
return oldmask;
@ -1810,7 +1810,7 @@ mode_t sys_umask(mode_t newmask)
mode_t sys_getumask(void)
{
Process* process = CurrentProcess();
ScopedLock lock(&process->id_lock);
ScopedLock lock(&process->idlock);
return process->umask;
}

View file

@ -72,8 +72,8 @@ int sys_psctl(pid_t pid, int request, void* ptr)
{
Process* parent = process->parent;
psst.ppid = parent->pid;
psst.ppid_prev = process->prev_sibling ? process->prev_sibling->pid : -1;
psst.ppid_next = process->next_sibling ? process->next_sibling->pid : -1;
psst.ppid_prev = process->prevsibling ? process->prevsibling->pid : -1;
psst.ppid_next = process->nextsibling ? process->nextsibling->pid : -1;
}
else
{
@ -81,13 +81,13 @@ int sys_psctl(pid_t pid, int request, void* ptr)
psst.ppid_prev = -1;
psst.ppid_next = -1;
}
psst.ppid_first = process->first_child ? process->first_child->pid : -1;
psst.ppid_first = process->firstchild ? process->firstchild->pid : -1;
if ( process->group )
{
Process* group = process->group;
psst.pgid = group->pid;
psst.pgid_prev = process->group_prev ? process->group_prev->pid : -1;
psst.pgid_next = process->group_next ? process->group_next->pid : -1;
psst.pgid_prev = process->groupprev ? process->groupprev->pid : -1;
psst.pgid_next = process->groupnext ? process->groupnext->pid : -1;
}
else
{
@ -95,13 +95,13 @@ int sys_psctl(pid_t pid, int request, void* ptr)
psst.pgid_prev = -1;
psst.pgid_next = -1;
}
psst.pgid_first = process->group_first ? process->group_first->pid : -1;
psst.pgid_first = process->groupfirst ? process->groupfirst->pid : -1;
if ( process->session )
{
Process* session = process->session;
psst.sid = session->pid;
psst.sid_prev = process->session_prev ? process->session_prev->pid : -1;
psst.sid_next = process->session_next ? process->session_next->pid : -1;
psst.sid_prev = process->sessionprev ? process->sessionprev->pid : -1;
psst.sid_next = process->sessionnext ? process->sessionnext->pid : -1;
}
else
{
@ -109,14 +109,14 @@ int sys_psctl(pid_t pid, int request, void* ptr)
psst.sid_prev = -1;
psst.sid_next = -1;
}
psst.sid_first = process->session_first ? process->session_first->pid : -1;
psst.sid_first = process->sessionfirst ? process->sessionfirst->pid : -1;
if ( process->init )
{
Process* init = process->init;
psst.init = init->pid;
psst.init_prev = process->init_prev ? process->init_prev->pid : -1;
psst.init_next = process->init_next ? process->init_next->pid : -1;
psst.init_prev = process->initprev ? process->initprev->pid : -1;
psst.init_next = process->initnext ? process->initnext->pid : -1;
}
else
{
@ -124,19 +124,19 @@ int sys_psctl(pid_t pid, int request, void* ptr)
psst.init_prev = -1;
psst.init_next = -1;
}
psst.init_first = process->init_first ? process->init_first->pid : -1;
kthread_mutex_lock(&process->id_lock);
psst.init_first = process->initfirst ? process->initfirst->pid : -1;
kthread_mutex_lock(&process->idlock);
psst.uid = process->uid;
psst.euid = process->euid;
psst.gid = process->gid;
psst.egid = process->egid;
kthread_mutex_unlock(&process->id_lock);
kthread_mutex_lock(&process->thread_lock);
kthread_mutex_unlock(&process->idlock);
kthread_mutex_lock(&process->threadlock);
psst.status = process->exit_code;
kthread_mutex_unlock(&process->thread_lock);
kthread_mutex_lock(&process->nice_lock);
kthread_mutex_unlock(&process->threadlock);
kthread_mutex_lock(&process->nicelock);
psst.nice = process->nice;
kthread_mutex_unlock(&process->nice_lock);
kthread_mutex_unlock(&process->nicelock);
kthread_mutex_lock(&process->segment_lock);
// TODO: Cache these.
for ( size_t i = 0; i < process->segments_used; i++ )

View file

@ -39,7 +39,7 @@ static int GetProcessPriority(pid_t who)
Process* process = who ? CurrentProcess()->GetPTable()->Get(who) : CurrentProcess();
if ( !process )
return errno = ESRCH, -1;
ScopedLock lock(&process->nice_lock);
ScopedLock lock(&process->nicelock);
return process->nice;
}
@ -50,7 +50,7 @@ static int SetProcessPriority(pid_t who, int prio)
Process* process = who ? CurrentProcess()->GetPTable()->Get(who) : CurrentProcess();
if ( !process )
return errno = ESRCH, -1;
ScopedLock lock(&process->nice_lock);
ScopedLock lock(&process->nicelock);
process->nice = prio;
return 0;
}
@ -68,9 +68,9 @@ static int GetProcessGroupPriority(pid_t who)
if ( !group )
return errno = ESRCH, -1;
int lowest = INT_MAX;
for ( Process* process = group->group_first; process; process = process->group_next )
for ( Process* process = group->groupfirst; process; process = process->groupnext )
{
ScopedLock lock(&process->nice_lock);
ScopedLock lock(&process->nicelock);
if ( process->nice < lowest )
lowest = process->nice;
}
@ -84,9 +84,9 @@ static int SetProcessGroupPriority(pid_t who, int prio)
Process* group = who ? CurrentProcess()->GetPTable()->Get(who) : CurrentProcessGroup();
if ( !group )
return errno = ESRCH, -1;
for ( Process* process = group->group_first; process; process = process->group_next )
for ( Process* process = group->groupfirst; process; process = process->groupnext )
{
ScopedLock lock(&process->nice_lock);
ScopedLock lock(&process->nicelock);
process->nice = prio;
}
return 0;

View file

@ -181,8 +181,8 @@ extern "C" void fake_interrupt(void);
static void FakeInterruptedContext(struct interrupt_context* intctx, int int_no)
{
#if defined(__i386__)
uintptr_t stack = current_thread->kernel_stack_pos +
current_thread->kernel_stack_size;
uintptr_t stack = current_thread->kernelstackpos +
current_thread->kernelstacksize;
stack -= sizeof(struct interrupt_context);
struct interrupt_context* fakectx = (struct interrupt_context*) stack;
memcpy(fakectx, intctx, sizeof(struct interrupt_context));
@ -209,8 +209,8 @@ static void FakeInterruptedContext(struct interrupt_context* intctx, int int_no)
intctx->esp = stack;
intctx->ss = KDS | KRPL;
#elif defined(__x86_64__)
uintptr_t stack = current_thread->kernel_stack_pos +
current_thread->kernel_stack_size;
uintptr_t stack = current_thread->kernelstackpos +
current_thread->kernelstacksize;
stack -= sizeof(struct interrupt_context);
struct interrupt_context* fakectx = (struct interrupt_context*) stack;
memcpy(fakectx, intctx, sizeof(struct interrupt_context));

View file

@ -144,8 +144,8 @@ int sys_sigaction(int signum,
memcpy(kact, &newact, sizeof(struct sigaction));
// Signals may become discarded because of the new handler.
ScopedLock threads_lock(&process->thread_lock);
for ( Thread* t = process->first_thread; t; t = t->next_sibling )
ScopedLock threads_lock(&process->threadlock);
for ( Thread* t = process->firstthread; t; t = t->nextsibling )
UpdatePendingSignals(t);
}
@ -315,9 +315,9 @@ int sys_kill(pid_t pid, int signum)
bool Process::DeliverGroupSignal(int signum) // process_family_lock held
{
if ( !group_first )
if ( !groupfirst )
return errno = ESRCH, false;
for ( Process* iter = group_first; iter; iter = iter->group_next )
for ( Process* iter = groupfirst; iter; iter = iter->groupnext )
{
int saved_errno = errno;
if ( !iter->DeliverSignal(signum) && errno != ESIGPENDING )
@ -331,9 +331,9 @@ bool Process::DeliverGroupSignal(int signum) // process_family_lock held
bool Process::DeliverSessionSignal(int signum) // process_family_lock held
{
if ( !session_first )
if ( !sessionfirst )
return errno = ESRCH, false;
for ( Process* iter = session_first; iter; iter = iter->session_next )
for ( Process* iter = sessionfirst; iter; iter = iter->sessionnext )
{
int saved_errno = errno;
if ( !iter->DeliverSignal(signum) && errno != ESIGPENDING )
@ -347,16 +347,16 @@ bool Process::DeliverSessionSignal(int signum) // process_family_lock held
bool Process::DeliverSignal(int signum)
{
ScopedLock lock(&thread_lock);
ScopedLock lock(&threadlock);
if ( !first_thread )
if ( !firstthread )
return errno = EINIT, false;
// Broadcast particular signals to all the threads in the process.
if ( signum == SIGCONT || signum == SIGSTOP || signum == SIGKILL )
{
int saved_errno = errno;
for ( Thread* t = first_thread; t; t = t->next_sibling )
for ( Thread* t = firstthread; t; t = t->nextsibling )
{
if ( !t->DeliverSignal(signum) && errno != ESIGPENDING )
{
@ -371,7 +371,7 @@ bool Process::DeliverSignal(int signum)
// TODO: This isn't how signals should be routed to a particular thread.
if ( CurrentThread()->process == this )
return CurrentThread()->DeliverSignal(signum);
return first_thread->DeliverSignal(signum);
return firstthread->DeliverSignal(signum);
}
int sys_raise(int signum)

View file

@ -59,18 +59,18 @@ Thread::Thread()
yield_to_tid = 0;
id = 0; // TODO: Make a thread id.
process = NULL;
prev_sibling = NULL;
next_sibling = NULL;
prevsibling = NULL;
nextsibling = NULL;
scheduler_list_prev = NULL;
scheduler_list_next = NULL;
state = NONE;
memset(&registers, 0, sizeof(registers));
kernel_stack_pos = 0;
kernel_stack_size = 0;
kernelstackpos = 0;
kernelstacksize = 0;
signal_count = 0;
signal_single_frame = 0;
signal_canary = 0;
kernel_stack_malloced = false;
kernelstackmalloced = false;
pledged_destruction = false;
force_no_signals = false;
signal_single = false;
@ -99,8 +99,8 @@ Thread::~Thread()
if ( process )
process->OnThreadDestruction(this);
assert(CurrentThread() != this);
if ( kernel_stack_malloced )
delete[] (uint8_t*) kernel_stack_pos;
if ( kernelstackmalloced )
delete[] (uint8_t*) kernelstackpos;
}
Thread* CreateKernelThread(Process* process,
@ -116,7 +116,7 @@ Thread* CreateKernelThread(Process* process,
return errno = EINVAL, (Thread*) NULL;
#endif
kthread_mutex_lock(&process->thread_lock);
kthread_mutex_lock(&process->threadlock);
// Note: Only allow the process itself to make threads, except the initial
// thread. This requirement is because kthread_exit() needs to know when
@ -124,7 +124,7 @@ Thread* CreateKernelThread(Process* process,
// and that no more threads will appear, so it can run some final process
// termination steps without any interference. It's always allowed to create
// threads in the kernel process as it never exits.
assert(!process->first_thread ||
assert(!process->firstthread ||
process == CurrentProcess() ||
process == Scheduler::GetKernelProcess());
@ -137,14 +137,14 @@ Thread* CreateKernelThread(Process* process,
// Create the family tree.
thread->process = process;
Thread* firsty = process->first_thread;
Thread* firsty = process->firstthread;
if ( firsty )
firsty->prev_sibling = thread;
thread->next_sibling = firsty;
process->first_thread = thread;
firsty->prevsibling = thread;
thread->nextsibling = firsty;
process->firstthread = thread;
process->threads_not_exiting_count++;
kthread_mutex_unlock(&process->thread_lock);
kthread_mutex_unlock(&process->threadlock);
return thread;
}
@ -260,9 +260,9 @@ Thread* CreateKernelThread(Process* process, void (*entry)(void*), void* user,
Thread* thread = CreateKernelThread(process, &regs, name);
if ( !thread ) { delete[] stack; return NULL; }
thread->kernel_stack_pos = (uintptr_t) stack;
thread->kernel_stack_size = stacksize;
thread->kernel_stack_malloced = true;
thread->kernelstackpos = (uintptr_t) stack;
thread->kernelstacksize = stacksize;
thread->kernelstackmalloced = true;
return thread;
}
@ -335,11 +335,11 @@ int sys_exit_thread(int requested_exit_code,
extended.unmap_size = Page::AlignUp(extended.unmap_size);
kthread_mutex_lock(&thread->process->thread_lock);
kthread_mutex_lock(&thread->process->threadlock);
bool is_others = false;
for ( Thread* iter = thread->process->first_thread;
for ( Thread* iter = thread->process->firstthread;
!is_others && iter;
iter = iter->next_sibling )
iter = iter->nextsibling )
{
if ( iter == thread )
continue;
@ -355,7 +355,7 @@ int sys_exit_thread(int requested_exit_code,
process->threads_exiting = true;
else if ( process->threads_exiting )
are_threads_exiting = true;
kthread_mutex_unlock(&thread->process->thread_lock);
kthread_mutex_unlock(&thread->process->threadlock);
// Self-destruct if another thread began exiting the process.
if ( are_threads_exiting )

View file

@ -295,7 +295,7 @@ int TTY::tcsetpgrp(ioctx_t* /*ctx*/, pid_t pgid)
Process* process = CurrentProcess()->GetPTable()->Get(pgid);
if ( !process )
return errno = ESRCH, -1;
if ( !process->group_first )
if ( !process->groupfirst )
return errno = EINVAL, -1;
foreground_pgid = pgid;
return 0;
@ -864,7 +864,7 @@ int TTY::ioctl(ioctx_t* ctx, int cmd, uintptr_t arg)
return errno = EPERM, -1;
ScopedLock family_lock(&process_family_lock);
Process* process = CurrentProcess();
if ( !force && !process->session_first )
if ( !force && !process->sessionfirst )
return errno = EPERM, -1;
Process* session = process->session;
// TODO: Don't do this if the sesion already has a tty.

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -14,17 +14,14 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* framebuffer.c
* Framebuffer utilities.
* Framebuffer functions.
*/
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "framebuffer.h"
#include "pixel.h"
#include "vgafont.h"
struct framebuffer framebuffer_crop(struct framebuffer fb,
size_t left,
@ -72,102 +69,3 @@ void framebuffer_copy_to_framebuffer_blend(const struct framebuffer dst,
}
}
}
struct framebuffer framebuffer_crop_int(struct framebuffer fb,
int left,
int top,
int width,
int height)
{
if ( left < 0 ) { width -= -left; left = 0; }
if ( top < 0 ) { top -= -height; top -= 0; }
if ( width < 0 ) { width = 0; }
if ( height < 0 ) { height = 0; }
return framebuffer_crop(fb, left, top, width, height);
}
struct framebuffer framebuffer_cut_left_x(struct framebuffer fb, int offset)
{
fb = framebuffer_crop_int(fb, offset, 0, fb.xres - offset, fb.yres);
return fb;
}
struct framebuffer framebuffer_cut_right_x(struct framebuffer fb, int offset)
{
fb = framebuffer_crop_int(fb, 0, 0, fb.xres - offset, fb.yres);
return fb;
}
struct framebuffer framebuffer_cut_top_y(struct framebuffer fb, int offset)
{
fb = framebuffer_crop_int(fb, 0, offset, fb.xres, fb.yres - offset);
return fb;
}
struct framebuffer framebuffer_cut_bottom_y(struct framebuffer fb, int offset)
{
fb = framebuffer_crop_int(fb, 0, 0, fb.xres, fb.yres - offset);
return fb;
}
struct framebuffer framebuffer_center_x(struct framebuffer fb, int x, int width)
{
x = x - width / 2;
if ( x < 0 ) { width -= -x; x = 0; }
if ( width < 0 ) { width = 0; }
fb = framebuffer_crop(fb, x, 0, width, fb.yres);
return fb;
}
struct framebuffer framebuffer_center_y(struct framebuffer fb, int y, int height)
{
y = y - height / 2;
if ( y < 0 ) { height -= -y; y = 0; }
if ( height < 0 ) { height = 0; }
fb = framebuffer_crop(fb, 0, y, fb.xres, height);
return fb;
}
struct framebuffer framebuffer_right_x(struct framebuffer fb, int x, int width)
{
x = x - width;
if ( x < 0 ) { width -= -x; x = 0; }
if ( width < 0 ) { width = 0; }
fb = framebuffer_crop(fb, x, 0, width, fb.yres);
return fb;
}
struct framebuffer framebuffer_bottom_y(struct framebuffer fb, int y, int height)
{
y = y - height;
if ( y < 0 ) { height -= -y; y = 0; }
if ( height < 0 ) { height = 0; }
fb = framebuffer_crop(fb, 0, y, fb.xres, height);
return fb;
}
struct framebuffer framebuffer_center_text_x(struct framebuffer fb, int x, const char* str)
{
int width = (FONT_WIDTH + 1) * strlen(str);
return framebuffer_center_x(fb, x, width);
}
struct framebuffer framebuffer_center_text_y(struct framebuffer fb, int y, const char* str)
{
(void) str;
int height = FONT_HEIGHT;
return framebuffer_center_y(fb, y, height);
}
struct framebuffer framebuffer_right_text_x(struct framebuffer fb, int x, const char* str)
{
int width = (FONT_WIDTH + 1) * strlen(str);
return framebuffer_right_x(fb, x, width);
}
struct framebuffer framebuffer_bottom_text_y(struct framebuffer fb, int y, const char* str)
{
(void) str;
int height = FONT_HEIGHT;
return framebuffer_bottom_y(fb, y, height);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2016 Jonas 'Sortie' Termansen.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* framebuffer.h
* Framebuffer utilities.
* Framebuffer functions.
*/
#ifndef FRAMEBUFFER_H
@ -59,22 +59,5 @@ void framebuffer_copy_to_framebuffer(const struct framebuffer dst,
const struct framebuffer src);
void framebuffer_copy_to_framebuffer_blend(const struct framebuffer dst,
const struct framebuffer src);
struct framebuffer framebuffer_crop_int(struct framebuffer fb,
int left,
int top,
int width,
int height);
struct framebuffer framebuffer_cut_left_x(struct framebuffer fb, int offset);
struct framebuffer framebuffer_cut_right_x(struct framebuffer fb, int offset);
struct framebuffer framebuffer_cut_top_y(struct framebuffer fb, int offset);
struct framebuffer framebuffer_cut_bottom_y(struct framebuffer fb, int offset);
struct framebuffer framebuffer_center_x(struct framebuffer fb, int x, int width);
struct framebuffer framebuffer_center_y(struct framebuffer fb, int y, int height);
struct framebuffer framebuffer_right_x(struct framebuffer fb, int x, int width);
struct framebuffer framebuffer_bottom_y(struct framebuffer fb, int y, int height);
struct framebuffer framebuffer_center_text_x(struct framebuffer fb, int x, const char* str);
struct framebuffer framebuffer_center_text_y(struct framebuffer fb, int y, const char* str);
struct framebuffer framebuffer_right_text_x(struct framebuffer fb, int x, const char* str);
struct framebuffer framebuffer_bottom_text_y(struct framebuffer fb, int y, const char* str);
#endif

View file

@ -63,7 +63,6 @@ enum stage
STAGE_USERNAME,
STAGE_PASSWORD,
STAGE_CHECKING,
STAGE_EXITING,
};
struct textbox
@ -112,7 +111,6 @@ struct glogin
enum stage stage;
bool animating;
const char* warning;
const char* announcement;
bool pointer_working;
struct termios old_tio;
bool has_old_tio;
@ -501,33 +499,6 @@ static void render_progress(struct framebuffer fb)
}
}
static void render_exit(struct framebuffer fb)
{
assert(state.announcement);
for ( int yoff = -1; yoff <= 1; yoff++ )
{
for ( int xoff = -1; xoff <= 1; xoff++ )
{
struct framebuffer msgfb = fb;
int y = (fb.yres - FONT_HEIGHT) / 2 + yoff;
msgfb = framebuffer_cut_top_y(msgfb, y);
int w = strlen(state.announcement) * (FONT_WIDTH+1);
int x = (fb.xres - w) / 2 + xoff;
msgfb = framebuffer_cut_left_x(msgfb, x);
render_text(msgfb, state.announcement, make_color_a(0, 0, 0, 64));
}
}
struct framebuffer msgfb = fb;
int y = (fb.yres - FONT_HEIGHT) / 2;
msgfb = framebuffer_cut_top_y(msgfb, y);
int w = strlen(state.announcement) * (FONT_WIDTH+1);
int x = (fb.xres - w) / 2;
msgfb = framebuffer_cut_left_x(msgfb, x);
render_text(msgfb, state.announcement, make_color(255, 255, 255));
}
static void render_login(struct framebuffer fb)
{
render_background(fb);
@ -538,7 +509,6 @@ static void render_login(struct framebuffer fb)
case STAGE_USERNAME: render_form(fb); break;
case STAGE_PASSWORD: render_form(fb); break;
case STAGE_CHECKING: render_progress(fb); break;
case STAGE_EXITING: render_exit(fb); break;
}
if ( state.pointer_working )
render_pointer(fb);
@ -699,52 +669,6 @@ static bool render(struct glogin* state)
return true;
}
static void handle_special_graphical(struct glogin* state,
enum special_action special_action)
{
switch ( special_action )
{
case SPECIAL_ACTION_NONE:
state->announcement = NULL;
break;
case SPECIAL_ACTION_EXIT:
state->announcement = "Exiting...";
break;
case SPECIAL_ACTION_POWEROFF:
state->announcement = "Powering off...";
break;
case SPECIAL_ACTION_REBOOT:
state->announcement = "Rebooting...";
break;
case SPECIAL_ACTION_HALT:
state->announcement = "Halting...";
break;
case SPECIAL_ACTION_REINIT:
state->announcement = "Reinitializing operating system...";
break;
}
if ( state->announcement )
{
state->stage = STAGE_EXITING;
state->fading_from = false;
render(state);
}
handle_special(special_action);
}
static int get_init_exit_plan(void)
{
FILE* fp = popen("/sbin/service default exit-code", "r");
if ( !fp )
return -1;
int result = -1;
char buffer[sizeof(int) * 3];
if ( fgets(buffer, sizeof(buffer), fp) && buffer[0] )
result = atoi(buffer);
pclose(fp);
return result;
}
static void think(struct glogin* state)
{
if ( state->stage == STAGE_CHECKING )
@ -755,7 +679,6 @@ static void think(struct glogin* state)
sched_yield();
return;
}
forward_sigterm_to = 0;
if ( result )
{
if ( !login(username, session) )
@ -773,22 +696,6 @@ static void think(struct glogin* state)
state->warning = strerror(errno);
}
}
// TODO: Find a method to detect what init is trying to do so we can display
// the appropriate message to the user.
if ( got_sigterm )
{
int exit_code = get_init_exit_plan();
enum special_action action = SPECIAL_ACTION_EXIT;
if ( exit_code == 0 )
action = SPECIAL_ACTION_POWEROFF;
else if ( exit_code == 1 )
action = SPECIAL_ACTION_REBOOT;
else if ( exit_code == 2 )
action = SPECIAL_ACTION_HALT;
else if ( exit_code == 3 )
action = SPECIAL_ACTION_REINIT;
handle_special_graphical(state, action);
}
}
static void keyboard_event(struct glogin* state, uint32_t codepoint)
@ -810,7 +717,7 @@ static void keyboard_event(struct glogin* state, uint32_t codepoint)
state->warning = "Invalid username";
break;
}
handle_special_graphical(state, action);
handle_special(action);
state->stage = STAGE_PASSWORD;
textbox_reset(&textbox_password);
break;
@ -822,10 +729,8 @@ static void keyboard_event(struct glogin* state, uint32_t codepoint)
state->stage = STAGE_USERNAME;
state->warning = strerror(errno);
}
forward_sigterm_to = state->chk.pid;
break;
case STAGE_CHECKING:
case STAGE_EXITING:
break;
}
return;
@ -836,7 +741,6 @@ static void keyboard_event(struct glogin* state, uint32_t codepoint)
case STAGE_USERNAME: textbox = &textbox_username; break;
case STAGE_PASSWORD: textbox = &textbox_password; break;
case STAGE_CHECKING: break;
case STAGE_EXITING: break;
}
if ( textbox && codepoint < 128 )
{
@ -967,12 +871,6 @@ bool glogin_init(struct glogin* state)
struct timespec duration = timespec_make(0, 150*1000*1000);
state->fade_from_end = timespec_add(state->fade_from_begin, duration);
}
sigset_t sigterm;
sigemptyset(&sigterm);
sigaddset(&sigterm, SIGTERM);
sigprocmask(SIG_BLOCK, &sigterm, NULL);
struct sigaction sa = { .sa_handler = on_interrupt_signal };
sigaction(SIGTERM, &sa, NULL);
return true;
}
@ -1002,14 +900,9 @@ int glogin_main(struct glogin* state)
nfds_t nfds = 2;
struct timespec wake_now_ts = timespec_make(0, 0);
struct timespec* wake = state->animating ? &wake_now_ts : NULL;
sigset_t pollmask;
sigprocmask(SIG_SETMASK, NULL, &pollmask);
sigdelset(&pollmask, SIGTERM);
int num_events = ppoll(pfds, nfds, wake, &pollmask);
int num_events = ppoll(pfds, nfds, wake, NULL);
if ( num_events < 0 )
{
if ( errno == EINTR )
continue;
warn("poll");
break;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, 2018, 2022, 2023, 2024 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2018, 2022, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2023 dzwdz.
*
* Permission to use, copy, modify, and distribute this software for any
@ -46,21 +46,12 @@
#include "login.h"
pid_t forward_sigterm_to = 0;
volatile sig_atomic_t got_sigterm = 0;
void on_interrupt_signal(int signum)
static void on_interrupt_signal(int signum)
{
if ( signum == SIGINT )
dprintf(1, "^C");
if ( signum == SIGQUIT )
dprintf(1, "^\\");
if ( signum == SIGTERM )
{
got_sigterm = 1;
if ( forward_sigterm_to )
kill(forward_sigterm_to, SIGTERM);
}
}
bool check_real(const char* username, const char* password)
@ -121,10 +112,8 @@ bool check_begin(struct check* chk,
{
sigdelset(&chk->oldset, SIGINT);
sigdelset(&chk->oldset, SIGQUIT);
sigdelset(&chk->oldset, SIGTERM);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
unsigned int termmode = TERMMODE_UNICODE | TERMMODE_SIGNAL |
TERMMODE_UTF8 | TERMMODE_LINEBUFFER |
TERMMODE_ECHO;
@ -155,17 +144,6 @@ bool check_end(struct check* chk, bool* result, bool try)
fcntl(chk->pipe, F_SETFL, fcntl(chk->pipe, F_GETFL) | O_NONBLOCK);
chk->pipe_nonblock = true;
}
sigset_t sigterm, oldset;
sigemptyset(&sigterm);
sigaddset(&sigterm, SIGTERM);
struct sigaction sa = { .sa_handler = on_interrupt_signal }, old_sa;
if ( !try )
{
sigprocmask(SIG_BLOCK, &sigterm, &oldset);
forward_sigterm_to = chk->pid;
sigaction(SIGTERM, &sa, &old_sa);
sigprocmask(SIG_UNBLOCK, &sigterm, NULL);
}
while ( chk->errnum_done < sizeof(chk->errnum_bytes) )
{
ssize_t amount = read(chk->pipe, chk->errnum_bytes + chk->errnum_done,
@ -178,13 +156,6 @@ bool check_end(struct check* chk, bool* result, bool try)
}
chk->errnum_done += amount;
}
if ( !try )
{
sigprocmask(SIG_BLOCK, &sigterm, NULL);
forward_sigterm_to = 0;
sigaction(SIGTERM, &old_sa, NULL);
sigprocmask(SIG_SETMASK, &oldset, NULL);
}
int code;
pid_t wait_ret = waitpid(chk->pid, &code, try ? WNOHANG : 0);
if ( try && wait_ret == 0 )
@ -261,11 +232,9 @@ bool login(const char* username, const char* session)
{
sigdelset(&oldset, SIGINT);
sigdelset(&oldset, SIGQUIT);
sigdelset(&oldset, SIGTERM);
sigdelset(&oldset, SIGTSTP);
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
(void) (
setpgid(0, 0) < 0 ||
close(pipe_fds[0]) < 0 ||
@ -285,7 +254,6 @@ bool login(const char* username, const char* session)
open("/dev/tty", O_WRONLY) != 2 ||
setcloexecfrom(3) < 0 ||
tcsetpgrp(0, getpgid(0)) ||
// TODO: Do this immediately? At least unblock SIGTERM.
sigprocmask(SIG_SETMASK, &oldset, NULL) < 0 ||
settermmode(0, TERMMODE_NORMAL) < 0 ||
(session ?
@ -301,34 +269,13 @@ bool login(const char* username, const char* session)
}
free(login_shell);
close(pipe_fds[1]);
sigset_t sigterm;
sigemptyset(&sigterm);
sigaddset(&sigterm, SIGTERM);
sigprocmask(SIG_BLOCK, &sigterm, NULL);
struct sigaction sa = { .sa_handler = on_interrupt_signal }, old_sa;
forward_sigterm_to = child_pid;
sigaction(SIGTERM, &sa, &old_sa);
sigprocmask(SIG_UNBLOCK, &sigterm, NULL);
// TODO: What happens if EINTR happens here? waitpid might block.
int errnum;
if ( readall(pipe_fds[0], &errnum, sizeof(errnum)) < (ssize_t) sizeof(errnum) )
errnum = 0;
close(pipe_fds[0]);
int child_status;
while ( waitpid(child_pid, &child_status, 0) < 0 )
{
if ( errno == EINTR )
continue;
if ( waitpid(child_pid, &child_status, 0) < 0 )
errnum = errno;
break;
}
sigprocmask(SIG_BLOCK, &sigterm, NULL);
forward_sigterm_to = 0;
sigaction(SIGTERM, &old_sa, NULL);
tcsetattr(0, TCSAFLUSH, &tio);
tcsetpgrp(0, getpgid(0));
sigprocmask(SIG_SETMASK, &oldset, NULL);
@ -387,7 +334,7 @@ bool parse_username(const char* input,
*session = NULL;
*action = SPECIAL_ACTION_NONE;
if ( !strcmp(input, "exit") )
return *action = SPECIAL_ACTION_EXIT, true;
return *action = SPECIAL_ACTION_POWEROFF, true;
else if ( !strcmp(input, "poweroff") )
return *action = SPECIAL_ACTION_POWEROFF, true;
else if ( !strcmp(input, "reboot") )
@ -429,7 +376,6 @@ void handle_special(enum special_action action)
switch ( action )
{
case SPECIAL_ACTION_NONE: return;
case SPECIAL_ACTION_EXIT: exit(0);
case SPECIAL_ACTION_POWEROFF: exit(0);
case SPECIAL_ACTION_REBOOT: exit(1);
case SPECIAL_ACTION_HALT: exit(2);
@ -448,7 +394,7 @@ int textual(void)
char* username = NULL;
char* session = NULL;
while ( !got_sigterm )
while ( true )
{
char hostname[HOST_NAME_MAX + 1];
hostname[0] = '\0';
@ -514,9 +460,6 @@ int textual(void)
continue;
}
if ( got_sigterm )
break;
if ( !login(username, session) )
{
warn("logging in as %s", username);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, 2023, 2024 Jonas 'Sortie' Termansen.
* Copyright (c) 2014, 2015, 2023 Jonas 'Sortie' Termansen.
* Copyright (c) 2023 dzwdz.
*
* Permission to use, copy, modify, and distribute this software for any
@ -39,14 +39,12 @@ struct check
enum special_action
{
SPECIAL_ACTION_NONE,
SPECIAL_ACTION_EXIT,
SPECIAL_ACTION_POWEROFF,
SPECIAL_ACTION_REBOOT,
SPECIAL_ACTION_HALT,
SPECIAL_ACTION_REINIT,
};
void on_interrupt_signal(int signum);
bool login(const char* username, const char* session);
bool check_real(const char* username, const char* password);
bool check_begin(struct check* chk,
@ -64,7 +62,4 @@ bool parse_username(const char* input,
enum special_action* action);
void handle_special(enum special_action action);
extern pid_t forward_sigterm_to;
extern volatile sig_atomic_t got_sigterm;
#endif

10
sh/sh.c
View file

@ -1183,8 +1183,6 @@ struct execute_result execute(char** tokens,
return result;
}
signal(SIGHUP, SIG_DFL);
setpgid(0, pgid != -1 ? pgid : 0);
if ( interactive && pgid == -1 )
{
@ -2044,7 +2042,7 @@ static int run(FILE* fp,
read_command_non_interactive(&sh_read_command, fp);
if ( sh_read_command.abort_condition )
break;
continue;
if ( sh_read_command.eof_condition )
{
@ -2139,9 +2137,6 @@ static int top(FILE* fp,
if ( *script_exited || (status != 0 && exit_on_error) )
return status;
// Receive read EOF instead so we save the shell history.
signal(SIGHUP, SIG_IGN);
edit_line_history_load(&edit_state, getenv("HISTFILE"));
}
@ -2149,10 +2144,7 @@ static int top(FILE* fp,
status);
if ( interactive )
{
edit_line_history_save(&edit_state, getenv("HISTFILE"));
signal(SIGHUP, SIG_DFL);
}
return status;
}