kernel+libc: Implement waitpid()
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
41c7e3780d
commit
b6fb5f3dfe
@ -3,6 +3,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static char** split_command_into_argv(const char* cmd)
|
static char** split_command_into_argv(const char* cmd)
|
||||||
@ -94,7 +95,6 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't have sched_yield() or waitpid() yet...
|
if (waitpid(child, NULL, 0) < 0) perror("waitpid");
|
||||||
sleep(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ set(SOURCES
|
|||||||
src/sys/id.cpp
|
src/sys/id.cpp
|
||||||
src/sys/mkdir.cpp
|
src/sys/mkdir.cpp
|
||||||
src/sys/mknod.cpp
|
src/sys/mknod.cpp
|
||||||
|
src/sys/waitpid.cpp
|
||||||
src/fs/VFS.cpp
|
src/fs/VFS.cpp
|
||||||
src/fs/tmpfs/FileSystem.cpp
|
src/fs/tmpfs/FileSystem.cpp
|
||||||
src/fs/devices/DeviceRegistry.cpp
|
src/fs/devices/DeviceRegistry.cpp
|
||||||
|
@ -11,4 +11,5 @@ Result<u64> sys_exit(Registers*, SyscallArgs args)
|
|||||||
current->state = ThreadState::Exited;
|
current->state = ThreadState::Exited;
|
||||||
|
|
||||||
kernel_yield();
|
kernel_yield();
|
||||||
|
unreachable();
|
||||||
}
|
}
|
||||||
|
28
kernel/src/sys/waitpid.cpp
Normal file
28
kernel/src/sys/waitpid.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "memory/MemoryManager.h"
|
||||||
|
#include "sys/Syscall.h"
|
||||||
|
#include "thread/Scheduler.h"
|
||||||
|
#include <bits/waitpid.h>
|
||||||
|
|
||||||
|
Result<u64> sys_waitpid(Registers*, SyscallArgs args)
|
||||||
|
{
|
||||||
|
pid_t pid = (pid_t)args[0];
|
||||||
|
int* status_ptr = (int*)args[1];
|
||||||
|
int options = (int)args[2];
|
||||||
|
|
||||||
|
Thread* thread = TRY(Result<Thread*>::from_option(Scheduler::find_by_pid(pid), ESRCH));
|
||||||
|
|
||||||
|
while (thread->state != ThreadState::Exited)
|
||||||
|
{
|
||||||
|
if (options & WNOHANG) return err(EAGAIN);
|
||||||
|
kernel_sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
int status = (int)thread->status;
|
||||||
|
|
||||||
|
thread->state = ThreadState::Dying;
|
||||||
|
|
||||||
|
if (status_ptr)
|
||||||
|
if (!MemoryManager::copy_to_user_typed(status_ptr, &status)) return err(EFAULT);
|
||||||
|
|
||||||
|
return (u64)pid;
|
||||||
|
}
|
@ -253,6 +253,17 @@ namespace Scheduler
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Option<Thread*> find_by_pid(pid_t pid)
|
||||||
|
{
|
||||||
|
Option<Thread*> result;
|
||||||
|
|
||||||
|
g_threads.for_each([&](Thread* thread) {
|
||||||
|
if (thread->id == (u64)pid && thread->state != ThreadState::Dying) result = thread;
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernel_sleep(u64 ms)
|
void kernel_sleep(u64 ms)
|
||||||
|
@ -26,6 +26,8 @@ namespace Scheduler
|
|||||||
void invoke(Registers* regs);
|
void invoke(Registers* regs);
|
||||||
|
|
||||||
LinkedList<Thread> check_for_dying_threads();
|
LinkedList<Thread> check_for_dying_threads();
|
||||||
|
|
||||||
|
Option<Thread*> find_by_pid(pid_t pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void kernel_yield();
|
extern "C" void kernel_yield();
|
||||||
|
@ -15,6 +15,7 @@ set(SOURCES
|
|||||||
src/init.cpp
|
src/init.cpp
|
||||||
src/sys/stat.cpp
|
src/sys/stat.cpp
|
||||||
src/sys/mman.cpp
|
src/sys/mman.cpp
|
||||||
|
src/sys/wait.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(${LUNA_ARCH} STREQUAL "x86_64")
|
if(${LUNA_ARCH} STREQUAL "x86_64")
|
||||||
|
8
libc/include/bits/waitpid.h
Normal file
8
libc/include/bits/waitpid.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/* bits/waitpid.h: Constants for waitpid(). */
|
||||||
|
|
||||||
|
#ifndef _BITS_WAITPID_H
|
||||||
|
#define _BITS_WAITPID_H
|
||||||
|
|
||||||
|
#define WNOHANG 1
|
||||||
|
|
||||||
|
#endif
|
21
libc/include/sys/wait.h
Normal file
21
libc/include/sys/wait.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* sys/wait.h: Functions for waiting. */
|
||||||
|
|
||||||
|
#ifndef _SYS_WAIT_H
|
||||||
|
#define _SYS_WAIT_H
|
||||||
|
|
||||||
|
#include <bits/waitpid.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wait for a child process to exit. */
|
||||||
|
pid_t waitpid(pid_t pid, int* status, int options);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
13
libc/src/sys/wait.cpp
Normal file
13
libc/src/sys/wait.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <bits/errno-return.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
pid_t waitpid(pid_t pid, int* status, int options)
|
||||||
|
{
|
||||||
|
long rc = syscall(SYS_waitpid, pid, status, options);
|
||||||
|
__errno_return(rc, pid_t);
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#define enumerate_syscalls(_e) \
|
#define enumerate_syscalls(_e) \
|
||||||
_e(exit) _e(clock_gettime) _e(mmap) _e(munmap) _e(usleep) _e(open) _e(close) _e(read) _e(getpid) _e(write) \
|
_e(exit) _e(clock_gettime) _e(mmap) _e(munmap) _e(usleep) _e(open) _e(close) _e(read) _e(getpid) _e(write) \
|
||||||
_e(lseek) _e(mkdir) _e(exec) _e(mknod) _e(fork)
|
_e(lseek) _e(mkdir) _e(exec) _e(mknod) _e(fork) _e(waitpid)
|
||||||
|
|
||||||
enum Syscalls
|
enum Syscalls
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user