CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/File/FileDescriptor.cpp
Views: 1401
#include "ppsspp_config.h"12#include <errno.h>3#include <cmath>4#include <cstdio>5#ifndef _WIN326#include <arpa/inet.h>7#include <netinet/in.h>8#include <sys/socket.h>9#include <sys/types.h>10#include <sys/select.h>11#include <unistd.h>12#else13#include <io.h>14#include <winsock2.h>15#include <ws2tcpip.h>16#endif17#include <fcntl.h>1819#include "Common/CommonTypes.h"20#include "Common/Data/Encoding/Utf8.h"21#include "Common/File/FileDescriptor.h"22#include "Common/Log.h"2324namespace fd_util {2526// Slow as hell and should only be used for prototyping.27// Reads from a socket, up to an '\n'. This means that if the line ends28// with '\r', the '\r' will be returned.29size_t ReadLine(int fd, char *vptr, size_t buf_size) {30char *buffer = vptr;31size_t n;32for (n = 1; n < buf_size; n++) {33char c;34size_t rc;35if ((rc = read(fd, &c, 1)) == 1) {36*buffer++ = c;37if (c == '\n')38break;39} else if (rc == 0) {40if (n == 1)41return 0;42else43break;44} else {45if (errno == EINTR)46continue;47_assert_msg_(false, "Error in Readline()");48}49}5051*buffer = 0;52return n;53}5455// Misnamed, it just writes raw data in a retry loop.56size_t WriteLine(int fd, const char *vptr, size_t n) {57const char *buffer = vptr;58size_t nleft = n;5960while (nleft > 0) {61int nwritten;62if ((nwritten = (int)write(fd, buffer, (unsigned int)nleft)) <= 0) {63if (errno == EINTR)64nwritten = 0;65else66_assert_msg_(false, "Error in Writeline()");67}68nleft -= nwritten;69buffer += nwritten;70}7172return n;73}7475size_t WriteLine(int fd, const char *buffer) {76return WriteLine(fd, buffer, strlen(buffer));77}7879size_t Write(int fd, const std::string &str) {80return WriteLine(fd, str.c_str(), str.size());81}8283bool WaitUntilReady(int fd, double timeout, bool for_write) {84struct timeval tv;85tv.tv_sec = (long)floor(timeout);86tv.tv_usec = (long)((timeout - floor(timeout)) * 1000000.0);8788fd_set fds;89FD_ZERO(&fds);90FD_SET(fd, &fds);91// First argument to select is the highest socket in the set + 1.92int rval;93if (for_write) {94rval = select(fd + 1, nullptr, &fds, nullptr, &tv);95} else {96rval = select(fd + 1, &fds, nullptr, nullptr, &tv);97}9899if (rval < 0) {100// Error calling select.101return false;102} else if (rval == 0) {103// Timeout.104return false;105} else {106// Socket is ready.107return true;108}109}110111void SetNonBlocking(int sock, bool non_blocking) {112#ifndef _WIN32113int opts = fcntl(sock, F_GETFL);114if (opts < 0) {115perror("fcntl(F_GETFL)");116ERROR_LOG(Log::IO, "Error getting socket status while changing nonblocking status");117}118if (non_blocking) {119opts = (opts | O_NONBLOCK);120} else {121opts = (opts & ~O_NONBLOCK);122}123124if (fcntl(sock, F_SETFL, opts) < 0) {125perror("fcntl(F_SETFL)");126ERROR_LOG(Log::IO, "Error setting socket nonblocking status");127}128#else129u_long val = non_blocking ? 1 : 0;130if (ioctlsocket(sock, FIONBIO, &val) != 0) {131ERROR_LOG(Log::IO, "Error setting socket nonblocking status");132}133#endif134}135136std::string GetLocalIP(int sock) {137union {138struct sockaddr sa;139struct sockaddr_in ipv4;140#if !PPSSPP_PLATFORM(SWITCH)141struct sockaddr_in6 ipv6;142#endif143} server_addr;144memset(&server_addr, 0, sizeof(server_addr));145socklen_t len = sizeof(server_addr);146if (getsockname(sock, (struct sockaddr *)&server_addr, &len) == 0) {147char temp[64]{};148149// We clear the port below for WSAAddressToStringA.150void *addr = nullptr;151#if !PPSSPP_PLATFORM(SWITCH)152if (server_addr.sa.sa_family == AF_INET6) {153server_addr.ipv6.sin6_port = 0;154addr = &server_addr.ipv6.sin6_addr;155}156#endif157if (addr == nullptr) {158server_addr.ipv4.sin_port = 0;159addr = &server_addr.ipv4.sin_addr;160}161#ifdef _WIN32162wchar_t wtemp[sizeof(temp)];163DWORD len = (DWORD)sizeof(temp);164// Windows XP doesn't support inet_ntop.165if (WSAAddressToStringW((struct sockaddr *)&server_addr, sizeof(server_addr), nullptr, wtemp, &len) == 0) {166return ConvertWStringToUTF8(wtemp);167}168#else169const char *result = inet_ntop(server_addr.sa.sa_family, addr, temp, sizeof(temp));170if (result) {171return result;172}173#endif174}175return "";176}177178} // fd_util179180181