kernel+libc: Add the poll() syscall
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
df77fc8de8
commit
207d901de8
@ -42,6 +42,7 @@ set(SOURCES
|
|||||||
src/sys/resource.cpp
|
src/sys/resource.cpp
|
||||||
src/sys/signal.cpp
|
src/sys/signal.cpp
|
||||||
src/sys/socket.cpp
|
src/sys/socket.cpp
|
||||||
|
src/sys/poll.cpp
|
||||||
src/fs/VFS.cpp
|
src/fs/VFS.cpp
|
||||||
src/fs/Pipe.cpp
|
src/fs/Pipe.cpp
|
||||||
src/fs/Mount.cpp
|
src/fs/Mount.cpp
|
||||||
|
70
kernel/src/sys/poll.cpp
Normal file
70
kernel/src/sys/poll.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "fs/VFS.h"
|
||||||
|
#include "memory/MemoryManager.h"
|
||||||
|
#include "sys/Syscall.h"
|
||||||
|
#include "thread/Scheduler.h"
|
||||||
|
#include <bits/poll.h>
|
||||||
|
|
||||||
|
Result<u64> sys_poll(Registers* regs, SyscallArgs args)
|
||||||
|
{
|
||||||
|
struct pollfd* fds = (struct pollfd*)args[0];
|
||||||
|
nfds_t nfds = (nfds_t)args[1];
|
||||||
|
int timeout = (int)args[2];
|
||||||
|
|
||||||
|
struct pollfd* kfds = (struct pollfd*)TRY(malloc_impl(nfds * sizeof(pollfd)));
|
||||||
|
auto guard = make_scope_guard([kfds] { free_impl(kfds); });
|
||||||
|
|
||||||
|
if (!MemoryManager::copy_from_user(fds, kfds, nfds * sizeof(pollfd))) return err(EFAULT);
|
||||||
|
|
||||||
|
Vector<SharedPtr<VFS::Inode>> inodes;
|
||||||
|
auto* current = Scheduler::current();
|
||||||
|
|
||||||
|
for (nfds_t i = 0; i < nfds; i++)
|
||||||
|
{
|
||||||
|
int fd = kfds[i].fd;
|
||||||
|
auto maybe_inode = current->resolve_fd(fd);
|
||||||
|
if (maybe_inode.has_error())
|
||||||
|
{
|
||||||
|
kfds[i].revents |= POLLNVAL;
|
||||||
|
TRY(inodes.try_append({}));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TRY(inodes.try_append(maybe_inode.release_value()->description->inode));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool infinite = timeout < 0;
|
||||||
|
int fds_with_events;
|
||||||
|
|
||||||
|
do {
|
||||||
|
fds_with_events = 0;
|
||||||
|
for (nfds_t i = 0; i < nfds; i++)
|
||||||
|
{
|
||||||
|
auto& inode = inodes[i];
|
||||||
|
if (!inode) continue;
|
||||||
|
|
||||||
|
if (kfds[i].events & POLLIN && !inode->will_block_if_read())
|
||||||
|
{
|
||||||
|
fds_with_events++;
|
||||||
|
kfds[i].revents |= POLLIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fds_with_events && (timeout > 0 || infinite))
|
||||||
|
{
|
||||||
|
kernel_sleep(10);
|
||||||
|
timeout -= (int)current->sleep_ticks_left;
|
||||||
|
if (current->interrupted)
|
||||||
|
{
|
||||||
|
guard.deactivate();
|
||||||
|
free_impl(kfds);
|
||||||
|
if (current->will_invoke_signal_handler()) return err(EINTR);
|
||||||
|
current->process_pending_signals(regs);
|
||||||
|
return err(EINTR);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
MemoryManager::copy_to_user(fds, kfds, nfds * sizeof(pollfd));
|
||||||
|
|
||||||
|
return fds_with_events;
|
||||||
|
}
|
@ -3,7 +3,8 @@
|
|||||||
#ifndef _BITS_FIXED_SIZE_TYPES_H
|
#ifndef _BITS_FIXED_SIZE_TYPES_H
|
||||||
#define _BITS_FIXED_SIZE_TYPES_H
|
#define _BITS_FIXED_SIZE_TYPES_H
|
||||||
|
|
||||||
#if !defined(_SYS_TYPES_H) && !defined(_BITS_SETJMP_TYPES_H) && !defined(_BITS_MAKEDEV_H) && !defined(_BITS_TERMIOS_H)
|
#if !defined(_SYS_TYPES_H) && !defined(_BITS_SETJMP_TYPES_H) && !defined(_BITS_MAKEDEV_H) && \
|
||||||
|
!defined(_BITS_TERMIOS_H) && !defined(_BITS_POLL_H)
|
||||||
#error "Never include bits/fixed-size-types.h, use the standard <stdint.h> header instead."
|
#error "Never include bits/fixed-size-types.h, use the standard <stdint.h> header instead."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
21
libc/include/bits/poll.h
Normal file
21
libc/include/bits/poll.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* bits/poll.h: The pollfd data structure. */
|
||||||
|
|
||||||
|
#ifndef _BITS_POLL_H
|
||||||
|
#define _BITS_POLL_H
|
||||||
|
|
||||||
|
#include <bits/fixed-size-types.h>
|
||||||
|
|
||||||
|
#define POLLIN 0
|
||||||
|
#define POLLERR 1
|
||||||
|
#define POLLNVAL 2
|
||||||
|
|
||||||
|
typedef __u64_t nfds_t;
|
||||||
|
|
||||||
|
struct pollfd
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
short events;
|
||||||
|
short revents;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -7,7 +7,7 @@
|
|||||||
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
_e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) _e(mount) \
|
||||||
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \
|
_e(umount) _e(pstat) _e(getrusage) _e(symlinkat) _e(readlinkat) _e(umask) _e(linkat) _e(faccessat) \
|
||||||
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask) _e(setpgid) _e(isatty) \
|
_e(pivot_root) _e(sigreturn) _e(sigaction) _e(kill) _e(sigprocmask) _e(setpgid) _e(isatty) \
|
||||||
_e(getpgid) _e(socket) _e(bind) _e(connect) _e(listen) _e(accept)
|
_e(getpgid) _e(socket) _e(bind) _e(connect) _e(listen) _e(accept) _e(poll)
|
||||||
|
|
||||||
enum Syscalls
|
enum Syscalls
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user