sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
select.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#define LIBCGLUE_SYS_SOCKET_NO_ALIASES
12#define LIBCGLUE_ARPA_INET_NO_ALIASES
13#include <sys/socket.h>
14#include <ps2sdkapi.h>
15#include <errno.h>
16
17#include "ps2sdkapi.h"
18
19/* FIXME: This function currently cannot handle heterogeneous fds */
20int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
21{
22 int fd;
23 int ret;
24 int iop_max_fd = -1;
25 fd_set ready_readfds, ready_writefds, ready_exceptfds;
26 fd_set iop_readfds, iop_writefds, iop_exceptfds;
27
28 if (_libcglue_fdman_socket_ops == NULL || _libcglue_fdman_socket_ops->select == NULL)
29 {
30 errno = ENOSYS;
31 return -1;
32 }
33
34 FD_ZERO(&ready_readfds);
35 FD_ZERO(&ready_writefds);
36 FD_ZERO(&ready_exceptfds);
37
38 FD_ZERO(&iop_readfds);
39 FD_ZERO(&iop_writefds);
40 FD_ZERO(&iop_exceptfds);
41
42 for (fd = 0; fd < n; fd += 1)
43 {
44 int in_read = readfds && FD_ISSET(fd, readfds);
45 int in_write = writefds && FD_ISSET(fd, writefds);
46 int in_except = exceptfds && FD_ISSET(fd, exceptfds);
47 int iop_fd;
48
49 if (!in_read && !in_write && !in_except)
50 {
51 continue;
52 }
53
54 iop_fd = ps2sdk_get_iop_fd(fd);
55 if (iop_fd < 0)
56 {
57 errno = EBADF;
58 return -1;
59 }
60 if (iop_fd > iop_max_fd)
61 {
62 iop_max_fd = iop_fd;
63 }
64 if (in_read)
65 {
66 FD_SET(iop_fd, &iop_readfds);
67 }
68 if (in_write)
69 {
70 FD_SET(iop_fd, &iop_writefds);
71 }
72 if (in_except)
73 {
74 FD_SET(iop_fd, &iop_exceptfds);
75 }
76 }
77
78 /* Pass max(iop_fd)+1 to the underlying select, not the EE-side n.
79 * The bits in iop_*fds are at iop_fd positions; if iop_fd > n-1 the
80 * underlying select would iterate an empty range and block forever
81 * waiting for events on bits it isn't watching. */
82 ret = _libcglue_fdman_socket_ops->select(iop_max_fd + 1, &iop_readfds, &iop_writefds, &iop_exceptfds, timeout);
83
84 for (fd = 0; fd < n; fd += 1)
85 {
86 int in_read = readfds && FD_ISSET(fd, readfds);
87 int in_write = writefds && FD_ISSET(fd, writefds);
88 int in_except = exceptfds && FD_ISSET(fd, exceptfds);
89 int iop_fd;
90
91 if (!in_read && !in_write && !in_except)
92 {
93 continue;
94 }
95
96 iop_fd = ps2sdk_get_iop_fd(fd);
97 if (iop_fd < 0)
98 {
99 continue;
100 }
101 if (in_read && FD_ISSET(iop_fd, &iop_readfds))
102 {
103 FD_SET(fd, &ready_readfds);
104 }
105 if (in_write && FD_ISSET(iop_fd, &iop_writefds))
106 {
107 FD_SET(fd, &ready_writefds);
108 }
109 if (in_except && FD_ISSET(iop_fd, &iop_exceptfds))
110 {
111 FD_SET(fd, &ready_exceptfds);
112 }
113 }
114
115 if (readfds)
116 {
117 *readfds = ready_readfds;
118 }
119 if (writefds)
120 {
121 *writefds = ready_writefds;
122 }
123 if (exceptfds)
124 {
125 *exceptfds = ready_exceptfds;
126 }
127
128 return ret;
129}
#define ENOSYS
Definition errno.h:194
#define EBADF
Definition errno.h:46
Definition time.h:30