From 75bab5a4b9b643a423daf3f1b7c94de3aa0c18a5 Mon Sep 17 00:00:00 2001 From: Andrey Bychkov Date: Tue, 11 Aug 2026 18:19:24 +0300 Subject: [PATCH] feat: add WebAssembly (Emscripten) build support - Platform detection: EMSCRIPTEN/WASM macros in piplatform.h - CMake: PIP_WASM option, auto-detect, STATIC lib, pthread flags, disable incompatible modules (console, usb, fftw, opencl, lua, http_server, http_client, mqtt_client) - Macros: environ, SHUT_RDWR, HAS_LOCALE off, PIP_MIN_MSLEEP=10ms - System stubs: process, signals, library, systeminfo, hidevice - IO stubs: serial, ethernet, can, sharedmemory - Thread: gettid() fallback via pthread_self() - Core: locale/init adjustments, console.log routing via EM_ASM - Fix: toDecimal precision loss, unreachable code in createPipe --- CMakeLists.txt | 7 +- libs/main/core/pibase_macros.h | 16 +- libs/main/core/picout.cpp | 55 +++--- libs/main/core/piincludes.cpp | 4 +- libs/main/core/piincludes_p.h | 2 +- libs/main/core/piinit.cpp | 20 +-- libs/main/io_devices/piethernet.cpp | 213 ++++++++++++------------ libs/main/io_devices/piserial.cpp | 125 ++++++++------ libs/main/io_devices/pisharedmemory.cpp | 22 +-- libs/main/math/pimathbase.h | 3 +- libs/main/piplatform.h | 11 +- libs/main/system/pihidevice.cpp | 104 +++++++++--- libs/main/system/pilibrary.cpp | 148 ++++++++++++++-- libs/main/system/piprocess.cpp | 113 +++++++++---- libs/main/system/pisignals.cpp | 25 +-- libs/main/system/pisysteminfo.cpp | 19 ++- libs/main/thread/pithread.cpp | 4 +- 17 files changed, 564 insertions(+), 327 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3814bb24..703acb45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,6 @@ option(PIP_FFTW_F "Support fftw module for float" ON) option(PIP_FFTW_L "Support fftw module for long double" ON) option(PIP_FFTW_Q "Support fftw module for quad double" OFF) option(PIP_MANUAL_TEST "Build dev test (main.cpp)" OFF) -option(PIP_WASM "Build for WebAssembly (Emscripten)" OFF) set(PIP_UTILS 1) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_STANDARD 11) @@ -230,10 +229,8 @@ if(PIP_FREERTOS) set(LOCAL ON) endif() -if(NOT PIP_WASM) - if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten" OR DEFINED CMAKE_Emscripten) - set(PIP_WASM ON) - endif() +if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten" OR DEFINED CMAKE_Emscripten) + set(PIP_WASM ON) endif() if(PIP_WASM) diff --git a/libs/main/core/pibase_macros.h b/libs/main/core/pibase_macros.h index ae1d23da..7fb664a1 100644 --- a/libs/main/core/pibase_macros.h +++ b/libs/main/core/pibase_macros.h @@ -195,7 +195,7 @@ extern long long __pi_perf_freq; # ifndef SHUT_RDWR # define SHUT_RDWR 2 # endif -#endif +#endif //EMSCRIPTEN #ifndef DOXYGEN @@ -210,13 +210,9 @@ extern long long __pi_perf_freq; typedef long time_t; # endif -# ifdef LINUX +# if defined(LINUX) || defined(EMSCRIPTEN) # define environ __environ -# endif - -# ifdef EMSCRIPTEN -# define environ __environ -# endif +# endif //EMSCRIPTEN # ifdef FREE_BSD extern char ** environ; @@ -248,7 +244,7 @@ extern char ** environ; # pragma GCC diagnostic warning "-Wdeprecated-declarations" # if defined(LINUX) && !defined(EMSCRIPTEN) # define HAS_LOCALE -# endif +# endif //EMSCRIPTEN # ifdef MAC_OS # pragma GCC diagnostic ignored "-Wundefined-bool-conversion" # pragma GCC diagnostic ignored "-Wc++11-extensions" @@ -405,9 +401,9 @@ typedef long long ssize_t; #ifndef PIP_MIN_MSLEEP # if defined(MICRO_PIP) || defined(EMSCRIPTEN) # define PIP_MIN_MSLEEP 10. -# else +# else //EMSCRIPTEN # define PIP_MIN_MSLEEP 1. -# endif +# endif //EMSCRIPTEN #endif diff --git a/libs/main/core/picout.cpp b/libs/main/core/picout.cpp index b78536f8..971160ab 100644 --- a/libs/main/core/picout.cpp +++ b/libs/main/core/picout.cpp @@ -236,9 +236,11 @@ PICout & PICout::operator<<(PICoutAction v) { SetConsoleCursorPosition(__Private__::hOut, coord); printf(" "); SetConsoleCursorPosition(__Private__::hOut, coord); -#elif !defined(EMSCRIPTEN) +#else //EMSCRIPTEN +# ifndef EMSCRIPTEN printf("\e[1D \e[1D"); -#endif +# endif //EMSCRIPTEN +#endif //EMSCRIPTEN } break; case PICoutManipulators::ShowCursor: @@ -247,9 +249,11 @@ PICout & PICout::operator<<(PICoutAction v) { GetConsoleCursorInfo(__Private__::hOut, &curinfo); curinfo.bVisible = true; SetConsoleCursorInfo(__Private__::hOut, &curinfo); -#elif !defined(EMSCRIPTEN) +#else //EMSCRIPTEN +# ifndef EMSCRIPTEN printf("\e[?25h"); -#endif +# endif //EMSCRIPTEN +#endif //EMSCRIPTEN } break; case PICoutManipulators::HideCursor: @@ -258,9 +262,11 @@ PICout & PICout::operator<<(PICoutAction v) { GetConsoleCursorInfo(__Private__::hOut, &curinfo); curinfo.bVisible = false; SetConsoleCursorInfo(__Private__::hOut, &curinfo); -#elif !defined(EMSCRIPTEN) +#else //EMSCRIPTEN +# ifndef EMSCRIPTEN printf("\e[?25l"); -#endif +# endif //EMSCRIPTEN +#endif //EMSCRIPTEN } break; case PICoutManipulators::ClearLine: @@ -279,18 +285,22 @@ PICout & PICout::operator<<(PICoutAction v) { delete[] line; } SetConsoleCursorPosition(__Private__::hOut, coord); -#elif !defined(EMSCRIPTEN) +#else //EMSCRIPTEN +# ifndef EMSCRIPTEN printf("\e[0G\e[K"); -#endif +# endif //EMSCRIPTEN +#endif //EMSCRIPTEN } break; case PICoutManipulators::ClearScreen: if (isOutputDeviceActive(Console)) { #ifdef WINDOWS /// TODO : wondows ClearScreen !!! -#elif !defined(EMSCRIPTEN) +#else //EMSCRIPTEN +# ifndef EMSCRIPTEN printf("\e[H\e[J"); -#endif +# endif //EMSCRIPTEN +#endif //EMSCRIPTEN } break; case PICoutManipulators::SaveContol: saveControls(); break; @@ -378,14 +388,16 @@ void PICout::stdoutPIString(const PIString & str, PICoutStdStream s) { }, buf, (int)s); -#elif defined(HAS_LOCALE) +#else //EMSCRIPTEN +# ifdef HAS_LOCALE std::wstring_convert, char16_t> utf8conv; getStdStream(s) << utf8conv.to_bytes((char16_t *)&(const_cast(str).front()), (char16_t *)&(const_cast(str).front()) + str.size()); -#else +# else // HAS_LOCALE for (PIChar c: str) getStdWStream(s).put(c.toWChar()); -#endif +# endif // HAS_LOCALE +#endif //EMSCRIPTEN } @@ -410,9 +422,9 @@ PICout & PICout::write(const char * str, int len) { 0, (int)stream_); } -#else +#else //EMSCRIPTEN if (isOutputDeviceActive(Console)) getStdStream(stream_).write(str, len); -#endif +#endif //EMSCRIPTEN if (isOutputDeviceActive(Buffer)) PICout::__string__().append(PIString(str, len)); } return *this; @@ -437,9 +449,9 @@ void PICout::writeChar(char c) { } else { #ifdef EMSCRIPTEN if (isOutputDeviceActive(Console)) fputc(c, stream_ == PICoutStdStream::StdErr ? stderr : stdout); -#else +#else //EMSCRIPTEN if (isOutputDeviceActive(Console)) getStdStream(stream_) << c; -#endif +#endif //EMSCRIPTEN if (isOutputDeviceActive(Buffer)) PICout::__string__().append(c); } } @@ -682,9 +694,9 @@ void PICout::applyFormat(PICoutFormat f) { if (buffer_ || !isOutputDeviceActive(Console)) return; #ifdef EMSCRIPTEN return; -#endif +#else //EMSCRIPTEN format_changed_ = true; -#ifdef WINDOWS +# ifdef WINDOWS static int mask_fore = ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); static int mask_back = ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); switch (f) { @@ -714,7 +726,7 @@ void PICout::applyFormat(PICoutFormat f) { default: break; } SetConsoleTextAttribute(__Private__::hOut, win_attr_); -#else +# else switch (f) { case Bin: case Oct: @@ -744,7 +756,8 @@ void PICout::applyFormat(PICoutFormat f) { case PICoutManipulators::Default: printf("\e[0m"); break; default: break; } -#endif +# endif +#endif //EMSCRIPTEN } diff --git a/libs/main/core/piincludes.cpp b/libs/main/core/piincludes.cpp index d1a52130..9e7f522c 100644 --- a/libs/main/core/piincludes.cpp +++ b/libs/main/core/piincludes.cpp @@ -40,9 +40,9 @@ double piMountInfoRefreshIntervalMs = 10000.; lconv * currentLocale = #if defined(ANDROID) || defined(EMSCRIPTEN) 0; -#else +#else //EMSCRIPTEN std::localeconv(); -#endif +#endif //EMSCRIPTEN #ifdef MAC_OS clock_serv_t __pi_mac_clock; diff --git a/libs/main/core/piincludes_p.h b/libs/main/core/piincludes_p.h index d8087b8f..7f2edf10 100644 --- a/libs/main/core/piincludes_p.h +++ b/libs/main/core/piincludes_p.h @@ -58,7 +58,7 @@ typedef LONG(NTAPI * PINtSetTimerResolution)(ULONG, BOOLEAN, PULONG); #ifdef EMSCRIPTEN # include # include -#endif +#endif //EMSCRIPTEN // clang-format on diff --git a/libs/main/core/piinit.cpp b/libs/main/core/piinit.cpp index e4964bef..35e3501a 100644 --- a/libs/main/core/piinit.cpp +++ b/libs/main/core/piinit.cpp @@ -50,7 +50,7 @@ void __PISetTimerResolution() { # include # ifndef EMSCRIPTEN # include -# endif +# endif //EMSCRIPTEN # include # ifdef BLACKBERRY # include @@ -116,8 +116,8 @@ PIInit::PIInit() { break; } } -# endif -# else // WINDOWS +# endif //EMSCRIPTEN +# else // WINDOWS // OS version DWORD dwVersion = GetVersion(); DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); @@ -143,7 +143,7 @@ PIInit::PIInit() { setTimerResolutionAddr = (PINtSetTimerResolution)GetProcAddress(PRIVATE->ntlib, "NtSetTimerResolution"); __PISetTimerResolution(); } -# endif // WINDOWS +# endif // WINDOWS # ifdef HAS_LOCALE // std::cout << "has locale" << std::endl; if (currentLocale_t != 0) { @@ -156,9 +156,9 @@ PIInit::PIInit() { # ifndef EMSCRIPTEN setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); -# endif -# endif // HAS_LOCALE -# endif // ANDROID +# endif //EMSCRIPTEN +# endif // HAS_LOCALE +# endif // ANDROID PRIVATE->delete_locs = false; __syslocname__ = __sysoemname__ = 0; __utf8name__ = const_cast("UTF-8"); @@ -235,12 +235,12 @@ PIInit::PIInit() { sinfo->OS_version = uns.release; sinfo->architecture = uns.machine; } -# else +# else //EMSCRIPTEN sinfo->processorsCount = 1; sinfo->OS_version = PIStringAscii("WASM"); sinfo->architecture = PIStringAscii("wasm32"); -# endif -# endif // WINDOWS +# endif //EMSCRIPTEN +# endif // WINDOWS # ifdef ESP_PLATFORM esp_chip_info_t chip_info; diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index a07994fa..fec02876 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -73,7 +73,7 @@ # endif # endif #endif -#endif +#endif //EMSCRIPTEN // clang-format on #include "piwaitevent_p.h" @@ -110,7 +110,7 @@ PIString getSockAddr(sockaddr * s) { const char * r = inet_ntop(AF_INET, &((sockaddr_in *)s)->sin_addr, buf, sizeof(buf)); return r ? PIStringAscii(r) : PIString(); } -#endif +#endif // WINDOWS, EMSCRIPTEN REGISTER_DEVICE(PIEthernet) @@ -121,7 +121,7 @@ PRIVATE_DEFINITION_START(PIEthernet) sockaddr_in addr_; sockaddr_in saddr_; sockaddr_in raddr_; -#endif +#endif // EMSCRIPTEN PIWaitEvent event; PRIVATE_DEFINITION_END(PIEthernet) @@ -158,7 +158,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) { setPath(ip_port); #ifndef EMSCRIPTEN ethNonblocking(sock); -#endif +#endif // EMSCRIPTEN PRIVATE->event.create(); // piCoutObj << "new tcp client" << sock_; } @@ -218,8 +218,7 @@ void PIEthernet::construct() { void PIEthernet::init() { #ifdef EMSCRIPTEN return; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN if (isOpened() || is_server_client) return; if (sock != -1) return; // piCout << "init " << type(); @@ -252,7 +251,7 @@ void PIEthernet::init() { applyBuffers(); applyOptInt(IPPROTO_IP, IP_TTL, TTL()); // piCoutObj << "inited" << path(); -#endif +#endif // EMSCRIPTEN } @@ -278,11 +277,11 @@ PIByteArray PIEthernet::macToBytes(const PIString & mac) { PIString PIEthernet::applyMask(const PIString & ip, const PIString & mask) { #ifdef EMSCRIPTEN return PIString(); -#else +#else // EMSCRIPTEN struct in_addr ia; ia.s_addr = inet_addr(ip.dataAscii()) & inet_addr(mask.dataAscii()); return PIStringAscii(inet_ntoa(ia)); -#endif +#endif // EMSCRIPTEN } @@ -296,11 +295,11 @@ PINetworkAddress PIEthernet::applyMask(const PINetworkAddress & ip, const PINetw PIString PIEthernet::getBroadcast(const PIString & ip, const PIString & mask) { #ifdef EMSCRIPTEN return PIString(); -#else +#else // EMSCRIPTEN struct in_addr ia; ia.s_addr = inet_addr(ip.dataAscii()) | ~inet_addr(mask.dataAscii()); return PIStringAscii(inet_ntoa(ia)); -#endif +#endif // EMSCRIPTEN } @@ -314,8 +313,7 @@ PINetworkAddress PIEthernet::getBroadcast(const PINetworkAddress & ip, const PIN bool PIEthernet::openDevice() { #ifdef EMSCRIPTEN return false; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN if (connected_) return true; // piCoutObj << "open"; init(); @@ -335,7 +333,7 @@ bool PIEthernet::openDevice() { PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); # endif // piCout << "bind to" << (params[PIEthernet::Broadcast] ? "255.255.255.255" : ip_) << ":" << port_ << " ..."; - int tries = 0; + int tries = 0; while ((bind(sock, (sockaddr *)&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) { init(); tries++; @@ -352,7 +350,7 @@ bool PIEthernet::openDevice() { applyOptInt(IPPROTO_IP, IP_TTL, TTL()); addr_lr.clear(); return true; -#endif +#endif // EMSCRIPTEN } @@ -383,8 +381,7 @@ void PIEthernet::closeSocket(int & sd) { void PIEthernet::applyTimeouts() { #ifdef EMSCRIPTEN return; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN if (sock < 0) return; PISystemTime rtm = readTimeout(), wtm = writeTimeout(); applyTimeout(sock, SO_RCVTIMEO, rtm); @@ -393,7 +390,7 @@ void PIEthernet::applyTimeouts() { applyTimeout(sock_s, SO_RCVTIMEO, rtm); applyTimeout(sock_s, SO_SNDTIMEO, wtm); } -#endif +#endif // EMSCRIPTEN } @@ -408,7 +405,7 @@ void PIEthernet::applyBuffers() { ethSetsockoptInt(sock, SOL_SOCKET, SO_SNDBUF, snd_buf); } } -#endif +#endif // EMSCRIPTEN } @@ -416,9 +413,8 @@ void PIEthernet::applyTimeout(int fd, int opt, PISystemTime tm) { if (fd == 0) return; #ifdef EMSCRIPTEN return; -#endif -#ifndef EMSCRIPTEN - // piCoutObj << "setReadIsBlocking" << yes; +#else // EMSCRIPTEN + // piCoutObj << "setReadIsBlocking" << yes; # ifdef WINDOWS DWORD _tm = tm.toMilliseconds(); # else @@ -427,7 +423,7 @@ void PIEthernet::applyTimeout(int fd, int opt, PISystemTime tm) { _tm.tv_usec = tm.nanoseconds / 1000; # endif ethSetsockopt(fd, SOL_SOCKET, opt, &_tm, sizeof(_tm)); -#endif +#endif // EMSCRIPTEN } @@ -440,8 +436,7 @@ void PIEthernet::applyOptInt(int level, int opt, int val) { bool PIEthernet::joinMulticastGroup(const PIString & group) { #ifdef EMSCRIPTEN return false; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN if (sock == -1) init(); if (sock == -1) return false; if (type() != UDP) { @@ -490,15 +485,14 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) { applyOptInt(IPPROTO_IP, IP_MULTICAST_TTL, multicastTTL()); if (!mcast_groups.contains(group)) mcast_groups << group; return true; -#endif +#endif // EMSCRIPTEN } bool PIEthernet::leaveMulticastGroup(const PIString & group) { #ifdef EMSCRIPTEN return false; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN if (sock == -1) init(); if (sock == -1) return false; if (type() != UDP) { @@ -531,15 +525,14 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) { } mcast_groups.removeAll(group); return true; -#endif +#endif // EMSCRIPTEN } bool PIEthernet::connect(bool threaded) { #ifdef EMSCRIPTEN return false; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN if (threaded) { connecting_ = true; return true; @@ -553,11 +546,11 @@ bool PIEthernet::connect(bool threaded) { PRIVATE->addr_.sin_addr.s_addr = addr_r.ip(); PRIVATE->addr_.sin_family = AF_INET; # ifdef QNX - PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); + PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); # endif - connecting_ = true; - connected_ = connectTCP(); - connecting_ = false; + connecting_ = true; + connected_ = connectTCP(); + connecting_ = false; if (!connected_) { piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); } @@ -566,15 +559,14 @@ bool PIEthernet::connect(bool threaded) { connected(); } return connected_; -#endif +#endif // EMSCRIPTEN } bool PIEthernet::listen(bool threaded) { #ifdef EMSCRIPTEN return false; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN if (sock == -1) init(); if (sock == -1) return false; if (threaded) { @@ -596,10 +588,10 @@ bool PIEthernet::listen(bool threaded) { PRIVATE->addr_.sin_addr.s_addr = addr_r.ip(); PRIVATE->addr_.sin_family = AF_INET; # ifdef QNX - PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); + PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); # endif - opened_ = false; - int tries = 0; + opened_ = false; + int tries = 0; while ((bind(sock, (sockaddr *)&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == -1) && (tries < 2)) { init(); tries++; @@ -616,7 +608,7 @@ bool PIEthernet::listen(bool threaded) { piCoutObj << "listen on" << path(); server_thread_.start(server_func); return true; -#endif +#endif // EMSCRIPTEN } @@ -711,8 +703,7 @@ void PIEthernet::interrupt() { ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) { #ifdef EMSCRIPTEN return -1; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN // piCout << "read" << sock; if (sock == -1) init(); if (sock == -1 || read_to == 0) return -1; @@ -727,10 +718,10 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) { PRIVATE->addr_.sin_addr.s_addr = addr_r.ip(); PRIVATE->addr_.sin_family = AF_INET; # ifdef QNX - PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); + PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); # endif // piCoutObj << "connect to " << path() << "..."; - connected_ = connectTCP(); + connected_ = connectTCP(); // piCoutObj << "connect to " << path() << connected_; if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); opened_.exchange(connected_); @@ -838,15 +829,14 @@ ssize_t PIEthernet::readDevice(void * read_to, ssize_t max_size) { default: break; } return -1; -#endif +#endif // EMSCRIPTEN } ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) { #ifdef EMSCRIPTEN return -1; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN if (sock == -1) init(); if (sock == -1 || !isWriteable()) { // piCoutObj << "Can`t send to uninitialized socket"; @@ -880,10 +870,10 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) { PRIVATE->addr_.sin_addr.s_addr = addr_r.ip(); PRIVATE->addr_.sin_family = AF_INET; # ifdef QNX - PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); + PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); # endif // piCoutObj << "connect to " << ip << ":" << port_; - connected_ = connectTCP(); + connected_ = connectTCP(); if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); opened_.exchange(connected_); if (connected_) { @@ -940,7 +930,7 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) { default: break; } return -1; -#endif +#endif // EMSCRIPTEN } @@ -961,7 +951,7 @@ void PIEthernet::applyParameters() { if (params[PIEthernet::ReuseAddress]) ethSetsockoptBool(sock, SOL_SOCKET, SO_REUSEADDR); if (params[PIEthernet::Broadcast]) ethSetsockoptBool(sock, SOL_SOCKET, SO_BROADCAST); if (params[PIEthernet::NoDelay] && (type() == TCP_Client)) ethSetsockoptBool(sock, IPPROTO_TCP, TCP_NODELAY, true); -#endif +#endif // EMSCRIPTEN } @@ -974,8 +964,7 @@ void PIEthernet::clientDeleted(PIObject * o) { void PIEthernet::server_func(void * eth) { #ifdef EMSCRIPTEN return; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN PIEthernet * ce = (PIEthernet *)eth; if (ce->listen_threaded) { if (!ce->server_bounded) { @@ -989,7 +978,7 @@ void PIEthernet::server_func(void * eth) { sockaddr_in client_addr; socklen_t slen = sizeof(client_addr); # ifdef WINDOWS - long wr = ce->waitForEvent(ce->PRIVATEWB->event, FD_ACCEPT | FD_CLOSE); + long wr = ce->waitForEvent(ce->PRIVATEWB->event, FD_ACCEPT | FD_CLOSE); if (wr != FD_ACCEPT) { piMSleep(10); return; @@ -1030,7 +1019,7 @@ void PIEthernet::server_func(void * eth) { ce->clients_mutex.unlock(); ce->newConnection(e); // cout << "connected " << ip << endl; -#endif +#endif // EMSCRIPTEN } @@ -1048,8 +1037,7 @@ void PIEthernet::setType(Type t, bool reopen) { bool PIEthernet::connectTCP() { #ifdef EMSCRIPTEN return false; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN ::connect(sock, (sockaddr *)&(PRIVATE->addr_), sizeof(PRIVATE->addr_)); // piCout << errorString(); # ifdef WINDOWS @@ -1071,7 +1059,7 @@ bool PIEthernet::connectTCP() { } # endif return false; -#endif +#endif // EMSCRIPTEN } @@ -1109,13 +1097,12 @@ bool PIEthernet::configureDevice(const void * e_main, const void * e_parent) { void PIEthernet::propertyChanged(const char * name) { #ifdef EMSCRIPTEN return; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN PIConstChars pn(name); if (pn.endsWith("Timeout")) applyTimeouts(); if (pn == "TTL") applyOptInt(IPPROTO_IP, IP_TTL, TTL()); if (pn == "MulticastTTL") applyOptInt(IPPROTO_IP, IP_MULTICAST_TTL, multicastTTL()); -#endif +#endif // EMSCRIPTEN } @@ -1204,13 +1191,13 @@ void PIEthernet::configureFromVariantDevice(const PIPropertyStorage & d) { PIEthernet::InterfaceList PIEthernet::interfaces() { #ifdef EMSCRIPTEN return {}; -#endif +#else // EMSCRIPTEN // piCout << "PIEthernet::interfaces()"; PIEthernet::InterfaceList il; Interface ci; - ci.index = -1; - ci.mtu = 1500; -#ifdef WINDOWS + ci.index = -1; + ci.mtu = 1500; +# ifdef WINDOWS int ret = 0; ulong ulOutBufLen = sizeof(IP_ADAPTER_INFO); PIP_ADAPTER_INFO pAdapterInfo = (PIP_ADAPTER_INFO)HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO)); @@ -1261,10 +1248,10 @@ PIEthernet::InterfaceList PIEthernet::interfaces() { } } if (pAdapterInfo) HeapFree(GetProcessHeap(), 0, pAdapterInfo); -#elif !defined(EMSCRIPTEN) -# ifdef MICRO_PIP -# else -# ifdef ANDROID +# else // WINDOWS +# ifdef MICRO_PIP +# else +# ifdef ANDROID struct ifconf ifc; int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (s == -1) { @@ -1301,7 +1288,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() { } delete[] ifc.ifc_buf; ::close(s); -# else +# else struct ifaddrs *ret, *cif = 0; int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (getifaddrs(&ret) == 0) { @@ -1319,8 +1306,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() { ci.address = getSockAddr(cif->ifa_addr); ci.netmask = getSockAddr(cif->ifa_netmask); ci.mac.clear(); -# ifdef QNX -# ifndef BLACKBERRY +# ifdef QNX +# ifndef BLACKBERRY int fd = ::open((PIString("/dev/io-net/") + ci.name).dataAscii(), O_RDONLY); if (fd >= 0) { nic_config_t nic; @@ -1328,9 +1315,9 @@ PIEthernet::InterfaceList PIEthernet::interfaces() { ::close(fd); ci.mac = macFromBytes(PIByteArray(nic.permanent_address, 6)); } -# endif -# else -# ifdef MAC_OS +# endif +# else +# ifdef MAC_OS PIString req = PISystemInfo::instance()->ifconfigPath + " " + ci.name + " | grep ether"; FILE * fp = popen(req.dataAscii(), "r"); if (fp != 0) { @@ -1341,7 +1328,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() { } pclose(fp); } -# else +# else if (s != -1) { struct ifreq ir; memset(&ir, 0, sizeof(ir)); @@ -1353,8 +1340,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() { ci.mtu = ir.ifr_mtu; } } +# endif # endif -# endif ci.flags = 0; if (cif->ifa_flags & IFF_UP) ci.flags |= PIEthernet::ifActive; if (cif->ifa_flags & IFF_RUNNING) ci.flags |= PIEthernet::ifRunning; @@ -1375,10 +1362,11 @@ PIEthernet::InterfaceList PIEthernet::interfaces() { piCout << "[PIEthernet]" << "Can`t get interfaces: %1"_tr("PIEthernet").arg(errorString()); if (s != -1) ::close(s); +# endif # endif -# endif -#endif +# endif // WINDOWS return il; +#endif // EMSCRIPTEN } @@ -1397,7 +1385,7 @@ PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) { } struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr; return PINetworkAddress(uint(sa->sin_addr.s_addr)); -#endif +#endif // WINDOWS, MICRO_PIP, EMSCRIPTEN } @@ -1422,11 +1410,13 @@ PIVector PIEthernet::allAddresses() { int PIEthernet::ethErrorCore() { #ifdef WINDOWS return WSAGetLastError(); -#elif !defined(EMSCRIPTEN) - return errno; -#else +#else // WINDOWS +# ifdef EMSCRIPTEN return -1; -#endif +# else // EMSCRIPTEN + return errno; +# endif // EMSCRIPTEN +#endif // WINDOWS } @@ -1448,11 +1438,13 @@ PIString PIEthernet::ethErrorString() { } else ret += '?'; return ret; -#elif !defined(EMSCRIPTEN) - return errorString(); -#else +#else // WINDOWS +# ifdef EMSCRIPTEN return PIString(); -#endif +# else // EMSCRIPTEN + return errorString(); +# endif // EMSCRIPTEN +#endif // WINDOWS } @@ -1460,8 +1452,7 @@ int PIEthernet::ethRecv(int sock, void * buf, int size, int flags) { if (sock < 0) return -1; #ifdef EMSCRIPTEN return -1; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN return recv(sock, # ifdef WINDOWS (char *) @@ -1469,7 +1460,7 @@ int PIEthernet::ethRecv(int sock, void * buf, int size, int flags) { buf, size, flags); -#endif +#endif // EMSCRIPTEN } @@ -1477,8 +1468,7 @@ int PIEthernet::ethRecvfrom(int sock, void * buf, int size, int flags, sockaddr if (sock < 0) return -1; #ifdef EMSCRIPTEN return -1; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN # ifdef QNX return recv(sock, buf, size, flags); # else @@ -1493,7 +1483,7 @@ int PIEthernet::ethRecvfrom(int sock, void * buf, int size, int flags, sockaddr addr, &len); # endif -#endif +#endif // EMSCRIPTEN } @@ -1501,8 +1491,7 @@ int PIEthernet::ethSendto(int sock, const void * buf, int size, int flags, socka if (sock < 0) return -1; #ifdef EMSCRIPTEN return -1; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN return sendto(sock, # ifdef WINDOWS (const char *) @@ -1512,15 +1501,14 @@ int PIEthernet::ethSendto(int sock, const void * buf, int size, int flags, socka flags, addr, addr_len); -#endif +#endif // EMSCRIPTEN } void PIEthernet::ethClosesocket(int sock, bool shutdown) { #ifdef EMSCRIPTEN return; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN // piCout << "close socket" << sock << shutdown; if (sock < 0) return; if (shutdown) @@ -1532,7 +1520,7 @@ void PIEthernet::ethClosesocket(int sock, bool shutdown) { SHUT_RDWR); ::close(sock); # endif -#endif +#endif // EMSCRIPTEN } @@ -1540,8 +1528,7 @@ int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * opt if (sock < 0) return -1; #ifdef EMSCRIPTEN return -1; -#endif -#ifndef EMSCRIPTEN +#else // EMSCRIPTEN auto ret = setsockopt(sock, level, optname, @@ -1552,7 +1539,7 @@ int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * opt optlen); if (ret != 0) piCout << "setsockopt error:" << ethErrorString(); return ret; -#endif +#endif // EMSCRIPTEN } @@ -1585,16 +1572,19 @@ void PIEthernet::ethNonblocking(int sock) { #ifdef WINDOWS u_long mode = 1; ioctlsocket(sock, FIONBIO, &mode); -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN fcntl(sock, F_SETFL, O_NONBLOCK); -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS } bool PIEthernet::ethIsWriteable(int sock) { #ifdef EMSCRIPTEN return false; -#endif +#else // EMSCRIPTEN /* fd_set fd_test; FD_ZERO(&fd_test); FD_SET(sock, &fd_test); @@ -1606,7 +1596,7 @@ bool PIEthernet::ethIsWriteable(int sock) { timeout.tv_sec = timeout.tv_usec = 0; ::select(fds, nullptr, &fd_test, nullptr, &timeout); return FD_ISSET(sock, &fd_test);*/ -#ifdef WINDOWS +# ifdef WINDOWS fd_set fd_test; FD_ZERO(&fd_test); FD_SET(sock, &fd_test); @@ -1614,10 +1604,11 @@ bool PIEthernet::ethIsWriteable(int sock) { timeout.tv_sec = timeout.tv_usec = 0; ::select(0, nullptr, &fd_test, nullptr, &timeout); return FD_ISSET(sock, &fd_test); -#elif !defined(EMSCRIPTEN) +# else // WINDOWS int ret = 0; socklen_t len = sizeof(ret); getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&ret, &len); return ret == 0; -#endif +# endif // WINDOWS +#endif // EMSCRIPTEN } diff --git a/libs/main/io_devices/piserial.cpp b/libs/main/io_devices/piserial.cpp index 37d8570c..71778dbe 100644 --- a/libs/main/io_devices/piserial.cpp +++ b/libs/main/io_devices/piserial.cpp @@ -91,7 +91,7 @@ # include # include # include -# endif +# endif // EMSCRIPTEN # ifndef B50 # define B50 0000001 # endif @@ -176,7 +176,7 @@ #endif #if defined(LINUX) && !defined(EMSCRIPTEN) # include -#endif +#endif // LINUX && !EMSCRIPTEN //! \class PISerial piserial.h @@ -218,10 +218,13 @@ PRIVATE_DEFINITION_START(PISerial) HANDLE hCom = nullptr; DWORD readed = 0, mask = 0; OVERLAPPED overlap, overlap_write; -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN termios desc, sdesc; uint readed = 0; -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS PRIVATE_DEFINITION_END(PISerial) @@ -398,14 +401,17 @@ bool PISerial::setBreak(bool enabled) { return true; } } -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN if (ioctl(fd, enabled ? TIOCSBRK : TIOCCBRK) < 0) { piCoutObj << "setBreak error: " << errorString(); return false; } else { return true; } -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS return false; } @@ -427,13 +433,16 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) { } return true; } -# elif !defined(EMSCRIPTEN) +# else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) { piCoutObj << "setBit" << bname << " error: " << errorString(); return false; } return true; -# endif +# endif // EMSCRIPTEN +# endif // WINDOWS #endif piCoutObj << "setBit" << bname << " doesn`t implemented, sorry :-("; return false; @@ -447,11 +456,14 @@ bool PISerial::isBit(int bit, const PIString & bname) const { } #ifndef PISERIAL_NO_PINS # ifdef WINDOWS -# elif !defined(EMSCRIPTEN) +# else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN int ret = 0; if (ioctl(fd, TIOCMGET, &ret) < 0) piCoutObj << "isBit" << bname << " error: " << errorString(); return ret & bit; -# endif +# endif // EMSCRIPTEN +# endif // WINDOWS #endif piCoutObj << "isBit" << bname << " doesn`t implemented, sorry :-("; return false; @@ -461,7 +473,7 @@ bool PISerial::isBit(int bit, const PIString & bname) const { void PISerial::flush() { #if !defined(WINDOWS) && !defined(EMSCRIPTEN) if (fd != -1) tcflush(fd, TCIOFLUSH); -#endif +#endif // WINDOWS && EMSCRIPTEN } @@ -752,7 +764,9 @@ bool PISerial::openDevice() { return false; } fd = 0; -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN int om = 0; switch (mode()) { case PIIODevice::ReadOnly: om = O_RDONLY; break; @@ -767,7 +781,8 @@ bool PISerial::openDevice() { tcgetattr(fd, &PRIVATE->desc); PRIVATE->sdesc = PRIVATE->desc; // piCoutObj << "Initialized " << p; -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS applySettings(); PRIVATE->event.create(); #ifdef WINDOWS @@ -789,10 +804,13 @@ bool PISerial::closeDevice() { // piCoutObj << "close" << CloseHandle(PRIVATE->hCom); PRIVATE->hCom = 0; -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN tcsetattr(fd, TCSANOW, &PRIVATE->sdesc); ::close(fd); -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS fd = -1; } PRIVATE->event.destroy(); @@ -830,7 +848,9 @@ void PISerial::applySettings() { piCoutObj << "Unable to set comm state for \"%1\""_tr("PISerial").arg(path()); return; } -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN if (fd == -1) return; tcgetattr(fd, &PRIVATE->desc); PRIVATE->desc.c_oflag = PRIVATE->desc.c_lflag = PRIVATE->desc.c_cflag = 0; @@ -864,7 +884,8 @@ void PISerial::applySettings() { piCoutObj << "Can`t set attributes for \"%1\""_tr("PISerial").arg(path()); return; } -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS } @@ -883,9 +904,12 @@ void PISerial::setTimeouts() { times.WriteTotalTimeoutConstant = isOptionSet(BlockingWrite) ? 0 : 1; times.WriteTotalTimeoutMultiplier = 0; if (SetCommTimeouts(PRIVATE->hCom, ×) == -1) piCoutObj << "Unable to set timeouts for \"" << path() << "\""; -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN fcntl(fd, F_SETFL, isOptionSet(BlockingRead) ? 0 : O_NONBLOCK); -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS } @@ -934,7 +958,10 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) { return -1; // piCoutObj << "read" << (PRIVATE->readed) << errorString(); return PRIVATE->readed; -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN + return -1; +# else // EMSCRIPTEN if (!canRead()) return -1; if (isOptionSet(PIIODevice::BlockingRead)) { if (!PRIVATE->event.wait(fd)) return -1; @@ -949,9 +976,8 @@ ssize_t PISerial::readDevice(void * read_to, ssize_t max_size) { } } return ret; -#else - return -1; -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS } @@ -974,12 +1000,14 @@ ssize_t PISerial::writeDevice(const void * data, ssize_t max_size) { sending = false; // piCoutObj << "send ok" << dwrote;// << " bytes in " << path(); wrote = (ssize_t)dwrote; -#elif !defined(EMSCRIPTEN) +#else // WINDOWS +# ifdef EMSCRIPTEN + return -1; +# else // EMSCRIPTEN wrote = ::write(fd, data, max_size); if (isOptionSet(BlockingWrite)) tcdrain(fd); -#else - return -1; -#endif +# endif // EMSCRIPTEN +#endif // WINDOWS return wrote; // piCoutObj << "Error while sending"; } @@ -1196,10 +1224,10 @@ bool parseID(PIString str, PISerial::DeviceInfo & di) { PIVector PISerial::availableDevicesInfo(bool test) { #ifdef EMSCRIPTEN return {}; -#endif +#else // EMSCRIPTEN PIVector ret; DeviceInfo di; -#ifdef WINDOWS +# ifdef WINDOWS static const GUID guids[] = {GUID_DEVINTERFACE_MODEM, GUID_DEVINTERFACE_COMPORT}; static const int guids_cnt = sizeof(guids) / sizeof(GUID); for (int i = 0; i < guids_cnt; ++i) { @@ -1228,12 +1256,12 @@ PIVector PISerial::availableDevicesInfo(bool test) { } SetupDiDestroyDeviceInfoList(dis); } -#elif !defined(EMSCRIPTEN) -# ifndef ANDROID +# else // WINDOWS +# ifndef ANDROID PIStringList prefixes; -# ifdef QNX +# ifdef QNX prefixes << "ser"; -# else +# else prefixes << "ttyS" << "ttyO" << "ttyUSB" @@ -1244,14 +1272,14 @@ PIVector PISerial::availableDevicesInfo(bool test) { << "ttyAMA" << "rfcomm" << "ircomm"; -# ifdef FREE_BSD +# ifdef FREE_BSD prefixes << "cu"; -# endif -# ifdef MAC_OS +# endif +# ifdef MAC_OS prefixes.clear(); prefixes << "cu." << "tty."; -# endif +# endif PIFile file_prefixes("/proc/tty/drivers", PIIODevice::ReadOnly); if (file_prefixes.open()) { PIString fc = PIString::fromAscii(file_prefixes.readAll()), line, cpref; @@ -1272,18 +1300,18 @@ PIVector PISerial::availableDevicesInfo(bool test) { } prefixes.removeDuplicates(); } -# endif +# endif PIDir dir("/dev"); PIVector de = dir.entries(); -# ifdef LINUX +# ifdef LINUX char linkbuf[1024]; -# endif +# endif for (const auto & e: de) { // TODO changes in FileInfo for (const auto & p: prefixes) { if (e.name().startsWith(p)) { di = DeviceInfo(); di.path = e.path; -# ifdef LINUX +# ifdef LINUX ssize_t lsz = readlink(("/sys/class/tty/" + e.name()).dataAscii(), linkbuf, 1024); if (lsz > 0) { PIString fpath = "/sys/class/tty/" + PIString(linkbuf, lsz) + "/"; @@ -1299,16 +1327,16 @@ PIVector PISerial::availableDevicesInfo(bool test) { if (di.pID > 0) break; } } -# endif +# endif ret << di; } } } -# endif -#endif +# endif +# endif // WINDOWS if (test) { for (int i = 0; i < ret.size_s(); ++i) { -#ifdef WINDOWS +# ifdef WINDOWS void * hComm = CreateFileA(ret[i].path.dataAscii(), GENERIC_READ, FILE_SHARE_READ, @@ -1329,7 +1357,7 @@ PIVector PISerial::availableDevicesInfo(bool test) { continue; } CloseHandle(hComm); -#elif !defined(EMSCRIPTEN) +# else // WINDOWS int fd = ::open(ret[i].path.dataAscii(), O_NOCTTY | O_RDONLY); if (fd == -1) { ret.remove(i); @@ -1347,10 +1375,11 @@ PIVector PISerial::availableDevicesInfo(bool test) { continue; } ::close(fd); -#endif +# endif // WINDOWS } } return ret; +#endif // EMSCRIPTEN } @@ -1368,5 +1397,5 @@ void PISerial::threadedReadBufferSizeChanged() { ss.xmit_fifo_size = piMaxi(threadedReadBufferSize(), 4096); ioctl(fd, TIOCSSERIAL, &ss); // piCoutObj << "a" << ss.xmit_fifo_size; -#endif +#endif // LINUX && !EMSCRIPTEN } diff --git a/libs/main/io_devices/pisharedmemory.cpp b/libs/main/io_devices/pisharedmemory.cpp index 8f058693..d9e8f83a 100644 --- a/libs/main/io_devices/pisharedmemory.cpp +++ b/libs/main/io_devices/pisharedmemory.cpp @@ -98,10 +98,10 @@ PISharedMemory::~PISharedMemory() { bool PISharedMemory::openDevice() { #ifdef EMSCRIPTEN return false; -#endif +#else // EMSCRIPTEN close(); // piCoutObj << "try open" << path() << dsize; -#ifdef WINDOWS +# ifdef WINDOWS PRIVATE->name = ("PIP_SHM_" + path()).toByteArray(); PRIVATE->name.push_back(0); const char * nm = (const char *)PRIVATE->name.data(); @@ -122,8 +122,8 @@ bool PISharedMemory::openDevice() { return false; } // piCout << PRIVATE->map << PRIVATE->data; -#endif -#ifdef SHM_POSIX +# endif +# ifdef SHM_POSIX PRIVATE->name = ("/pip_shm_" + path()).toByteArray(); PRIVATE->name.push_back(0); int fd = shm_open((const char *)PRIVATE->name.data(), O_RDWR, 0777); @@ -153,8 +153,9 @@ bool PISharedMemory::openDevice() { return false; } // piCoutObj << "opened" << PRIVATE->data; -#endif +# endif return true; +#endif // EMSCRIPTEN } @@ -226,17 +227,18 @@ void PISharedMemory::initPrivate() { PIByteArray PISharedMemory::readAll() { #ifdef EMSCRIPTEN return PIByteArray(); -#endif +#else // EMSCRIPTEN if (dsize <= 0) return PIByteArray(); -#ifdef WINDOWS +# ifdef WINDOWS if (!PRIVATE->data) return PIByteArray(); -#endif -#ifdef SHM_POSIX +# endif +# ifdef SHM_POSIX if (!PRIVATE->data) return PIByteArray(); -#endif +# endif PIByteArray a(dsize); read(a.data(), a.size_s()); return a; +#endif // EMSCRIPTEN } diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index 1367ded1..e8e240b5 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -168,7 +168,8 @@ inline double pow10(const double & e) {return pow (10. , e);} //! \~english Returns `10` raised to the specified power. //! \~russian Возвращает `10` в указанной степени. inline ldouble pow10(const ldouble & e) {return powl(10.L, e);} -#endif +#else //EMSCRIPTEN +#endif //EMSCRIPTEN // clang-format on diff --git a/libs/main/piplatform.h b/libs/main/piplatform.h index c2729db5..76a89f31 100644 --- a/libs/main/piplatform.h +++ b/libs/main/piplatform.h @@ -76,16 +76,10 @@ //! \~\ingroup Core //! \~\brief -//! \~english Defined for Emscripten/WASM targets. -//! \~russian Определяется для целевых сборок Emscripten/WASM. +//! \~english Defined for Emscripten targets. +//! \~russian Определяется для целевых сборок Emscripten. # define EMSCRIPTEN -//! \~\ingroup Core -//! \~\brief -//! \~english Defined for WebAssembly targets. -//! \~russian Определяется для целевых сборок WebAssembly. -# define WASM - //! \~\ingroup Core //! \~\brief //! \~english Defined for reduced embedded PIP builds. @@ -170,7 +164,6 @@ #endif #ifdef __EMSCRIPTEN__ # define EMSCRIPTEN -# define WASM # ifdef __wasm64__ # define ARCH_BITS_64 # else diff --git a/libs/main/system/pihidevice.cpp b/libs/main/system/pihidevice.cpp index 299d8811..ce7daaf4 100644 --- a/libs/main/system/pihidevice.cpp +++ b/libs/main/system/pihidevice.cpp @@ -2,7 +2,8 @@ #include "piliterals_string.h" #include "piliterals_time.h" -#ifndef EMSCRIPTEN +#ifdef EMSCRIPTEN +#else // EMSCRIPTEN # ifndef WINDOWS # include "pidir.h" # include "pifile.h" @@ -25,7 +26,7 @@ extern "C" { } // clang-format on # endif -#endif +#endif // EMSCRIPTEN bool PIHIDeviceInfo::match(const PIString & str) const { @@ -63,15 +64,17 @@ void PIHIDeviceInfo::prepare() { PICout operator<<(PICout s, const PIHIDeviceInfo & v) { s.saveAndSetControls(0); - s << "PIHIDeviceInfo(" << v.product << " (" << v.manufacturer << "), " << v.VID << ":" << v.PID << ", " << v.axesAbsoluteCount() - << " abs axes, " << v.axesRelativeCount() << " rel axes, " << v.buttonsCount() << " buttons)"; + s << "PIHIDeviceInfo(" << v.product << " (" << v.manufacturer << "), " << v.VID << ":" << v.PID + << ", " //<< "path \"" << v.path << "\", " + << v.axesAbsoluteCount() << " abs axes, " << v.axesRelativeCount() << " rel axes, " << v.buttonsCount() << " buttons)"; s.restoreControls(); return s; } PRIVATE_DEFINITION_START(PIHIDevice) -#ifndef EMSCRIPTEN +#ifdef EMSCRIPTEN +#else // EMSCRIPTEN # ifndef WINDOWS PIFile file; bool is_js = false; @@ -80,7 +83,7 @@ PRIVATE_DEFINITION_START(PIHIDevice) HANDLE deviceHandle = nullptr; PHIDP_PREPARSED_DATA preparsed = nullptr; # endif -#endif +#endif // EMSCRIPTEN PRIVATE_DEFINITION_END(PIHIDevice) @@ -91,13 +94,13 @@ PIHIDevice::~PIHIDevice() { bool PIHIDevice::isOpened() const { #ifdef EMSCRIPTEN return false; -#else +#else // EMSCRIPTEN # ifndef WINDOWS return PRIVATE->file.isOpened(); # else return PRIVATE->deviceHandle; # endif -#endif +#endif // EMSCRIPTEN } @@ -110,7 +113,7 @@ bool PIHIDevice::open(const PIHIDeviceInfo & device) { if (device.isNull()) return false; #ifdef EMSCRIPTEN return false; -#else +#else // EMSCRIPTEN # ifndef WINDOWS if (!PRIVATE->file.open(di.path, PIIODevice::ReadOnly)) { piCout << "PIHIDevice::open" << di.path << "error:" << errorString(); @@ -138,7 +141,7 @@ bool PIHIDevice::open(const PIHIDeviceInfo & device) { } return true; # endif -#endif +#endif // EMSCRIPTEN } @@ -151,7 +154,7 @@ void PIHIDevice::close() { stop(); #ifdef EMSCRIPTEN return; -#else +#else // EMSCRIPTEN # ifndef WINDOWS PRIVATE->file.close(); # else @@ -164,13 +167,16 @@ void PIHIDevice::close() { PRIVATE->preparsed = nullptr; } # endif -#endif +#endif // EMSCRIPTEN } void PIHIDevice::start() { if (!isOpened()) return; PIThread::start(200_Hz); +#ifndef WINDOWS +#else // WINDOWS +#endif // WINDOWS } @@ -188,7 +194,7 @@ void PIHIDevice::stop() { void PIHIDevice::run() { #ifdef EMSCRIPTEN return; -#else +#else // EMSCRIPTEN Event e; # ifndef WINDOWS # pragma pack(push, 1) @@ -199,10 +205,10 @@ void PIHIDevice::run() { uint value; }; struct js_event { - uint time; - short value; - uchar type; - uchar number; + uint time; /* event timestamp in milliseconds */ + short value; /* value */ + uchar type; /* event type */ + uchar number; /* axis/button number */ }; # pragma pack(pop) if (PRIVATE->is_js) { @@ -212,15 +218,18 @@ void PIHIDevice::run() { bool ok = false; switch (ie.type) { case 2: { + // piCout << ie.value; cur_axes[ie.number] = procDeadZone(ie.value / 32767. / 2. + 0.5); ok = true; } break; case 1: + // piCout << ie.code; cur_buttons[ie.number] = ie.value; ok = true; break; default: break; } + // piCout << ok << ie.type << ie.code << ie.value; if (!ok) continue; } } else { @@ -229,7 +238,7 @@ void PIHIDevice::run() { if (ie.type == 0) continue; bool ok = false; switch (ie.type) { - case 2: { + case 2: { // rel axis auto vi = di.axis_by_dataindex.value(ie.code); if (vi.isValid()) { e.type = Event::tAxisMove; @@ -239,35 +248,41 @@ void PIHIDevice::run() { } ok = true; } break; - case 3: { + case 3: { // abs axis auto vi = di.axis_by_dataindex.value(ie.code); float fv = (ie.value - vi.min) / piMaxf(1.f, (float)(vi.max - vi.min)); cur_axes[ie.code] = procDeadZone(fv); ok = true; } break; - case 1: + case 1: // button + // piCout << ie.code; cur_buttons[ie.code] = ie.value; ok = true; break; default: break; } + // piCout << ok << ie.type << ie.code << ie.value; if (!ok) continue; } } # else PRIVATE->buffer.resize(di.input_report_size).fill(0); DWORD readed = 0; + // piCout << "read" << PRIVATE->deviceHandle << PRIVATE->buffer.size(); HIDP_DATA gdd[256]; ULONG gdd_len = 256; if (ReadFile(PRIVATE->deviceHandle, PRIVATE->buffer.data(), PRIVATE->buffer.size_s(), &readed, nullptr) != TRUE) return; + // piCout << readed << PRIVATE->buffer.size(); if (readed != PRIVATE->buffer.size()) return; auto gd = HidP_GetData(HidP_Input, gdd, &gdd_len, PRIVATE->preparsed, (PCHAR)PRIVATE->buffer.data(), PRIVATE->buffer.size_s()); NO_UNUSED(gd); + // piCout << "readed" << PRIVATE->buffer << gdd_len; auto cbit = cur_buttons.makeIterator(); while (cbit.next()) cbit.value() = 0; for (ULONG i = 0; i < gdd_len; ++i) { const auto & cd(gdd[i]); + // piCout << cd.DataIndex << cd.RawValue; auto vi = di.axis_by_dataindex.value(cd.DataIndex); if (vi.isValid()) { if (vi.is_relative) { @@ -276,14 +291,17 @@ void PIHIDevice::run() { e.value = static_cast(cd.RawValue); event(e); } else { + // auto & axis(cur_axes[cd.DataIndex]); float fv = (cd.RawValue - vi.min) / piMaxf(1.f, (float)(vi.max - vi.min)); cur_axes[vi.data_index] = procDeadZone(fv); } + // piCout << "axis" << vi.data_index << "->" << cur_axes[vi.data_index]; continue; } auto bi = di.button_by_dataindex.value(cd.DataIndex); if (bi.isValid()) { cur_buttons[bi.data_index] = 1; + // piCout << "button" << bi.data_index << "-> 1"; continue; } } @@ -310,7 +328,7 @@ void PIHIDevice::run() { } } prev_buttons = cur_buttons; -#endif +#endif // EMSCRIPTEN } @@ -331,10 +349,9 @@ PIVector PIHIDevice::allDevices(bool try_open) { #ifdef EMSCRIPTEN (void)try_open; return ret; -#endif +#endif // EMSCRIPTEN -#ifndef WINDOWS -# ifndef EMSCRIPTEN +#if !defined(WINDOWS) && !defined(EMSCRIPTEN) auto readFile = [](const PIString & path) { auto ba = PIFile::readAll(path); @@ -353,18 +370,23 @@ PIVector PIHIDevice::allDevices(bool try_open) { PIDir hid_dir("/sys/bus/hid/devices"_a); auto hid_devs = hid_dir.entries(); for (const auto & hd: hid_devs) { + // piCout << d.path; if (!isDir(hd)) continue; PIDir dir_input(hd.path + "/input"_a); auto hid_inputs = dir_input.entries(); for (const auto & hd_i: hid_inputs) { if (!isDir(hd_i)) continue; + // now in /sys/bus/hid/devices//input/input + // piCout << hd_i.path; PIHIDeviceInfo dev; dev.product = readFile(hd_i.path + "/name"_a); + // piCout << readFile(hd_i.path + "/name"_a); dev.VID = readFile(hd_i.path + "/id/vendor"_a); dev.PID = readFile(hd_i.path + "/id/product"_a); dev.version = readFile(hd_i.path + "/id/version"_a); dev.manufacturer = readFile(hd_i.path + "/id/manufacturer"_a); + // piCout << dev.product; dev.input_report_size = 24; PIDir dir_e(hd_i.path); PIStringList devs; @@ -373,6 +395,16 @@ PIVector PIHIDevice::allDevices(bool try_open) { if (!d_e.isDir() || d_e.flags[PIFile::FileInfo::Dot] || d_e.flags[PIFile::FileInfo::DotDot]) continue; devs << d_e.name(); } + /*bool dev_found = false; + for (const auto & d: devs) { + if (d.startsWith("js"_a)) { + dev.path = "/dev/input/"_a + d; + dev_found = true; + break; + } + } + if (!dev_found) {*/ + // search for event dir for (const auto & d: devs) { if (d.startsWith("event"_a)) { dev.path = "/dev/input/"_a + d; @@ -387,12 +419,17 @@ PIVector PIHIDevice::allDevices(bool try_open) { if (test_f.isClosed()) continue; } + // ullong ev = readFile(hd_i.path + "/capabilities/ev"_a).toULLong(16); + auto readAxes = [readFile, checkBit, &hd_i, &dev](const PIString & file, bool is_relative) { PIVector ret; ullong bits = readFile(hd_i.path + file).toULLong(16); + // piCout<< PICoutManipulators::Bin << abs; if (bits > 0) { int fd = ::open(dev.path.dataAscii(), O_RDONLY); - if (fd < 0) {} + if (fd < 0) { + // piCout << "Warning: can`t open" << dev.path << errorString(); + } PIHIDeviceInfo::AxisInfo ai; ai.is_relative = is_relative; for (int bit = 0; bit < 64; ++bit) { @@ -403,6 +440,7 @@ PIVector PIHIDevice::allDevices(bool try_open) { if (ioctl(fd, EVIOCGABS(bit), &abs_info) != -1) { ai.min = abs_info.minimum; ai.max = abs_info.maximum; + // piCout << "axis" << bit << abs_info.minimum << abs_info.maximum << abs_info.flat << abs_info.fuzz; } else { ai.min = 0; ai.max = 1024; @@ -442,6 +480,7 @@ PIVector PIHIDevice::allDevices(bool try_open) { for (const auto * hwp: {"/usr/share/hwdata/usb.ids", "/var/lib/usbutils/usb.ids"}) { PIFile hwf(hwp, PIIODevice::ReadOnly); if (hwf.isClosed()) continue; + // piCout << "search" << dev.VID << "in" << hwp; PIString line; PIIOTextStream ts(&hwf); while (!hwf.isEnd()) { @@ -461,8 +500,7 @@ PIVector PIHIDevice::allDevices(bool try_open) { } } -# endif -#else +#elif defined(WINDOWS) GUID guid; HidD_GetHidGuid(&guid); @@ -512,12 +550,18 @@ PIVector PIHIDevice::allDevices(bool try_open) { continue; } + // piCout << i << deviceHandle; + PHIDP_PREPARSED_DATA preparsed = nullptr; if (HidD_GetPreparsedData(deviceHandle, &preparsed) == FALSE) { piCout << "HidD_GetPreparsedData error:" << errorString(); CloseHandle(deviceHandle); continue; } + // auto pp = PIByteArray(preparsed, 64); + // piCout << piChangedEndian(pp.dataAs(7)) << piChangedEndian(pp.dataAs(8)) << + // piChangedEndian(pp.dataAs(9)); + // piCout << pp; dev.path = deviceInterfaceDetailData->DevicePath; @@ -575,6 +619,7 @@ PIVector PIHIDevice::allDevices(bool try_open) { else axes_abs << vi; } + // piCout << vc.LinkCollection << vc.LinkUsage << vc.LinkUsagePage; } dev.axes << axes_abs << axes_rel; for (int i = 0; i < dev.axes.size_s(); ++i) @@ -587,6 +632,7 @@ PIVector PIHIDevice::allDevices(bool try_open) { for (int i = 0; i < _cnt; ++i) { const auto & bc(button_caps[i]); PIHIDeviceInfo::ButtonInfo bi; + // dev.values.append(PIHIDeviceInfo::ValueInfo{value_caps[i].BitSize, value_caps[i].LogicalMin, value_caps[i].LogicalMax}); if (bc.IsRange == 1) { int count = bc.Range.UsageMax - bc.Range.UsageMin + 1; int cur_index = bc.Range.DataIndexMin; @@ -595,12 +641,16 @@ PIVector PIHIDevice::allDevices(bool try_open) { bi.data_index = cur_index; dev.buttons << bi; ++cur_index; + // piCout << b << (start_bit / 8) << (start_bit % 8); } } else { bi.index = dev.buttons.size_s(); bi.data_index = bc.NotRange.DataIndex; dev.buttons << bi; + // piCout << (bi.bit / 8) << (bi.bit % 8); } + // piCout << bc.IsRange << bc.Range.UsageMin << bc.Range.UsageMax + // << bc.Range.DataIndexMin << bc.Range.DataIndexMax; } HidD_FreePreparsedData(preparsed); diff --git a/libs/main/system/pilibrary.cpp b/libs/main/system/pilibrary.cpp index b191e351..85bae7cc 100644 --- a/libs/main/system/pilibrary.cpp +++ b/libs/main/system/pilibrary.cpp @@ -27,14 +27,109 @@ # endif +//! \class PILibrary pilibrary.h +//! \~\details +//! \~english \section _sec0 Synopsis +//! \~russian \section _sec0 Краткий обзор +//! \~english +//! %PILibrary allow you dynamically load external library and use +//! some methods from it. %PILibrary instance contains library +//! pointer and unload library on destructor, so recommended +//! to use it with \b new creation. +//! +//! Main method of %PILibrary is \a resolve(const char *), which returns +//! \c void* pointer to requested method. One should test it +//! to \c nullptr and convert it in pointer to the required method. +//! +//! In case of C++ libraries it`s very important to use [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) +//! of exported methods! You may also need to mark methods for +//! export, e.g. \c __declspec(dllexport). You can include \c +//! and use \a PIP_PLUGIN_EXPORT to mark exports with PIP. +//! +//! \~russian +//! %PILibrary позволяет динамически загружать стороннюю библиотеку +//! и использовать оттуда методы. Экземпляр %PILibrary содержит +//! указатель на библиотеку и выгружает её в деструкторе, поэтому +//! рекомендуется создавать её с помощью \b new. +//! +//! Основной метод %PILibrary - это \a resolve(const char *), который возвращает +//! \c void* указатель на запрошенный метод. Необходимо проверить его +//! на \c nullptr и преобразовать в указатель на нужный метод. +//! +//! В случае C++ библиотеки очень важно использовать [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) +//! для экспортируемых методов! Также может понадобиться пометить +//! методы на экспорт, например, \c __declspec(dllexport). Можно включить \c +//! и использовать \a PIP_PLUGIN_EXPORT, чтобы пометить экспорт с помощью PIP. +//! +//! \~\code +//! extern "C" { +//! __declspec(dllexport) int exportedSum(int,int); +//! __declspec(dllexport) int exportedMul(int,int); +//! } +//! \endcode +//! +//! \~english \section _sec1 Usage +//! \~russian \section _sec1 Использование +//! +//! \~english Library: +//! \~russian Библиотека: +//! \~\code +//! #include +//! +//! extern "C" { +//! PIP_PLUGIN_EXPORT int exportedSum(int,int); +//! PIP_PLUGIN_EXPORT int exportedMul(int,int); +//! } +//! +//! int exportedSum(int a, int b) { +//! return a + b; +//! } +//! int exportedMul(int a, int b) { +//! return a * b; +//! } +//! \endcode +//! +//! \~english Program: +//! \~russian Программа: +//! \~\code +//! int main(int argc, char * argv[]) { +//! typedef int(*MyFunc)(int,int); +//! PILibrary * lib = new PILibrary(); +//! if (lib->load("mylib.dll")) { +//! MyFunc fadd = (MyFunc)lib->resolve("exportedSum"); +//! MyFunc fmul = (MyFunc)lib->resolve("exportedMul"); +//! if (fadd) { +//! int sum = fadd(1, 2); +//! piCout << "sum =" << sum; +//! } else { +//! piCout << "Can`t resolve" << "exportedSum"; +//! } +//! if (fmul) { +//! int mul = fadd(10, 20); +//! piCout << "mul =" << mul; +//! } else { +//! piCout << "Can`t resolve" << "exportedMul"; +//! } +//! } else { +//! piCout << lib->lastError(); +//! } +//! delete lib; +//! } +//! +//! // sum = 3 +//! // mul = 30 +//! \endcode +//! + + PRIVATE_DEFINITION_START(PILibrary) # ifdef WINDOWS HMODULE # elif defined(EMSCRIPTEN) void * -# else +# else // EMSCRIPTEN void * -# endif +# endif // EMSCRIPTEN hLib; PRIVATE_DEFINITION_END(PILibrary) @@ -67,9 +162,9 @@ void PILibrary::unload() { FreeLibrary(PRIVATE->hLib); # elif defined(EMSCRIPTEN) PRIVATE->hLib = 0; -# else +# else // EMSCRIPTEN dlclose(PRIVATE->hLib); -# endif +# endif // EMSCRIPTEN PRIVATE->hLib = 0; } @@ -79,22 +174,47 @@ bool PILibrary::isLoaded() const { } +//! \~\details +//! \~english +//! Returns exported method with name "symbol" from +//! loaded library. Method have to use [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) and +//! marked to export, according to compiler specification.\n +//! C-linkage doesn`t provide information about return type +//! and arguments, so you should manually convert obtained +//! pointer to required method format before call. +//! +//! \~russian +//! Возвращает экспортированный метод с именем "symbol" +//! из загруженной библиотеки. Метод должен иметь [C-linkage](https://en.cppreference.com/w/cpp/language/language_linkage) +//! и помечен для экспорта, согласно спецификации компилятора.\n +//! C-linkage не предоставляет информации о возвращаемом типе +//! и аргументах, поэтому необходимо вручную преобразовать +//! полученный указатель к формату требуемого метода перед вызовом. +//! +//! \~\return +//! \~english +//! \b void* pointer to method or\n +//! \b nullptr if method doesn`t exists or library not loaded +//! +//! \~russian +//! \b void* указатель на метод или\n +//! \b nullptr если метод не существует или библиотека не загружена void * PILibrary::resolve(const char * symbol) { if (!isLoaded()) return 0; # ifdef EMSCRIPTEN (void)symbol; liberror = "dlsym not available on Emscripten"; return 0; -# else +# else // EMSCRIPTEN void * ret; # ifdef WINDOWS ret = (void *)GetProcAddress(PRIVATE->hLib, symbol); -# else +# else // WINDOWS ret = dlsym(PRIVATE->hLib, symbol); -# endif +# endif // WINDOWS getLastError(); return ret; -# endif +# endif // EMSCRIPTEN } @@ -104,15 +224,15 @@ bool PILibrary::loadInternal() { # ifdef EMSCRIPTEN liberror = "dlopen not available on Emscripten"; return false; -# else +# else // EMSCRIPTEN # ifdef WINDOWS PRIVATE->hLib = LoadLibraryA(libpath.data()); -# else +# else // WINDOWS PRIVATE->hLib = dlopen(libpath.data(), RTLD_LAZY); -# endif +# endif // WINDOWS getLastError(); return PRIVATE->hLib; -# endif +# endif // EMSCRIPTEN } @@ -121,13 +241,13 @@ void PILibrary::getLastError() { liberror = errorString(); # elif defined(EMSCRIPTEN) liberror.clear(); -# else +# else // EMSCRIPTEN const char * e = dlerror(); if (e) liberror = e; else liberror.clear(); -# endif +# endif // EMSCRIPTEN } #endif // MICRO_PIP diff --git a/libs/main/system/piprocess.cpp b/libs/main/system/piprocess.cpp index d91ba75c..e546d9d3 100644 --- a/libs/main/system/piprocess.cpp +++ b/libs/main/system/piprocess.cpp @@ -24,16 +24,49 @@ # include "piliterals_bytes.h" # include "piprocess.h" # include "pitranslator.h" -# ifndef WINDOWS -# include -# include -# include -# endif +# ifdef EMSCRIPTEN +# else // EMSCRIPTEN +# ifndef WINDOWS +# include +# include +# include +# endif +# endif // EMSCRIPTEN # ifdef MAC_OS # include # endif +//! \class PIProcess piprocess.h +//! \~\details +//! \~english +//! This class able to start external executables, watch for them, +//! grab output and exit code. +//! +//! \~russian +//! +//! +//! \~english \section PIProcess_sec0 Synopsis +//! \~russian \section PIProcess_sec0 Краткий обзор +//! \~english +//! External executable can be started with control or fully independent +//! from application.\n +//! Start with control allow you to wait for finish, grab output +//! and terminate it at any time.\n +//! You can change working directory and environment of executable.\n +//! +//! \~russian +//! +//! +//! \~english \section PIProcess_sec1 Usage +//! \~russian \section PIProcess_sec1 Использование +//! \~english +//! +//! +//! \~russian +//! + + namespace { enum PipeDirection { PipeRead, @@ -55,8 +88,8 @@ constexpr int StdFileCount = StdLast + 1; using PipeHandleType = HANDLE; using SizeType = DWORD; # elif defined(EMSCRIPTEN) -using PipeHandleType = int; using SizeType = ssize_t; +using PipeHandleType = int; # else using SizeType = ssize_t; using PipeHandleType = int; @@ -71,9 +104,6 @@ PIString convertWindowsCmd(PIStringList sl) { return sl.join(' '); } # elif defined(EMSCRIPTEN) -char * const * convertToCharArrays(const PIStringList &) { - return nullptr; -} # else char * const * convertToCharArrays(const PIStringList & sl) { char ** cc = new char *[sl.size() + 1]; @@ -89,6 +119,7 @@ char * const * convertToCharArrays(const PIStringList & sl) { PRIVATE_DEFINITION_START(PIProcess) + # ifdef WINDOWS PROCESS_INFORMATION pi; # elif defined(EMSCRIPTEN) @@ -120,7 +151,7 @@ PRIVATE_DEFINITION_START(PIProcess) # ifdef EMSCRIPTEN (void)pipe_type; return false; -# else +# else // EMSCRIPTEN const int pt = pipe_type; # ifdef WINDOWS SECURITY_ATTRIBUTES saAttr; @@ -133,14 +164,15 @@ PRIVATE_DEFINITION_START(PIProcess) int ret = pipe(pipes[pt]); return ret != -1; # endif -# endif +# endif // EMSCRIPTEN + return false; } bool createPipes() { # ifdef EMSCRIPTEN return false; -# else +# else // EMSCRIPTEN for (int i = 0; i < StdFileCount; ++i) { if (grab[i]) { if (!createPipe(static_cast(i))) { @@ -158,7 +190,7 @@ PRIVATE_DEFINITION_START(PIProcess) if (grab[StdErr]) SetHandleInformation(pipes[StdErr][PipeRead], HANDLE_FLAG_INHERIT, 0); # endif return true; -# endif +# endif // EMSCRIPTEN } @@ -189,8 +221,9 @@ PRIVATE_DEFINITION_START(PIProcess) PIByteArray readPipe(StdFile pipe_type) { # ifdef EMSCRIPTEN + (void)pipe_type; return {}; -# else +# else // EMSCRIPTEN if (!grab[pipe_type]) return {}; constexpr size_t read_buffer_size = 4_KiB; PIByteArray read_buffer; @@ -222,14 +255,15 @@ PRIVATE_DEFINITION_START(PIProcess) } } return read_buffer; -# endif +# endif // EMSCRIPTEN } bool writePipe(const PIByteArray & data) { # ifdef EMSCRIPTEN + (void)data; return false; -# else +# else // EMSCRIPTEN SizeType sz = 0; # ifdef WINDOWS BOOL ok = WriteFile(pipes[StdIn][PipeWrite], data.data(), data.size(), &sz, NULL); @@ -247,7 +281,7 @@ PRIVATE_DEFINITION_START(PIProcess) sz = offset; # endif return sz == (SizeType)data.size_s(); -# endif +# endif // EMSCRIPTEN } PRIVATE_DEFINITION_END(PIProcess) @@ -257,6 +291,9 @@ PIProcess::PIProcess(): PIThread() { exit_code = -1; # ifdef WINDOWS PRIVATE->pi.dwProcessId = 0; +# elif defined(EMSCRIPTEN) + PRIVATE->pid = 0; + PRIVATE->forEachPipe([](PipeHandleType & pipe) { pipe = -1; }); # else PRIVATE->pid = 0; PRIVATE->forEachPipe([](PipeHandleType & pipe) { pipe = -1; }); @@ -288,7 +325,7 @@ void PIProcess::startProc(bool detached) { exec_start = false; exec_finished = false; return; -# else +# else // EMSCRIPTEN const PIString & str = args.front(); if (!detached) execStarted(str); if (!PRIVATE->createPipes()) return; @@ -301,16 +338,17 @@ void PIProcess::startProc(bool detached) { if (PRIVATE->grab[StdErr]) si.hStdError = PRIVATE->pipes[StdErr][PipeWrite]; si.dwFlags |= STARTF_USESTDHANDLES; const auto cmd = convertWindowsCmd(args); - if (CreateProcessA(0, - (LPSTR)cmd.data(), - 0, - 0, - true, - detached ? DETACHED_PROCESS : 0, - 0, - wd.isEmpty() ? 0 : wd.data(), - &si, - &(PRIVATE->pi))) { + if (CreateProcessA(0, // No module name (use command line) + (LPSTR)cmd.data(), // Command line + 0, // Process handle not inheritable + 0, // Thread handle not inheritable + true, // Set handle inheritance to FALSE + detached ? DETACHED_PROCESS /*CREATE_NEW_CONSOLE*/ : 0, // Creation flags + 0, // Use environment + wd.isEmpty() ? 0 : wd.data(), // Use working directory + &si, // Pointer to STARTUPINFO structure + &(PRIVATE->pi))) // Pointer to PROCESS_INFORMATION structure + { exec_start = true; if (!detached) { WaitForSingleObject(PRIVATE->pi.hProcess, INFINITE); @@ -352,6 +390,7 @@ void PIProcess::startProc(bool detached) { PRIVATE->closePipe(StdErr, PipeWrite); execve(str.data(), largs, lenv); + // normaly execve can't return, if it returns - error occured piCoutObj << "\"execve" << str << args << "\" error :" << errorString(); exit(127); } else { @@ -377,14 +416,14 @@ void PIProcess::startProc(bool detached) { # endif if (!detached) execFinished(str, exit_code); exec_start = false; -# endif +# endif // EMSCRIPTEN } void PIProcess::terminate() { # ifdef EMSCRIPTEN return; -# else +# else // EMSCRIPTEN # ifdef WINDOWS if (exec_start) { if (!TerminateProcess(PRIVATE->pi.hProcess, 0)) return; @@ -394,7 +433,7 @@ void PIProcess::terminate() { if (exec_start) kill(PRIVATE->pid, SIGKILL); PRIVATE->pid = 0; # endif -# endif +# endif // EMSCRIPTEN } @@ -408,13 +447,13 @@ void PIProcess::execIndependent(const PIString & program, const PIStringList & a int PIProcess::pID() const { # ifdef EMSCRIPTEN return -1; -# else +# else // EMSCRIPTEN # ifdef WINDOWS return PRIVATE->pi.dwProcessId; # else return PRIVATE->pid; # endif -# endif +# endif // EMSCRIPTEN } @@ -462,20 +501,20 @@ void PIProcess::enableReadStdErr(bool on) { int PIProcess::currentPID() { # ifdef EMSCRIPTEN return -1; -# else +# else // EMSCRIPTEN # ifdef WINDOWS return GetCurrentProcessId(); # else return getpid(); # endif -# endif +# endif // EMSCRIPTEN } PIStringList PIProcess::currentEnvironment() { # ifdef EMSCRIPTEN return PIStringList(); -# else +# else // EMSCRIPTEN PIStringList l; int i = 0; while (environ[i] != 0) { @@ -483,7 +522,7 @@ PIStringList PIProcess::currentEnvironment() { ++i; } return l; -# endif +# endif // EMSCRIPTEN } diff --git a/libs/main/system/pisignals.cpp b/libs/main/system/pisignals.cpp index b432d62d..cf100577 100644 --- a/libs/main/system/pisignals.cpp +++ b/libs/main/system/pisignals.cpp @@ -20,7 +20,8 @@ #include "pisignals.h" #include "piincludes.h" -#ifndef EMSCRIPTEN +#ifdef EMSCRIPTEN +#else // EMSCRIPTEN # ifdef BLACKBERRY # include # else @@ -30,7 +31,7 @@ # define SIGUSR1 10 # define SIGUSR2 12 # endif -#endif +#endif // EMSCRIPTEN PISignals::SignalEvent PISignals::ret_func; @@ -38,7 +39,7 @@ PISignals::SignalEvent PISignals::ret_func; void PISignals::grabSignals(PIFlags signals_) { #ifdef EMSCRIPTEN (void)signals_; -#else +#else // EMSCRIPTEN if (signals_[PISignals::Interrupt]) signal(signalCode(PISignals::Interrupt), PISignals::signal_event); if (signals_[PISignals::Illegal]) signal(signalCode(PISignals::Illegal), PISignals::signal_event); if (signals_[PISignals::Abort]) signal(signalCode(PISignals::Abort), PISignals::signal_event); @@ -62,14 +63,14 @@ void PISignals::grabSignals(PIFlags signals_) { if (signals_[PISignals::StopTTYInput]) signal(signalCode(PISignals::StopTTYInput), PISignals::signal_event); if (signals_[PISignals::StopTTYOutput]) signal(signalCode(PISignals::StopTTYOutput), PISignals::signal_event); # endif -#endif +#endif // EMSCRIPTEN } void PISignals::releaseSignals(PIFlags signals_) { #ifdef EMSCRIPTEN (void)signals_; -#else +#else // EMSCRIPTEN if (signals_[PISignals::Interrupt]) signal(signalCode(PISignals::Interrupt), SIG_DFL); if (signals_[PISignals::Illegal]) signal(signalCode(PISignals::Illegal), SIG_DFL); if (signals_[PISignals::Abort]) signal(signalCode(PISignals::Abort), SIG_DFL); @@ -93,16 +94,16 @@ void PISignals::releaseSignals(PIFlags signals_) { if (signals_[PISignals::StopTTYInput]) signal(signalCode(PISignals::StopTTYInput), SIG_DFL); if (signals_[PISignals::StopTTYOutput]) signal(signalCode(PISignals::StopTTYOutput), SIG_DFL); # endif -#endif +#endif // EMSCRIPTEN } void PISignals::raiseSignal(PISignals::Signal signal) { #ifdef EMSCRIPTEN (void)signal; -#else +#else // EMSCRIPTEN raise(signalCode(signal)); -#endif +#endif // EMSCRIPTEN } @@ -110,7 +111,7 @@ int PISignals::signalCode(PISignals::Signal signal) { #ifdef EMSCRIPTEN (void)signal; return 0; -#else +#else // EMSCRIPTEN switch (signal) { case PISignals::Interrupt: return SIGINT; case PISignals::Illegal: return SIGILL; @@ -138,7 +139,7 @@ int PISignals::signalCode(PISignals::Signal signal) { default: break; } return 0; -#endif +#endif // EMSCRIPTEN } @@ -146,7 +147,7 @@ PISignals::Signal PISignals::signalFromCode(int signal) { #ifdef EMSCRIPTEN (void)signal; return PISignals::Termination; -#else +#else // EMSCRIPTEN switch (signal) { case SIGINT: return PISignals::Interrupt; case SIGILL: return PISignals::Illegal; @@ -174,7 +175,7 @@ PISignals::Signal PISignals::signalFromCode(int signal) { default: break; } return PISignals::Termination; -#endif +#endif // EMSCRIPTEN } diff --git a/libs/main/system/pisysteminfo.cpp b/libs/main/system/pisysteminfo.cpp index b986a57e..d394a701 100644 --- a/libs/main/system/pisysteminfo.cpp +++ b/libs/main/system/pisysteminfo.cpp @@ -47,7 +47,7 @@ PISystemInfo * PISystemInfo::instance() { ret.hostname = "wasm"; ret.user = "browser"; ret.processorsCount = 1; -#endif +#endif // EMSCRIPTEN } return &ret; } @@ -66,7 +66,7 @@ PIStringList PISystemInfo::mountRoots() { } else clet += PIChar(letters[i]); } -#else +#else // WINDOWS # ifdef LINUX PIString s_df, s_m; char in[1024]; @@ -87,7 +87,7 @@ PIStringList PISystemInfo::mountRoots() { } # else # endif -#endif +#endif // WINDOWS return ret; } @@ -146,6 +146,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { PIString s_df, s_m; char in[1024]; piZeroMemory(in, 1024); + // piCout << "mountInfo 0"; FILE * fp = popen("df -B1", "r"); PIStringList l_df; PIMap fs; @@ -155,6 +156,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { pclose(fp); fp = 0; } + // piCout << "mountInfo 1"; piZeroMemory(in, 1024); fp = popen("mount -l", "r"); PIStringList tl; @@ -182,6 +184,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { me.label.cutLeft(1).cutRight(1); } fs[dev] = me; + // piCout << fsmp << fstl; } pclose(fp); fp = 0; @@ -201,6 +204,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { m.mount_point = s3.mp; m.label = s3.label; ret << m; + // piCout << ml; } #endif @@ -224,9 +228,9 @@ PIString confDir() { "" #elif defined(EMSCRIPTEN) "" -#else +#else // EMSCRIPTEN PIDir::home().path() + "/.config" -#endif +#endif // EMSCRIPTEN ; } @@ -250,14 +254,14 @@ PIString PISystemInfo::machineKey() { PIString conf = confDir() + "/.pip_machine_salt"; #ifdef EMSCRIPTEN ret = si->OS_name + "_" + si->architecture; -#else +#else // EMSCRIPTEN if (PIFile::isExists(conf)) salt = PIFile::readAll(conf); if (salt.size_s() != SALT_SIZE) { salt = generateSalt(); PIFile::writeAll(conf, salt); } ret = si->OS_name + "_" + si->architecture + "_" + si->hostname + "_" + salt.toHex(); -#endif +#endif // EMSCRIPTEN } return ret; } @@ -268,6 +272,7 @@ uint PISystemInfo::machineID() { if (ret == 0) { CRC_32 crc = standardCRC_32(); ret = crc.calculate(machineKey().toByteArray()); + // piCout << "machineID \"" << machineKey() << "\" =" << PICoutManipulators::Hex << ret; } return ret; } diff --git a/libs/main/thread/pithread.cpp b/libs/main/thread/pithread.cpp index 0d29ec0a..f7dbb1bc 100644 --- a/libs/main/thread/pithread.cpp +++ b/libs/main/thread/pithread.cpp @@ -49,7 +49,7 @@ #elif defined(EMSCRIPTEN) # include # define gettid() (pid_t)(uintptr_t) pthread_self() -#endif +#endif //EMSCRIPTEN #if defined(MAC_OS) || defined(BLACKBERRY) # include #endif @@ -870,7 +870,7 @@ void PIThread::_beginThread() { #endif #if defined(LINUX) || defined(EMSCRIPTEN) tid_ = gettid(); -#endif +#endif //EMSCRIPTEN setPriority(priority_); setThreadName(); PIINTROSPECTION_THREAD_START(this);