mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
syscalls: poll
This commit is contained in:
@@ -29,7 +29,8 @@ extern syscall_pipe2
|
||||
extern syscall_mkdir
|
||||
extern syscall_munmap
|
||||
extern syscall_umask
|
||||
func_count equ 28
|
||||
extern syscall_poll
|
||||
func_count equ 29
|
||||
|
||||
|
||||
func_table:
|
||||
@@ -61,6 +62,7 @@ func_table:
|
||||
dq syscall_mkdir
|
||||
dq syscall_munmap
|
||||
dq syscall_umask
|
||||
dq syscall_poll
|
||||
section .text
|
||||
global asm_syscall_entry
|
||||
|
||||
|
||||
@@ -100,6 +100,19 @@ int vfs_isatty(vnode_t* node){
|
||||
|
||||
}
|
||||
|
||||
int vfs_poll(vnode_t* node, pollfd* fd){
|
||||
|
||||
switch(GETTYPE(node->st.st_mode)){
|
||||
case TYPE_CHARDEV:
|
||||
case TYPE_BLOCKDEV:
|
||||
return devman_poll(node->st.st_rdev, fd);
|
||||
case TYPE_FIFO:
|
||||
default:
|
||||
_panic("Unsupported poll", NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int vfs_ioctl(vnode_t* node, unsigned long request, void* arg, int* result){
|
||||
|
||||
if(GETTYPE(node->st.st_mode) != TYPE_CHARDEV)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define _DEVMAN_H_INCLUDE
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <poll.h>
|
||||
|
||||
#define MAJOR_CONSOLE 1
|
||||
#define MAJOR_ZERO 2
|
||||
@@ -16,6 +17,7 @@ typedef struct{
|
||||
int (*isatty)(int minor);
|
||||
int (*isseekable)(int minor, size_t* seekmax);
|
||||
int (*ioctl)(int minor, unsigned long request, void* arg, int* result);
|
||||
int (*poll)(int minor, pollfd* fd);
|
||||
} devcalls;
|
||||
|
||||
int devman_read(int *error, int dev, void* buff, size_t count, size_t offset);
|
||||
@@ -24,6 +26,7 @@ int devman_newdevice(char* name, int type, int major, int minor, devcalls* calls
|
||||
int devman_isatty(int dev);
|
||||
int devman_isseekable(int dev, size_t* seekmax);
|
||||
int devman_ioctl(int dev, unsigned long request, void* arg, int* result);
|
||||
int devman_poll(int dev, pollfd* fd);
|
||||
void devman_init();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <hashtable.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <poll.h>
|
||||
|
||||
struct _vnode_t;
|
||||
struct _fscalls_t;
|
||||
@@ -74,6 +75,7 @@ int vfs_read(int* error, vnode_t* node, void* buff, size_t count, size_t offset)
|
||||
int vfs_isatty(vnode_t* node);
|
||||
int vfs_getdirent(dirnode_t* node, dent_t* buff, size_t count, uintmax_t offset, size_t* readcount);
|
||||
int vfs_ioctl(vnode_t* node, unsigned long request, void* arg, int* result);
|
||||
int vfs_poll(vnode_t* node, pollfd* fd);
|
||||
|
||||
void vfs_init();
|
||||
dirnode_t* vfs_root();
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef _POLL_H_INCLUDE
|
||||
#define _POLL_H_INCLUDE
|
||||
|
||||
typedef struct{
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
} pollfd;
|
||||
|
||||
#define POLLIN 0x0001
|
||||
#define POLLPRI 0x0002
|
||||
#define POLLOUT 0x0004
|
||||
#define POLLERR 0x0008
|
||||
#define POLLHUP 0x0010
|
||||
#define POLLNVAL 0x0020
|
||||
#define POLLRDNORM 0x0040
|
||||
#define POLLRDBAND 0x0080
|
||||
#define POLLWRNORM 0x0100
|
||||
#define POLLRDHUP 0x2000
|
||||
|
||||
#endif
|
||||
@@ -75,6 +75,16 @@ int devman_ioctl(int dev, unsigned long request, void* arg, int* result){
|
||||
return majorcalls[major(dev)]->ioctl(minor(dev), request, arg, result);
|
||||
}
|
||||
|
||||
int devman_poll(int dev, pollfd* fd){
|
||||
if(major(dev) > highestmajor)
|
||||
return ENOTTY;
|
||||
|
||||
if(!majorcalls[major(dev)]->poll)
|
||||
return ENOTTY;
|
||||
|
||||
return majorcalls[major(dev)]->poll(minor(dev), fd);
|
||||
}
|
||||
|
||||
void devman_init(){
|
||||
|
||||
devfs_init();
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
#include <kernel/syscalls.h>
|
||||
#include <kernel/alloc.h>
|
||||
#include <kernel/vmm.h>
|
||||
#include <arch/cls.h>
|
||||
#include <poll.h>
|
||||
#include <kernel/sched.h>
|
||||
|
||||
#define MAXNFDS 4096
|
||||
|
||||
syscallret syscall_poll(pollfd *fds, size_t nfds, int timeoutms){
|
||||
syscallret retv;
|
||||
retv.ret = -1;
|
||||
|
||||
if(fds > USER_SPACE_END){
|
||||
retv.errno = EFAULT;
|
||||
return retv;
|
||||
}
|
||||
|
||||
if(nfds > MAXNFDS){
|
||||
retv.errno = EINVAL;
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
// create the internal list
|
||||
|
||||
pollfd* ilist = alloc(1);
|
||||
|
||||
if(!ilist){
|
||||
retv.errno = ENOMEM;
|
||||
return retv;
|
||||
}
|
||||
|
||||
for(size_t fd = 0; fd < nfds; ++fd){
|
||||
|
||||
void* tmp = realloc(ilist,(fd+1)*sizeof(pollfd));
|
||||
if(!tmp){
|
||||
retv.errno = ENOMEM;
|
||||
goto ret;
|
||||
}
|
||||
|
||||
ilist[fd].fd = fds[fd].fd;
|
||||
ilist[fd].events = fds[fd].events;
|
||||
}
|
||||
|
||||
// check for events and stuff
|
||||
|
||||
bool eventhappened = false;
|
||||
|
||||
fdtable_t* fdtable = &arch_getcls()->thread->proc->fdtable;
|
||||
|
||||
while(!eventhappened){
|
||||
for(uintmax_t i = 0; i < nfds; ++i){
|
||||
if(ilist[i].fd < 0 || ilist[i].events == 0)
|
||||
continue;
|
||||
|
||||
// open fd
|
||||
|
||||
fd_t* fd;
|
||||
|
||||
int err = fd_access(fdtable, &fd, ilist[i].fd);
|
||||
|
||||
if(err){
|
||||
ilist[i].revents = POLLNVAL;
|
||||
eventhappened = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// poll
|
||||
|
||||
if(fd->node){
|
||||
if(vfs_poll(fd->node, &ilist[i]))
|
||||
ilist[i].revents = POLLERR;
|
||||
}
|
||||
|
||||
if(ilist[i].revents)
|
||||
eventhappened = true;
|
||||
|
||||
// cleanup
|
||||
|
||||
fd_release(fd);
|
||||
|
||||
}
|
||||
|
||||
// TODO check for signal or timeout
|
||||
|
||||
|
||||
}
|
||||
|
||||
// copy results into each fd
|
||||
|
||||
size_t eventcount = 0;
|
||||
|
||||
for(uintmax_t i = 0; i < nfds; ++i){
|
||||
|
||||
if(ilist[i].fd < 0 || ilist[i].revents == 0)
|
||||
continue;
|
||||
|
||||
fds[i].revents = ilist[i].revents;
|
||||
|
||||
++eventcount;
|
||||
|
||||
}
|
||||
|
||||
retv.errno = 0;
|
||||
retv.ret = eventcount;
|
||||
|
||||
ret:
|
||||
|
||||
if(ilist)
|
||||
free(ilist);
|
||||
|
||||
return retv;
|
||||
}
|
||||
+31
-6
@@ -153,10 +153,9 @@ __attribute__((noreturn)) static void console_thread(){
|
||||
}
|
||||
}
|
||||
else{ // not canon
|
||||
|
||||
if(tty.c_lflag & ECHO)
|
||||
if(tty.c_lflag & ECHO){
|
||||
console_write(strbufptr, strbuflen);
|
||||
|
||||
}
|
||||
arch_interrupt_disable();
|
||||
|
||||
ringbuffer_write(&input, strbufptr, strbuflen);
|
||||
@@ -204,7 +203,6 @@ static int read(int *error, int dev, void* buff, size_t count, size_t offset){
|
||||
|
||||
static int write(int *error, int dev, void* buff, size_t count, size_t offset){
|
||||
*error = 0;
|
||||
|
||||
console_write(buff, count);
|
||||
|
||||
return count;
|
||||
@@ -226,6 +224,8 @@ typedef struct{
|
||||
unsigned short ws_ypixel;
|
||||
} winsize;
|
||||
|
||||
#include <arch/cls.h>
|
||||
|
||||
static int ioctl(int minor, unsigned long req, void* arg){
|
||||
switch(req){
|
||||
case TIOCGWINSZ:
|
||||
@@ -248,10 +248,29 @@ static int ioctl(int minor, unsigned long req, void* arg){
|
||||
|
||||
}
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
static int poll(int minor, pollfd* fd){
|
||||
|
||||
if((fd->events & POLLIN) && input.write != input.read)
|
||||
fd->revents |= POLLIN;
|
||||
|
||||
if((fd->events & POLLOUT) && outputlock == 0)
|
||||
fd->revents |= POLLOUT;
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
devcalls calls = {
|
||||
read, write, isatty, isseekable, ioctl
|
||||
read, write, isatty, isseekable, ioctl, poll
|
||||
};
|
||||
|
||||
static void callback(struct limine_terminal *terminal, uint64_t type, uint64_t arg1, uint64_t arg2, uint64_t arg3){
|
||||
asm("cli;hlt");
|
||||
}
|
||||
|
||||
void consoledev_init(){
|
||||
|
||||
if(devman_newdevice("console", TYPE_CHARDEV, MAJOR_CONSOLE, 0, &calls))
|
||||
@@ -265,7 +284,13 @@ void consoledev_init(){
|
||||
if(!thread)
|
||||
_panic("Failed to initialise console thread", 0);
|
||||
|
||||
tty.c_lflag = ECHO | ICANON;
|
||||
tty.c_lflag = ECHO | ICANON | ISIG;
|
||||
tty.c_cc[VINTR] = 0x03;
|
||||
tty.ibaud = 38400;
|
||||
tty.obaud = 38400;
|
||||
|
||||
tty.c_cc[VMIN] = 1;
|
||||
|
||||
liminetty_setcallback(0, callback);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user