summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-10-27 01:24:22 +0200
committerAndreas Kling <awesomekling@gmail.com>2018-10-27 01:24:22 +0200
commitec07761d0fb654ac7a43089ad865a88340e67f3e (patch)
tree1ef1e48e8e1f24cc0fe5c2cbee0518e2876b08b7
parent5cfeeede7cbf46dddfaac912094922c3c43d7db4 (diff)
downloadserenity-ec07761d0fb654ac7a43089ad865a88340e67f3e.zip
Implement waitpid() support for getting the waitee's exit code.
-rw-r--r--Kernel/Syscall.cpp2
-rw-r--r--Kernel/Task.cpp16
-rw-r--r--Kernel/Task.h3
-rw-r--r--Kernel/_fs_contentsbin1024000 -> 1024000 bytes
-rw-r--r--LibC/unistd.cpp4
-rw-r--r--LibC/unistd.h6
-rw-r--r--Userland/sh.cpp12
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
index a074bdec66..9e4402d690 100644
--- a/Kernel/_fs_contents
+++ b/Kernel/_fs_contents
Binary files differ
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;
}