int sys_poll_hdlr(uint32_t arg1, uint32_t arg2, uint32_t arg3) { struct pollfd *pfd = (struct pollfd *)arg1; int i, n = (int)arg2; uint32_t timeout = jiffies + arg3; int ret = 0; struct fnode *f; /* TODO: Set process wakeup timer */ while (jiffies < timeout) { for (i = 0; i < n; i++) { f = task_filedesc_get(pfd[i].fd); if (!f || !f->owner || !f->owner->ops.poll) { return -EOPNOTSUPP; } ret += f->owner->ops.poll(f, pfd[i].events, &pfd[i].revents); } if (ret > 0) return ret; task_suspend(); return SYS_CALL_AGAIN; } return 0; }
int sys_listen_hdlr(int sd, unsigned int backlog) { struct fnode *fno = task_filedesc_get(sd); if (fno && fno->owner && fno->owner->ops.listen) { return fno->owner->ops.listen(sd, backlog); } return -EINVAL; }
int sys_bind_hdlr(int sd, struct sockaddr_env *se) { struct fnode *fno = task_filedesc_get(sd); if (fno && fno->owner && fno->owner->ops.bind) { return fno->owner->ops.bind(sd, se->se_addr, se->se_len); } return -1; }
int sys_write_hdlr(int fd, void *buf, int len) { struct fnode *fno = task_filedesc_get(fd); if (fno && fno->owner && fno->owner->ops.write) { return fno->owner->ops.write(fd, buf, len); } return -1; }
int sys_read_hdlr(int fd, void *buf, int len) { struct fnode *fno = task_filedesc_get(fd); if (fno) { return fno->owner->ops.read(fd, buf, len); } return -1; }
int sys_getsockopt_hdlr(int sd, int level, int optname, void *optval, unsigned int *optlen) { struct fnode *fno = task_filedesc_get(sd); if (fno && fno->owner && fno->owner->ops.getsockopt) { return fno->owner->ops.getsockopt(sd, level, optname, optval, optlen); } return -1; }
int sys_sendto_hdlr(int sd, const void *buf, int len, int flags, struct sockaddr_env *se ) { struct fnode *fno = task_filedesc_get(sd); if (fno && fno->owner && fno->owner->ops.sendto) { return fno->owner->ops.sendto(sd, buf, len, flags, se->se_addr, se->se_len); } return -1; }
int sys_recvfrom_hdlr(int sd, void *buf, int len, int flags, struct sockaddr_env *se) { struct fnode *fno = task_filedesc_get(sd); if (fno && fno->owner && fno->owner->ops.recvfrom) { return fno->owner->ops.recvfrom(sd, buf, len, flags, se->se_addr, &(se->se_len)); } return -1; }
int sys_accept_hdlr(int sd, struct sockaddr_env *se) { struct fnode *fno = task_filedesc_get(sd); if (fno && fno->owner && fno->owner->ops.accept) { return fno->owner->ops.accept(sd, se->se_addr, &(se->se_len)); } return -1; }
int sys_shutdown_hdlr(int sd, int how) { struct fnode *fno = task_filedesc_get(sd); if (fno && fno->owner && fno->owner->ops.shutdown) { return fno->owner->ops.shutdown(sd, how); } return -EINVAL; }
int sys_getpeername_hdlr(int sd, struct sockaddr_env *se) { struct fnode *fno = task_filedesc_get(sd); if (task_ptr_valid(se)) return -EACCES; if (fno && fno->owner && fno->owner->ops.getpeername) { return fno->owner->ops.getpeername(sd, se->se_addr, &(se->se_len)); } return -EINVAL; }
int sys_setsockopt_hdlr(int sd, int level, int optname, void *optval, unsigned int optlen) { struct fnode *fno = task_filedesc_get(sd); if (task_ptr_valid(optval)) return -EACCES; if (fno && fno->owner && fno->owner->ops.setsockopt) { return fno->owner->ops.setsockopt(sd, level, optname, optval, optlen); } return -EINVAL; }
int sys_accept_hdlr(int sd, struct sockaddr_env *se) { struct fnode *fno = task_filedesc_get(sd); if (task_ptr_valid(se)) return -EACCES; if (fno && fno->owner && fno->owner->ops.accept) { if (se) return fno->owner->ops.accept(sd, se->se_addr, &(se->se_len)); else return fno->owner->ops.accept(sd, NULL, NULL); } return -EINVAL; }
int sys_sendto_hdlr(int sd, const void *buf, int len, int flags, struct sockaddr_env *se ) { struct fnode *fno = task_filedesc_get(sd); if (fno && fno->owner && fno->owner->ops.sendto) { if (se) { if (task_ptr_valid(buf)) return -EACCES; return fno->owner->ops.sendto(sd, buf, len, flags, se->se_addr, se->se_len); } else return fno->owner->ops.sendto(sd, buf, len, flags, NULL, 0); } return -EINVAL; }
int sys_read_hdlr(int fd, void *buf, int len) { struct fnode *fno = task_filedesc_get(fd); if (!task_fd_readable(fd)) return -EPERM; if (task_ptr_valid(buf)) return -EACCES; if (fno && fno->owner->ops.read) { return fno->owner->ops.read(fno, buf, len); } else if (fno->owner && fno->owner->ops.recvfrom) { return fno->owner->ops.recvfrom(fd, buf, len, 0, NULL, NULL); } return -ENOENT; }
int sys_recvfrom_hdlr(int sd, void *buf, int len, int flags, struct sockaddr_env *se) { struct fnode *fno = task_filedesc_get(sd); if (task_ptr_valid(buf)) return -EACCES; if (fno && fno->owner && fno->owner->ops.recvfrom) { if (se) { if (task_ptr_valid(se)) return -EACCES; return fno->owner->ops.recvfrom(sd, buf, len, flags, se->se_addr, &(se->se_len)); } else return fno->owner->ops.recvfrom(sd, buf, len, flags, NULL, NULL); } return -EINVAL; }
int sys_write_hdlr(int fd, void *buf, int len) { struct fnode *fno = task_filedesc_get(fd); if (!task_fd_writable(fd)) return -EPERM; if (task_ptr_valid(buf)) return -EACCES; if (!fno) return -ENOENT; if (fno->owner && fno->owner->ops.write) { return fno->owner->ops.write(fno, buf, len); } else if (fno->owner && fno->owner->ops.sendto) { return fno->owner->ops.sendto(fd, buf, len, 0, NULL, 0); } return -EOPNOTSUPP; }