MCPcopy Create free account
hub / github.com/LemonOSProject/LemonOS / SysSelect

Function SysSelect

Kernel/src/arch/x86_64/syscalls.cpp:2090–2216  ·  view source on GitHub ↗

//////////////////////// \brief SysSelect(nfds, readfds, writefds, exceptfds, timeout) Set a file handle's mode/status flags \param nfds (int) number of file descriptors \param readfds (fd_set) check for readable fds \param writefds (fd_set) check for writable fds \param exceptfds (fd_set) check for exceptions on fds \param timeout (timespec) timeout period \return number of events on success, n

Source from the content-addressed store, hash-verified

2088/// \return number of events on success, negative error code on failure
2089/////////////////////////////
2090long SysSelect(regs64_t* r){
2091 process_t* currentProcess = Scheduler::GetCurrentProcess();
2092
2093 int nfds = static_cast<int>(SC_ARG0(r));
2094 fd_set_t* readFdsMask = reinterpret_cast<fd_set_t*>(SC_ARG1(r));
2095 fd_set_t* writeFdsMask = reinterpret_cast<fd_set_t*>(SC_ARG2(r));
2096 fd_set_t* exceptFdsMask = reinterpret_cast<fd_set_t*>(SC_ARG3(r));
2097 timespec_t* timeout = reinterpret_cast<timespec_t*>(SC_ARG4(r));
2098
2099 if(!((!readFdsMask || Memory::CheckUsermodePointer(SC_ARG1(r), sizeof(fd_set_t), currentProcess->addressSpace))
2100 && (!writeFdsMask || Memory::CheckUsermodePointer(SC_ARG2(r), sizeof(fd_set_t), currentProcess->addressSpace))
2101 && (!exceptFdsMask || Memory::CheckUsermodePointer(SC_ARG3(r), sizeof(fd_set_t), currentProcess->addressSpace))
2102 && Memory::CheckUsermodePointer(SC_ARG4(r), sizeof(timespec_t), currentProcess->addressSpace))){
2103 return -EFAULT; // Only return EFAULT if read/write/exceptfds is not null
2104 }
2105
2106 List<Pair<fs_fd_t*, int>> readfds;
2107 List<Pair<fs_fd_t*, int>> writefds;
2108 List<Pair<fs_fd_t*, int>> exceptfds;
2109
2110 auto getHandleSafe = [&](int fd) -> fs_fd_t* {
2111 if(static_cast<unsigned>(fd) > currentProcess->fileDescriptors.get_length()){
2112 return nullptr;
2113 }
2114 return currentProcess->fileDescriptors[fd]; // If fd is null then this will return null as if out of range
2115 };
2116
2117 for(int i = 0; i < 128 && i * 8 < nfds; i++){
2118 char read = 0, write = 0, except = 0;
2119 if(readFdsMask) {
2120 read = readFdsMask->fds_bits[i];
2121 readFdsMask->fds_bits[i] = 0; // With select the fds are cleared to 0 unless they are ready
2122 }
2123
2124 if(writeFdsMask){
2125 write = writeFdsMask->fds_bits[i];
2126 writeFdsMask->fds_bits[i] = 0;
2127 }
2128
2129 if(exceptFdsMask){
2130 except = exceptFdsMask->fds_bits[i];
2131 exceptFdsMask->fds_bits[i] = 0;
2132 }
2133
2134 for(int j = 0; j < 8 && (i * 8 + j) < nfds; j++){
2135 if((read >> j) & 0x1){
2136 fs_fd_t* h = getHandleSafe(i * 8 + j);
2137 if(!h){
2138 return -EBADF;
2139 }
2140
2141 readfds.add_back(Pair<fs_fd_t*, int>(h, i * 8 + j));
2142 }
2143
2144 if((write >> j) & 0x1){
2145 fs_fd_t* h = getHandleSafe(i * 8 + j);
2146 if(!h){
2147 return -EBADF;

Callers

nothing calls this directly

Calls 9

GetCurrentProcessFunction · 0.85
CheckUsermodePointerFunction · 0.85
FD_SETFunction · 0.85
GetSystemUptimeStructFunction · 0.85
CanWriteMethod · 0.80
YieldFunction · 0.70
get_lengthMethod · 0.45
add_backMethod · 0.45
CanReadMethod · 0.45

Tested by

no test coverage detected