int ksocket_recvfrom(int sid, void* buf, size_t len, int flags,
struct sockaddr_in* src);
int ksocket_close(int sid);
+int ksocket_poll(int sid, int events);
void ksocket_init(void);
#endif
#include "socket.h"
+#include "fs.h"
#include "net.h"
#include "errno.h"
#include "process.h"
s->in_use = 0;
return 0;
}
+
+int ksocket_poll(int sid, int events) {
+ if (sid < 0 || sid >= KSOCKET_MAX) return VFS_POLL_ERR;
+ struct ksocket* s = &sockets[sid];
+ if (!s->in_use) return VFS_POLL_ERR | VFS_POLL_HUP;
+
+ int revents = 0;
+
+ if (s->error) revents |= VFS_POLL_ERR;
+
+ if (s->state == KSOCK_PEER_CLOSED || s->state == KSOCK_CLOSED) {
+ revents |= VFS_POLL_HUP;
+ /* Peer-closed socket is still readable (returns EOF / remaining data) */
+ if (events & VFS_POLL_IN) revents |= VFS_POLL_IN;
+ return revents;
+ }
+
+ if (events & VFS_POLL_IN) {
+ if (s->state == KSOCK_LISTENING) {
+ if (s->aq_count > 0) revents |= VFS_POLL_IN;
+ } else {
+ if (s->rx_count > 0) revents |= VFS_POLL_IN;
+ }
+ }
+
+ if (events & VFS_POLL_OUT) {
+ if (s->state == KSOCK_CONNECTED) revents |= VFS_POLL_OUT;
+ }
+
+ return revents;
+}
kfree(node);
}
+static int sock_node_poll(fs_node_t* node, int events) {
+ if (!node) return VFS_POLL_ERR;
+ return ksocket_poll((int)node->inode, events);
+}
+
static const struct file_operations sock_fops = {
.read = sock_node_read,
.write = sock_node_write,
.close = sock_node_close,
+ .poll = sock_node_poll,
};
static fs_node_t* sock_node_create(int sid) {