os

An operating system
git clone https://erai.gay/code/os/
Log | Files | Refs | README | LICENSE

commit b553458289d3ba0983b1bba51f07c588100ad8e6
parent 79c3f601382979ac79163a0b0c78a7b12be32f7f
Author: erai <erai@omiltem.net>
Date:   Tue,  4 Jun 2024 23:26:56 -0400

signal handlers

Diffstat:
Mas.c | 5+++++
Mcc1.c | 6++++++
Msshd.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
Msyscall.c | 34++++++++++++++++++++++++++++++++--
4 files changed, 109 insertions(+), 14 deletions(-)

diff --git a/as.c b/as.c @@ -307,6 +307,11 @@ fixup_label(c: *assembler, l: *label) { } } +emit_restorer(c: *assembler) { + as_modri(c, OP_MOVI, R_RAX, 15); + as_op(c, OP_SYSCALL); +} + emit_ptr(c: *assembler, l: *label) { reserve(c, 16); as_modrm(c, OP_LEA, R_RAX, R_RIP, 0, 0, 128); diff --git a/cc1.c b/cc1.c @@ -1613,6 +1613,12 @@ main(argc: int, argv: **byte, envp: **byte) { emit_ret(c.as); } + d = find(c, "_restorer", 0:*byte, 1); + if (d.func_defined && !d.func_label.fixed) { + fixup_label(c.as, d.func_label); + emit_restorer(c.as); + } + d = find(c, "_include", 0:*byte, 1); if (d.func_defined && !d.func_label.fixed) { fixup_label(c.as, d.func_label); diff --git a/sshd.c b/sshd.c @@ -1,27 +1,33 @@ read_line(fd: int, buf: *byte, max: int): int { var len: int; - var c: int; + var ret: int; + var c: byte; len = 0; loop { if len == max { return 0; } - c = fdgetc(fd); - if c == '\n' { - buf[len] = 0:byte; - return len; + ret = read(fd, &c, 1); + + if ret == -EINTR { + continue; } - if c == -1 { + if ret == 0 { return 0; } - if c == '\r' { + if c == '\n':byte { + buf[len] = 0:byte; + return len; + } + + if c == '\r':byte { continue; } - buf[len] = c:byte; + buf[len] = c; len = len + 1; } } @@ -34,6 +40,9 @@ writeall(fd: int, buf: *byte, n: int): int { } ret = write(fd, buf, n); + if ret == -EINTR { + continue; + } if ret < 0 { return ret; } @@ -51,6 +60,10 @@ read_fill(fd: int, buf: *byte, n: int): int { } ret = read(fd, buf, n); + if ret == -EINTR { + continue; + } + if ret <= 0 { return -1; } @@ -1265,7 +1278,7 @@ doauth(ctx: *sshd_ctx) { // <- SSH_MSG_USERAUTH_REQUEST read_frame(ctx); decode_userauth_request(&cua, ctx); - if !ssh_streq(&cua.service, "ssh-connection") || !ssh_streq(&cua.user, "erai") { + if !ssh_streq(&cua.service, "ssh-connection") || !ssh_streq(&cua.user, ctx.username) { die("bad auth"); } @@ -1312,7 +1325,7 @@ doauth(ctx: *sshd_ctx) { encode_str(&s, ctx); b = SSH_MSG_USERAUTH_REQUEST; encode_u8(&b, ctx); - set_str(&s, "erai"); + set_str(&s, ctx.username); encode_str(&s, ctx); set_str(&s, "ssh-connection"); encode_str(&s, ctx); @@ -1520,6 +1533,20 @@ dorequest(ctx: *sshd_ctx) { } } +struct pfd4 { + p0: int; + p1: int; + p2: int; + p3: int; +} + +reset_pfd(pfd: *int, ctx: *sshd_ctx) { + pfd[0] = ctx.fd | (POLLIN << 32); + pfd[1] = ctx.child_stdin | (POLLOUT << 32); + pfd[2] = ctx.child_stdout | (POLLIN << 32); + pfd[3] = ctx.child_stderr | (POLLIN << 32); +} + client_loop(ctx: *sshd_ctx) { var tag: int; @@ -1575,6 +1602,7 @@ struct sshd_ctx { userpub: _ed25519_pub; hostkey: *byte; hostkeylen: int; + username: *byte; userkey: *byte; userkeylen: int; buf: *byte; @@ -1625,6 +1653,25 @@ format_key(d: **byte, dlen: *int, k: *byte, ctx: *sshd_ctx) { clear_frame(ctx); } +dosigchld() { + loop { + if wait(-1, 0:*int, WNOHANG) < 0 { + break; + } + } +} + +_restorer(); + +signal(sig: int, handler: func()) { + var act: sigaction; + act.handler = (&dosigchld):int; + act.flags = 1 << 26; + act.restorer = _restorer:int; + act.mask = 0; + sigaction(sig, &act, 0:*sigaction); +} + main(argc: int, argv: **byte, envp: **byte) { var fd: int; var cfd: int; @@ -1634,6 +1681,8 @@ main(argc: int, argv: **byte, envp: **byte) { var a: alloc; setup_alloc(&a); + signal(SIGCHLD, dosigchld); + bzero((&ctx):*byte, sizeof(ctx)); if unhex((&ctx.userpub):*byte, "5afb3032d86d60d700e1782bfe8083ff95504cecbda531bef5ba8cdd20f34c82") != 32 { @@ -1649,6 +1698,7 @@ main(argc: int, argv: **byte, envp: **byte) { ctx.ckex = alloc(ctx.a, 4096); ctx.sver = "SSH-2.0-omiltem"; + ctx.username = "erai"; format_key(&ctx.hostkey, &ctx.hostkeylen, (&ctx.pub):*byte, &ctx); format_key(&ctx.userkey, &ctx.userkeylen, (&ctx.userpub):*byte, &ctx); @@ -1657,7 +1707,7 @@ main(argc: int, argv: **byte, envp: **byte) { die("failed to open socket"); } - port = 2020; + port = 2222; sa.fpa = AF_INET | ((port & 0xff) << 24) | (((port >> 8) & 0xff) << 16); sa.pad = 0; if bind(fd, (&sa):*byte, sizeof(sa)) != 0 { @@ -1670,10 +1720,14 @@ main(argc: int, argv: **byte, envp: **byte) { loop { ctx.fd = accept(fd, 0:*byte, 0:*int); - if ctx.fd < 0 { + if ctx.fd == -EINTR { continue; } + if ctx.fd < 0 { + exit(1); + } + if fork() == 0 { close(fd); cmain(&ctx); diff --git a/syscall.c b/syscall.c @@ -7,11 +7,23 @@ enum { O_CREAT = 64, O_DIRECTORY = 0x1000, + EINTR = 4, + AF_INET = 2, SOCK_STREAM = 1, POLLIN = 1, POLLOUT = 4, + + WNOHANG = 1, + + SIG_DFL = 0, + SIG_IGN = 1, + + SIGINT = 2, + SIGALRM = 14, + SIGCHLD = 17, + SIGWINCH = 28, } _start(argc: int, argv: **byte, envp: **byte) { @@ -39,7 +51,7 @@ fstat(fd: int, buf: *byte): int { return syscall(5, fd, buf:int, 0, 0, 0, 0); } -poll(pfd: *byte, nfd: int, timeout: int): int { +poll(pfd: *int, nfd: int, timeout: int): int { return syscall(7, pfd:int, nfd, timeout, 0, 0, 0); } @@ -47,6 +59,17 @@ mmap(addr: int, len: int, prot: int, flags: int, fd: int, off: int): int { return syscall(9, addr, len, prot, flags, fd, off); } +struct sigaction { + handler: int; + flags: int; + restorer: int; + mask: int; +} + +sigaction(sig: int, act: *sigaction, oact: *sigaction): int { + return syscall(13, sig, act:int, oact:int, 8, 0, 0); +} + pipe(rfd: *int, wfd: *int): int { var buf: int; var ret: int; @@ -91,7 +114,14 @@ exit(n: int) { } wait(pid: int, status: *int, flags: int): int { - return syscall(61, pid, status:int, flags, 0, 0, 0); + var s: int; + var ret: int; + s = 0; + ret = syscall(61, pid, s:int, flags, 0, 0, 0); + if status { + *status = s & (-1 >> 32); + } + return ret; } rename(oldname: *byte, newname: *byte): int {