* SysPoll (fds, nfds, timeout) - Wait for file descriptors * fds - Array of pollfd structs * nfds - Number of pollfd structs * timeout - timeout period * * On Success - return number of file descriptors * On Failure - return -1 */
| 1503 | * On Failure - return -1 |
| 1504 | */ |
| 1505 | long SysPoll(regs64_t* r){ |
| 1506 | pollfd* fds = (pollfd*)SC_ARG0(r); |
| 1507 | unsigned nfds = SC_ARG1(r); |
| 1508 | long timeout = SC_ARG2(r); |
| 1509 | |
| 1510 | thread_t* thread = GetCPULocal()->currentThread; |
| 1511 | process_t* proc = Scheduler::GetCurrentProcess(); |
| 1512 | if(!Memory::CheckUsermodePointer(SC_ARG0(r), nfds * sizeof(pollfd), proc->addressSpace)){ |
| 1513 | Log::Warning("sys_poll: Invalid pointer to file descriptor array"); |
| 1514 | return -EFAULT; |
| 1515 | } |
| 1516 | |
| 1517 | fs_fd_t* files[nfds]; |
| 1518 | |
| 1519 | unsigned eventCount = 0; // Amount of fds with events |
| 1520 | for(unsigned i = 0; i < nfds; i++){ |
| 1521 | fds[i].revents = 0; |
| 1522 | if(fds[i].fd < 0) continue; |
| 1523 | |
| 1524 | if((uint64_t)fds[i].fd >= Scheduler::GetCurrentProcess()->fileDescriptors.get_length()){ |
| 1525 | Log::Warning("sys_poll: Invalid File Descriptor: %d", fds[i].fd); |
| 1526 | files[i] = 0; |
| 1527 | fds[i].revents |= POLLNVAL; |
| 1528 | eventCount++; |
| 1529 | continue; |
| 1530 | } |
| 1531 | |
| 1532 | fs_fd_t* handle = Scheduler::GetCurrentProcess()->fileDescriptors[fds[i].fd]; |
| 1533 | |
| 1534 | if(!handle || !handle->node){ |
| 1535 | Log::Warning("sys_poll: Invalid File Descriptor: %d", fds[i].fd); |
| 1536 | files[i] = 0; |
| 1537 | fds[i].revents |= POLLNVAL; |
| 1538 | eventCount++; |
| 1539 | continue; |
| 1540 | } |
| 1541 | |
| 1542 | files[i] = handle; |
| 1543 | |
| 1544 | bool hasEvent = 0; |
| 1545 | |
| 1546 | if((files[i]->node->flags & FS_NODE_TYPE) == FS_NODE_SOCKET){ |
| 1547 | if(!((Socket*)files[i]->node)->IsConnected() && !((Socket*)files[i]->node)->IsListening()){ |
| 1548 | fds[i].revents |= POLLHUP; |
| 1549 | hasEvent = true; |
| 1550 | } |
| 1551 | |
| 1552 | if(((Socket*)files[i]->node)->PendingConnections() && (fds[i].events & POLLIN)){ |
| 1553 | fds[i].revents |= POLLIN; |
| 1554 | hasEvent = true; |
| 1555 | } |
| 1556 | } |
| 1557 | |
| 1558 | if(files[i]->node->CanRead() && (fds[i].events & POLLIN)) { // If readable and the caller requested POLLIN |
| 1559 | fds[i].revents |= POLLIN; |
| 1560 | hasEvent = true; |
| 1561 | } |
| 1562 |
nothing calls this directly
no test coverage detected