Fix stream life-time race condition by reversing ownership
This commit is contained in:
@@ -233,11 +233,11 @@ void edit_start(const char* volume, const char* file_path, const char* text, siz
|
||||
(int)(editor.cursor.line - editor.row_offset) + 1,
|
||||
(int)(editor.cursor.col - editor.col_offset) + 1 + (int)gutter_width);
|
||||
|
||||
stream_write(process_get_pgid(), STREAM_OUT, backbuffer, bbptr - backbuffer);
|
||||
stream_write(process_get_exec_pgid(), STREAM_OUT, backbuffer, bbptr - backbuffer);
|
||||
|
||||
uint8_t ch = 0;
|
||||
for (;;) {
|
||||
if (stream_read(process_get_pgid(), STREAM_IN, &ch, 1) > 0)
|
||||
if (stream_read(STREAM_IN, &ch, 1) > 0)
|
||||
break;
|
||||
else
|
||||
sched();
|
||||
|
||||
39
ce/interp.c
39
ce/interp.c
@@ -188,7 +188,7 @@ static void cat(struct context* context, char** file_paths, size_t files_count)
|
||||
return;
|
||||
}
|
||||
|
||||
stream_write(process_get_pgid(), STREAM_OUT, buffer, chunk_size);
|
||||
stream_write(process_get_exec_pgid(), STREAM_OUT, buffer, chunk_size);
|
||||
}
|
||||
|
||||
if (rem > 0) {
|
||||
@@ -198,7 +198,7 @@ static void cat(struct context* context, char** file_paths, size_t files_count)
|
||||
return;
|
||||
}
|
||||
|
||||
stream_write(process_get_pgid(), STREAM_OUT, buffer, rem);
|
||||
stream_write(process_get_exec_pgid(), STREAM_OUT, buffer, rem);
|
||||
}
|
||||
|
||||
filereader_fini(&fr);
|
||||
@@ -463,25 +463,17 @@ struct cmd_write_proc_ctx {
|
||||
int cancel_pid;
|
||||
};
|
||||
|
||||
static void cmd_collect_proc(void* arg) {
|
||||
int pgid = (int)(uintptr_t)arg;
|
||||
|
||||
char recv[1024];
|
||||
int n;
|
||||
for (;;) {
|
||||
if ((n = stream_read(pgid, STREAM_OUT, (void*)recv, sizeof(recv) - 1)) > 0)
|
||||
stream_write(process_get_pgid(), STREAM_OUT, (void*)recv, n);
|
||||
else
|
||||
sched();
|
||||
}
|
||||
}
|
||||
struct cmd_collect_proc_ctx {
|
||||
int pgid;
|
||||
int collect_pid;
|
||||
};
|
||||
|
||||
static void cmd_write_proc(void* arg) {
|
||||
struct cmd_write_proc_ctx* ctx = arg;
|
||||
|
||||
uint8_t ch = 0;
|
||||
for (;;) {
|
||||
if (stream_read(process_get_pgid(), STREAM_IN, &ch, 1) > 0) {
|
||||
if (stream_read(STREAM_IN, &ch, 1) > 0) {
|
||||
if (ch == KB_CTRL('C')) {
|
||||
kill(ctx->cancel_pid);
|
||||
return;
|
||||
@@ -494,6 +486,20 @@ static void cmd_write_proc(void* arg) {
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_collect_proc(void* arg) {
|
||||
struct cmd_collect_proc_ctx* ctx = arg;
|
||||
|
||||
int n;
|
||||
char recv[1024];
|
||||
for (;;) {
|
||||
if ((n = stream_read(STREAM_OUT, recv, sizeof(recv))) > 0) {
|
||||
stream_write(process_get_exec_pgid(), STREAM_OUT, recv, n);
|
||||
} else {
|
||||
sched();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void execute_cmd(struct ast_cmd* cmd, struct context* context, bool run_bg) {
|
||||
if (strcmp(cmd->name, "echo") == 0) {
|
||||
echo(context, cmd->args, cmd->arg_count);
|
||||
@@ -576,9 +582,10 @@ static void execute_cmd(struct ast_cmd* cmd, struct context* context, bool run_b
|
||||
cprintf(context, "started background process: PID %d\n", pid);
|
||||
} else {
|
||||
struct cmd_write_proc_ctx wpctx = {.pgid = pgid, .cancel_pid = pid};
|
||||
struct cmd_collect_proc_ctx cpctx = {.pgid = pgid, .collect_pid = pid};
|
||||
|
||||
struct process_data* write_pdata = process_spawn(&cmd_write_proc, (void*)&wpctx);
|
||||
struct process_data* collect_pdata = process_spawn(&cmd_collect_proc, (void*)(uintptr_t)pgid);
|
||||
struct process_data* collect_pdata = process_spawn(&cmd_collect_proc, (void*)&cpctx);
|
||||
|
||||
exec_partial_fini(pid);
|
||||
wait_for_pid(pid);
|
||||
|
||||
@@ -41,5 +41,6 @@
|
||||
#define SYS_VOLUME_DELETE 40
|
||||
#define SYS_DATE_TIME 41
|
||||
#define SYS_GET_CMDLINE 42
|
||||
#define SYS_PROC_IS_ALIVE 43
|
||||
|
||||
#endif // _M_SYSCALL_DEFS_H
|
||||
|
||||
@@ -18,7 +18,7 @@ static void receiver(void* arg) {
|
||||
char recv[RECV_MAX];
|
||||
int n;
|
||||
for (;;) {
|
||||
n = stream_read(ce_pgid, STREAM_OUT, (void*)recv, RECV_MAX - 1);
|
||||
n = stream_read(STREAM_OUT, (void*)recv, RECV_MAX - 1);
|
||||
|
||||
if (n > 0)
|
||||
terminal_print(recv, n);
|
||||
|
||||
@@ -60,7 +60,7 @@ struct proc* proc_from_elf(uint8_t* elf_contents) {
|
||||
proc->pdata.regs.rip = aux.entry;
|
||||
fx_init(proc->pdata.fx_env);
|
||||
|
||||
proc->exec_pid = -1;
|
||||
proc->exec_pid = proc->pid;
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
@@ -770,17 +770,11 @@ DEFINE_SYSCALL(sys_stream_write) {
|
||||
return SYSRESULT(ST_OK);
|
||||
}
|
||||
|
||||
/* int stream_read (int pgid, int rid, void* buffer, size_t size) */
|
||||
/* int stream_read (int rid, void* buffer, size_t size) */
|
||||
DEFINE_SYSCALL(sys_stream_read) {
|
||||
int pgid = (int)a1;
|
||||
int rid = (int)a2;
|
||||
uintptr_t uvaddr_buffer = a3;
|
||||
size_t buffer_size = (size_t)a4;
|
||||
|
||||
struct procgroup* target_procgroup = procgroup_find(pgid);
|
||||
|
||||
if (target_procgroup == NULL)
|
||||
return SYSRESULT(-ST_NOT_FOUND);
|
||||
int rid = (int)a1;
|
||||
uintptr_t uvaddr_buffer = a2;
|
||||
size_t buffer_size = (size_t)a3;
|
||||
|
||||
struct procgroup* procgroup = proc->procgroup;
|
||||
|
||||
@@ -789,7 +783,7 @@ DEFINE_SYSCALL(sys_stream_read) {
|
||||
if (buffer == NULL)
|
||||
return SYSRESULT(-ST_BAD_ADDRESS_SPACE);
|
||||
|
||||
struct proc_resource* stream_resource = proc_find_resource(target_procgroup, rid);
|
||||
struct proc_resource* stream_resource = proc_find_resource(procgroup, rid);
|
||||
|
||||
if (stream_resource == NULL)
|
||||
return SYSRESULT(-ST_NOT_FOUND);
|
||||
@@ -893,6 +887,13 @@ DEFINE_SYSCALL(sys_get_cmdline) {
|
||||
return SYSRESULT(procgroup->uvaddr_cmdline);
|
||||
}
|
||||
|
||||
/* int proc_is_alive(int pid) */
|
||||
DEFINE_SYSCALL(sys_proc_is_alive) {
|
||||
int pid = (int)a1;
|
||||
|
||||
return SYSRESULT(proc_find_pid(pid) != NULL ? 1 : 0);
|
||||
}
|
||||
|
||||
static syscall_handler_func_t handler_table[] = {
|
||||
[SYS_QUIT] = &sys_quit,
|
||||
[SYS_TEST] = &sys_test,
|
||||
@@ -934,6 +935,7 @@ static syscall_handler_func_t handler_table[] = {
|
||||
[SYS_VOLUME_DELETE] = &sys_volume_delete,
|
||||
[SYS_DATE_TIME] = &sys_date_time,
|
||||
[SYS_GET_CMDLINE] = &sys_get_cmdline,
|
||||
[SYS_PROC_IS_ALIVE] = &sys_proc_is_alive,
|
||||
};
|
||||
|
||||
syscall_handler_func_t syscall_find_handler(int syscall_num) {
|
||||
|
||||
@@ -46,7 +46,7 @@ void in_stream_read_line(const char* prompt, char* buffer, size_t max) {
|
||||
for (;;) {
|
||||
uint8_t ch;
|
||||
|
||||
if (stream_read(process_get_pgid(), STREAM_IN, &ch, 1) <= 0) {
|
||||
if (stream_read(STREAM_IN, &ch, 1) <= 0) {
|
||||
sched();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <debugconsole.h>
|
||||
#include <mprintf.h>
|
||||
#include <printf.h>
|
||||
#include <process.h>
|
||||
@@ -32,7 +33,7 @@ void mprintf(const char* fmt, ...) {
|
||||
|
||||
va_end(args);
|
||||
|
||||
stream_write(process_get_pgid(), STREAM_OUT, mprintf_buffer, len);
|
||||
stream_write(process_get_exec_pgid(), STREAM_OUT, mprintf_buffer, len);
|
||||
|
||||
mprintf_buffer_unlock();
|
||||
}
|
||||
|
||||
@@ -101,8 +101,8 @@ int stream_write(int pgid, int rid, void* buffer, size_t size) {
|
||||
return (int)do_syscall(SYS_STREAM_WRITE, pgid, rid, buffer, size);
|
||||
}
|
||||
|
||||
int stream_read(int pgid, int rid, void* buffer, size_t size) {
|
||||
return (int)do_syscall(SYS_STREAM_READ, pgid, rid, buffer, size);
|
||||
int stream_read(int rid, void* buffer, size_t size) {
|
||||
return (int)do_syscall(SYS_STREAM_READ, rid, buffer, size);
|
||||
}
|
||||
|
||||
int get_proc_info(struct proc_info* infos, size_t count) {
|
||||
@@ -122,3 +122,5 @@ int volume_delete(const char* key) { return (int)do_syscall(SYS_VOLUME_DELETE, k
|
||||
int date_time(struct date_time* dt) { return (int)do_syscall(SYS_DATE_TIME, dt); }
|
||||
|
||||
const char* get_cmdline(void) { return (const char*)do_syscall(SYS_GET_CMDLINE, 0); }
|
||||
|
||||
int proc_is_alive(int pid) { return (int)do_syscall(SYS_PROC_IS_ALIVE, pid); }
|
||||
|
||||
@@ -110,7 +110,7 @@ int get_self_pid(void);
|
||||
int stream_write(int pgid, int rid, void* buffer, size_t size);
|
||||
|
||||
/* Read from a stream */
|
||||
int stream_read(int pgid, int rid, void* buffer, size_t size);
|
||||
int stream_read(int rid, void* buffer, size_t size);
|
||||
|
||||
/* get process information */
|
||||
int get_proc_info(struct proc_info* infos, size_t count);
|
||||
@@ -130,4 +130,7 @@ int date_time(struct date_time* dt);
|
||||
/* Get commandline string */
|
||||
const char* get_cmdline(void);
|
||||
|
||||
/* check if PID is alive */
|
||||
int proc_is_alive(int pid);
|
||||
|
||||
#endif // _LIBMSL_M_SYSTEM_H
|
||||
|
||||
Reference in New Issue
Block a user