diff options
-rw-r--r-- | Kernel/Process.cpp | 51 | ||||
-rw-r--r-- | Kernel/Process.h | 7 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 12 | ||||
-rw-r--r-- | Kernel/Syscall.h | 7 | ||||
-rw-r--r-- | LibC/setjmp.cpp | 13 | ||||
-rw-r--r-- | LibC/signal.cpp | 6 | ||||
-rw-r--r-- | LibC/signal.h | 1 | ||||
-rw-r--r-- | LibC/unistd.cpp | 35 | ||||
-rw-r--r-- | LibC/unistd.h | 4 |
9 files changed, 134 insertions, 2 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index e3d6f21870..b0ca2dc841 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1035,6 +1035,23 @@ int Process::sys$close(int fd) return rc; } +int Process::sys$access(const char* pathname, int mode) +{ + (void) mode; + VALIDATE_USER_READ(pathname, strlen(pathname)); + ASSERT_NOT_REACHED(); +} + +int Process::sys$fstat(int fd, Unix::stat* statbuf) +{ + VALIDATE_USER_WRITE(statbuf, sizeof(Unix::stat)); + auto* descriptor = file_descriptor(fd); + if (!descriptor) + return -EBADF; + descriptor->stat(statbuf); + return 0; +} + int Process::sys$lstat(const char* path, Unix::stat* statbuf) { VALIDATE_USER_WRITE(statbuf, sizeof(Unix::stat)); @@ -1139,6 +1156,36 @@ int Process::sys$open(const char* path, int options) return fd; } +int Process::sys$pipe(int* pipefd) +{ + VALIDATE_USER_WRITE(pipefd, sizeof(int) * 2); + ASSERT_NOT_REACHED(); +} + +int Process::sys$killpg(int pgrp, int signum) +{ + if (signum < 1 || signum >= 32) + return -EINVAL; + (void) pgrp; + ASSERT_NOT_REACHED(); +} + +int Process::sys$setuid(uid_t) +{ + ASSERT_NOT_REACHED(); +} + +int Process::sys$setgid(gid_t) +{ + ASSERT_NOT_REACHED(); +} + +unsigned Process::sys$alarm(unsigned seconds) +{ + (void) seconds; + ASSERT_NOT_REACHED(); +} + int Process::sys$uname(utsname* buf) { VALIDATE_USER_WRITE(buf, sizeof(utsname)); @@ -1472,7 +1519,7 @@ int Process::sys$dup2(int old_fd, int new_fd) Unix::sighandler_t Process::sys$signal(int signum, Unix::sighandler_t handler) { // FIXME: Fail with -EINVAL if attepmting to catch or ignore SIGKILL or SIGSTOP. - if (signum >= 32) + if (signum < 1 || signum >= 32) return (Unix::sighandler_t)-EINVAL; dbgprintf("sys$signal: %d => L%x\n", signum, handler); return nullptr; @@ -1508,7 +1555,7 @@ int Process::sys$sigpending(Unix::sigset_t* set) int Process::sys$sigaction(int signum, const Unix::sigaction* act, Unix::sigaction* old_act) { // FIXME: Fail with -EINVAL if attepmting to change action for SIGKILL or SIGSTOP. - if (signum >= 32) + if (signum < 1 || signum >= 32) return -EINVAL; VALIDATE_USER_READ(act, sizeof(Unix::sigaction)); InterruptDisabler disabler; // FIXME: This should use a narrower lock. diff --git a/Kernel/Process.h b/Kernel/Process.h index 3b2f684de1..9a47ab6073 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -129,6 +129,7 @@ public: int sys$close(int fd); ssize_t sys$read(int fd, void* outbuf, size_t nread); ssize_t sys$write(int fd, const void*, size_t); + int sys$fstat(int fd, Unix::stat*); int sys$lstat(const char*, Unix::stat*); int sys$stat(const char*, Unix::stat*); int sys$lseek(int fd, off_t, int whence); @@ -163,6 +164,12 @@ public: int sys$sigpending(Unix::sigset_t*); int sys$getgroups(int size, gid_t*); int sys$setgroups(size_t, const gid_t*); + int sys$pipe(int* pipefd); + int sys$killpg(int pgrp, int sig); + int sys$setgid(gid_t); + int sys$setuid(uid_t); + unsigned sys$alarm(unsigned seconds); + int sys$access(const char* pathname, int mode); static void initialize(); diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 2356e33a8e..d702e8d4c1 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -161,6 +161,18 @@ static DWORD handle(RegisterDump& regs, DWORD function, DWORD arg1, DWORD arg2, return 0; case Syscall::SC_sigprocmask: return current->sys$sigprocmask((int)arg1, (const Unix::sigset_t*)arg2, (Unix::sigset_t*)arg3); + case Syscall::SC_pipe: + return current->sys$pipe((int*)arg1); + case Syscall::SC_killpg: + return current->sys$killpg((int)arg1, (int)arg2); + case Syscall::SC_setuid: + return current->sys$setuid((uid_t)arg1); + case Syscall::SC_setgid: + return current->sys$setgid((gid_t)arg1); + case Syscall::SC_alarm: + return current->sys$alarm((unsigned)arg1); + case Syscall::SC_access: + return current->sys$access((const char*)arg1, (int)arg2); default: kprintf("<%u> int0x80: Unknown function %x requested {%x, %x, %x}\n", current->pid(), function, arg1, arg2, arg3); break; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 3cd39912aa..d18aa803b7 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -56,6 +56,13 @@ __ENUMERATE_SYSCALL(sigreturn) \ __ENUMERATE_SYSCALL(sigprocmask) \ __ENUMERATE_SYSCALL(sigpending) \ + __ENUMERATE_SYSCALL(pipe) \ + __ENUMERATE_SYSCALL(killpg) \ + __ENUMERATE_SYSCALL(setuid) \ + __ENUMERATE_SYSCALL(setgid) \ + __ENUMERATE_SYSCALL(alarm) \ + __ENUMERATE_SYSCALL(fstat) \ + __ENUMERATE_SYSCALL(access) \ #define DO_SYSCALL_A0(function) Syscall::invoke((dword)(function)) diff --git a/LibC/setjmp.cpp b/LibC/setjmp.cpp index e69de29bb2..b7378d1f4a 100644 --- a/LibC/setjmp.cpp +++ b/LibC/setjmp.cpp @@ -0,0 +1,13 @@ +#include <setjmp.h> +#include <assert.h> +#include <Kernel/Syscall.h> + +int setjmp(jmp_buf) +{ + assert(false); +} + +void longjmp(jmp_buf, int val) +{ + assert(false); +} diff --git a/LibC/signal.cpp b/LibC/signal.cpp index 32a08e32dc..362f1587dc 100644 --- a/LibC/signal.cpp +++ b/LibC/signal.cpp @@ -11,6 +11,12 @@ int kill(pid_t pid, int sig) __RETURN_WITH_ERRNO(rc, rc, -1); } +int killpg(int pgrp, int sig) +{ + int rc = Syscall::invoke(Syscall::SC_killpg, (dword)pgrp, (dword)sig); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + sighandler_t signal(int signum, sighandler_t handler) { sighandler_t old_handler = (sighandler_t)Syscall::invoke(Syscall::SC_signal, (dword)signum, (dword)handler); diff --git a/LibC/signal.h b/LibC/signal.h index 99e3283446..cb3b7599af 100644 --- a/LibC/signal.h +++ b/LibC/signal.h @@ -22,6 +22,7 @@ struct sigaction { }; int kill(pid_t, int sig); +int killpg(int pgrp, int sig); sighandler_t signal(int sig, sighandler_t); int sigaction(int sig, const struct sigaction* act, struct sigaction* old_act); int sigemptyset(sigset_t*); diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index f1dbded90e..d1aaeaa3d9 100644 --- a/LibC/unistd.cpp +++ b/LibC/unistd.cpp @@ -147,6 +147,12 @@ int stat(const char* path, struct stat* statbuf) __RETURN_WITH_ERRNO(rc, rc, -1); } +int fstat(int fd, struct stat *statbuf) +{ + int rc = Syscall::invoke(Syscall::SC_fstat, (dword)fd, (dword)statbuf); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + int chdir(const char* path) { int rc = Syscall::invoke(Syscall::SC_chdir, (dword)path); @@ -233,4 +239,33 @@ int getgroups(int size, gid_t list[]) __RETURN_WITH_ERRNO(rc, rc, -1); } +int pipe(int pipefd[2]) +{ + int rc = Syscall::invoke(Syscall::SC_pipe, (dword)pipefd); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + +unsigned int alarm(unsigned int seconds) +{ + return Syscall::invoke(Syscall::SC_alarm, (dword)seconds); +} + +int setuid(uid_t uid) +{ + int rc = Syscall::invoke(Syscall::SC_setuid, (dword)uid); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + +int setgid(uid_t gid) +{ + int rc = Syscall::invoke(Syscall::SC_setgid, (dword)gid); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + +int access(const char* pathname, int mode) +{ + int rc = Syscall::invoke(Syscall::SC_access, (dword)pathname, (dword)mode); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + } diff --git a/LibC/unistd.h b/LibC/unistd.h index 81e9146ae8..85b07a4e8f 100644 --- a/LibC/unistd.h +++ b/LibC/unistd.h @@ -33,6 +33,7 @@ pid_t waitpid(pid_t, int* wstatus, int options); int chdir(const char* path); char* getcwd(char* buffer, size_t size); char* getwd(char* buffer); +int fstat(int fd, struct stat* statbuf); int lstat(const char* path, struct stat* statbuf); int stat(const char* path, struct stat* statbuf); int sleep(unsigned seconds); @@ -46,6 +47,9 @@ int unlink(const char* pathname); int getdtablesize(); int dup(int old_fd); int dup2(int old_fd, int new_fd); +int pipe(int pipefd[2]); +unsigned int alarm(unsigned int seconds); +int access(const char* pathname, int mode); #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) #define WTERMSIG(status) ((status) & 0x7f) |