Compare commits
59 commits
cef7779f31
...
c6c285a414
Author | SHA1 | Date | |
---|---|---|---|
|
c6c285a414 | ||
|
b9c49648c4 | ||
|
e2a55139ad | ||
|
870cfa3668 | ||
|
d7ab7c552e | ||
|
d1632a9706 | ||
|
bd3d7df078 | ||
|
9c3ed11e09 | ||
|
cacb2e9c8e | ||
|
d07beee30a | ||
|
2d221e1ff1 | ||
|
bb7bd58ea8 | ||
|
c14c3c2e99 | ||
|
d4115c424a | ||
|
c3c5463e61 | ||
|
cd9da4da59 | ||
|
f757228bd8 | ||
|
0b2c6b91a0 | ||
|
c741dc1863 | ||
|
5abfe83b3a | ||
|
70d133ca8a | ||
|
f549ab4b77 | ||
|
f287d7298a | ||
|
824df667b2 | ||
|
9c23917c11 | ||
|
5b61b05fec | ||
|
2883ecb5ff | ||
|
2710f60690 | ||
|
c4e0a79bc1 | ||
|
8f466ecc13 | ||
|
d1574c1682 | ||
|
9a0670f055 | ||
|
18aab49cad | ||
|
5a877ea44b | ||
|
365ada713e | ||
|
3ba95b7415 | ||
|
1e4acb7401 | ||
|
1e9cd96738 | ||
|
e0d5ebc747 | ||
|
762f4feb75 | ||
|
8bb8718327 | ||
|
0e12ffcf60 | ||
|
eef9932761 | ||
|
0135f8a6fa | ||
|
59c69f4ee9 | ||
|
718fae5b87 | ||
|
56517529c0 | ||
|
e664dd5998 | ||
|
561771df54 | ||
|
4e56ca101c | ||
|
c9ca26f108 | ||
|
ea2e033ad6 | ||
|
07694a1ee1 | ||
|
74aa386f39 | ||
|
36d95209dc | ||
|
359b1a8642 | ||
|
77ad36cda8 | ||
|
faf0acef59 | ||
|
1f840b1e36 |
33 changed files with 355 additions and 791 deletions
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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") )
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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, ®s.sigmask, sizeof(sigset_t));
|
||||
memcpy(&thread->signal_stack, ®s.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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++ )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(®isters, 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, ®s, 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 )
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
10
sh/sh.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue