diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-10-27 01:24:22 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-10-27 01:24:22 +0200 |
commit | ec07761d0fb654ac7a43089ad865a88340e67f3e (patch) | |
tree | 1ef1e48e8e1f24cc0fe5c2cbee0518e2876b08b7 | |
parent | 5cfeeede7cbf46dddfaac912094922c3c43d7db4 (diff) | |
download | serenity-ec07761d0fb654ac7a43089ad865a88340e67f3e.zip |
Implement waitpid() support for getting the waitee's exit code.
-rw-r--r-- | Kernel/Syscall.cpp | 2 | ||||
-rw-r--r-- | Kernel/Task.cpp | 16 | ||||
-rw-r--r-- | Kernel/Task.h | 3 | ||||
-rw-r--r-- | Kernel/_fs_contents | bin | 1024000 -> 1024000 bytes | |||
-rw-r--r-- | LibC/unistd.cpp | 4 | ||||
-rw-r--r-- | LibC/unistd.h | 6 | ||||
-rw-r--r-- | Userland/sh.cpp | 12 |
7 files changed, 33 insertions, 10 deletions
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index ca0ed9b66c..4bf39c045c 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -95,7 +95,7 @@ DWORD handle(DWORD function, DWORD arg1, DWORD arg2, DWORD arg3) case Syscall::PosixGetpid: return current->sys$getpid(); case Syscall::PosixWaitpid: - return current->sys$waitpid((pid_t)arg1); + return current->sys$waitpid((pid_t)arg1, (int*)arg2, (int)arg3); case Syscall::PosixMmap: return (dword)current->sys$mmap((void*)arg1, (size_t)arg2); case Syscall::PosixMunmap: diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 21492915de..aa96881258 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -450,8 +450,13 @@ void Task::sys$exit(int status) s_tasks->remove(this); + for (auto* task = s_tasks->head(); task; task = task->next()) { + if (task->waitee() == m_pid) + task->m_waiteeStatus = status << 8; + } + if (!scheduleNewTask()) { - kprintf("Task::taskDidCrash: Failed to schedule a new task :(\n"); + kprintf("Task::sys$exit: Failed to schedule a new task :(\n"); HANG; } @@ -752,7 +757,6 @@ int Task::sys$chdir(const char* path) if (!handle->isDirectory()) return -ENOTDIR; m_cwd = handle->vnode(); - kprintf("m_cwd <- %p (%u)\n", m_cwd.ptr(), handle->vnode()->inode.index()); return 0; } @@ -844,14 +848,20 @@ pid_t Task::sys$getpid() return m_pid; } -pid_t Task::sys$waitpid(pid_t waitee) +pid_t Task::sys$waitpid(pid_t waitee, int* wstatus, int options) { + if (wstatus) + VALIDATE_USER_BUFFER(wstatus, sizeof(int)); + InterruptDisabler disabler; if (!Task::fromPID(waitee)) return -1; m_waitee = waitee; + m_waiteeStatus = 0; block(BlockedWait); yield(); + if (wstatus) + *wstatus = m_waiteeStatus; return m_waitee; } diff --git a/Kernel/Task.h b/Kernel/Task.h index afa6694f04..495dbde41c 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -95,7 +95,7 @@ public: int sys$geterror() { return m_error; } void sys$exit(int status); int sys$spawn(const char* path, const char** args); - pid_t sys$waitpid(pid_t); + pid_t sys$waitpid(pid_t, int* wstatus, int options); void* sys$mmap(void*, size_t size); int sys$munmap(void*, size_t size); int sys$get_dir_entries(int fd, void*, size_t); @@ -160,6 +160,7 @@ private: void* m_kernelStack { nullptr }; dword m_timesScheduled { 0 }; pid_t m_waitee { -1 }; + int m_waiteeStatus { 0 }; int m_fdBlockedOnRead { -1 }; size_t m_maxFileHandles { 16 }; diff --git a/Kernel/_fs_contents b/Kernel/_fs_contents Binary files differindex a074bdec66..9e4402d690 100644 --- a/Kernel/_fs_contents +++ b/Kernel/_fs_contents diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index da7e559103..1640ab0357 100644 --- a/LibC/unistd.cpp +++ b/LibC/unistd.cpp @@ -39,9 +39,9 @@ int close(int fd) __RETURN_WITH_ERRNO(rc, rc, -1); } -pid_t waitpid(pid_t waitee) +pid_t waitpid(pid_t waitee, int* wstatus, int options) { - int rc = Syscall::invoke(Syscall::PosixWaitpid, waitee); + int rc = Syscall::invoke(Syscall::PosixWaitpid, waitee, (dword)wstatus); __RETURN_WITH_ERRNO(rc, rc, -1); } diff --git a/LibC/unistd.h b/LibC/unistd.h index 6a5b40f3a7..74ee98ebda 100644 --- a/LibC/unistd.h +++ b/LibC/unistd.h @@ -10,13 +10,17 @@ pid_t getpid(); int open(const char* path); ssize_t read(int fd, void* buf, size_t count); int close(int fd); -pid_t waitpid(pid_t); +pid_t waitpid(pid_t, int* wstatus, int options); int chdir(const char* path); char* getcwd(char* buffer, size_t size); int lstat(const char* path, stat* statbuf); int sleep(unsigned seconds); int gethostname(char*, size_t); +#define WEXITSTATUS(status) (((status) & 0xff00) >> 8) +#define WTERMSIG(status) ((status) & 0x7f) +#define WIFEXITED(status) (WTERMSIG(status) == 0) + #define HOST_NAME_MAX 64 #define S_IFMT 0170000 diff --git a/Userland/sh.cpp b/Userland/sh.cpp index 68bd4dd286..7fb929dfdc 100644 --- a/Userland/sh.cpp +++ b/Userland/sh.cpp @@ -17,7 +17,8 @@ static void prompt() static int sh_pwd(int, const char**) { - printf("cwd: %s\n", g_cwd); + printf("%s\n", g_cwd); + return 0; } static int sh_cd(int argc, const char** argv) @@ -100,7 +101,14 @@ static int runcmd(char* cmd) return 1; } // FIXME: waitpid should give us the spawned process's exit status - waitpid(ret); + int wstatus = 0; + waitpid(ret, &wstatus, 0); + + if (WIFEXITED(wstatus)) { + //printf("Exited normally with status %d\n", WEXITSTATUS(wstatus)); + } else { + printf("Exited abnormally\n"); + } return retval; } |