diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index ca0ed9b66cc..4bf39c045cf 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 21492915de0..aa968812586 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 afa6694f04b..495dbde41c9 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 index a074bdec66a..9e4402d6903 100644 Binary files a/Kernel/_fs_contents and b/Kernel/_fs_contents differ diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index da7e5591032..1640ab03570 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 6a5b40f3a75..74ee98ebdaf 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 68bd4dd2863..7fb929dfdc5 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; }