/* PIP - Platform Independent Primitives Initialization Copyright (C) 2017 Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "piincludes_p.h" #include "piinit.h" #include "pitime.h" #include "pisignals.h" #include "piobject.h" #include "pisysteminfo.h" #include "pidir.h" #include "piprocess.h" #include "piresourcesstorage.h" #ifdef WINDOWS # include extern FILETIME __pi_ftjan1970; extern PINtQueryTimerResolution getTimerResolutionAddr; extern PINtSetTimerResolution setTimerResolutionAddr; void __PISetTimerResolution() { if (setTimerResolutionAddr == NULL || getTimerResolutionAddr == NULL) return; ULONG max(0), min(0), cur(0); getTimerResolutionAddr(&max, &min, &cur); //printf("getTimerResolution %lu %lu %lu\n", min, max, cur); setTimerResolutionAddr(min, TRUE, &cur); //printf("setTimerResolution %lu\n", cur); } #else # include # include # include # ifdef BLACKBERRY # include # else # include # endif #endif #ifdef MAC_OS # include # include # include //# include extern clock_serv_t __pi_mac_clock; #endif #ifdef PIP_ICU # include # include #endif /* #ifdef WINDOWS # include # include # include # include #else # include # include # include #endif*/ #ifdef HAS_LOCALE static locale_t currentLocale_t = 0; #endif PRIVATE_DEFINITION_START(PIInit) #ifdef WINDOWS HMODULE ntlib; ULONG prev_res; #endif PRIVATE_DEFINITION_END(PIInit) void __sighandler__(PISignals::Signal s) { //piCout << Hex << int(s); if (s == PISignals::StopTTYInput || s == PISignals::StopTTYOutput) piMSleep(10); if (s == PISignals::UserDefined1) dumpApplicationToFile(PIDir::home().path() + PIDir::separator + PIStringAscii("_PIP_DUMP_") + PIString::fromNumber(PIProcess::currentPID())); } #ifdef ANDROID void android_thread_exit_handler(int sig) { pthread_exit(0); } #endif PIInit::PIInit() { file_charset = 0; PISystemInfo * sinfo = PISystemInfo::instance(); sinfo->execDateTime = PIDateTime::current(); setFileCharset("UTF-8"); #ifndef ANDROID PISignals::setSlot(__sighandler__); PISignals::grabSignals(PISignals::UserDefined1); # ifndef WINDOWS PISignals::grabSignals(PISignals::StopTTYInput | PISignals::StopTTYOutput); sigset_t ss; sigemptyset(&ss); sigaddset(&ss, SIGALRM); sigprocmask(SIG_BLOCK, &ss, 0); pthread_sigmask(SIG_BLOCK, &ss, 0); signal(SIGPIPE, SIG_IGN); PIStringList ifpathes; ifpathes << PIStringAscii("/bin/ifconfig") << PIStringAscii("/sbin/ifconfig") << PIStringAscii("/usr/bin/ifconfig") << PIStringAscii("/usr/sbin/ifconfig"); piForeachC (PIString & i, ifpathes) if (fileExists(i)) { sinfo->ifconfigPath = i; piBreak; } # else // OS version DWORD dwVersion = GetVersion(); DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); sinfo->OS_version = PIString::fromNumber(dwMajorVersion) + "." + PIString::fromNumber(dwMinorVersion); // WinSock inint WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); // Timers init SYSTEMTIME jan1970 = {1970, 1, 4, 1, 0, 0, 0, 0}; SystemTimeToFileTime(&jan1970, &__pi_ftjan1970); LARGE_INTEGER pf; pf.QuadPart = -1; if (QueryPerformanceFrequency(&pf) != 0) __pi_perf_freq = pf.QuadPart; if (__pi_perf_freq == 0) __pi_perf_freq = -1; // Sleep precision init PRIVATE->ntlib = LoadLibrary("ntdll.dll"); if (PRIVATE->ntlib) { getTimerResolutionAddr = (PINtQueryTimerResolution)GetProcAddress(PRIVATE->ntlib, "NtQueryTimerResolution"); setTimerResolutionAddr = (PINtSetTimerResolution)GetProcAddress(PRIVATE->ntlib, "NtSetTimerResolution"); } __PISetTimerResolution(); /*if (setTimerResolution) setTimerResolutionAddr(1, TRUE, &(PRIVATE->prev_res));*/ # endif //piDebug = true; # ifdef HAS_LOCALE //cout << "has locale" << endl; if (currentLocale_t != 0) { freelocale(currentLocale_t); currentLocale_t = 0; } currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0); # else setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); # endif #else struct sigaction actions; memset(&actions, 0, sizeof(actions)); sigemptyset(&actions.sa_mask); actions.sa_flags = 0; actions.sa_handler = android_thread_exit_handler; sigaction(SIGTERM, &actions, 0); #endif #ifdef PIP_ICU __syslocname__ = __sysoemname__ = 0; //__syslocname__ = new char[256]; //memset(__syslocname__, 0, 256); UErrorCode e((UErrorCode)0); u_init(&e); # ifdef WINDOWS CPINFOEX cpinfo; int l = 0; /*GetCPInfoEx(CP_ACP, 0, &cpinfo); for (l = 0; l < MAX_PATH; ++l) if (cpinfo.CodePageName[l] == '\0' || cpinfo.CodePageName[l] == ' ') break; memcpy(__syslocname__, "windows-", 8); memcpy(&(__syslocname__[8]), cpinfo.CodePageName, l);*/ GetCPInfoEx(CP_OEMCP, 0, &cpinfo); for (l = 0; l < MAX_PATH; ++l) if (cpinfo.CodePageName[l] == '\0' || cpinfo.CodePageName[l] == ' ') break; __sysoemname__ = new char[256]; memset(__sysoemname__, 0, 256); memcpy(__sysoemname__, "ibm-", 4); memcpy(&(__sysoemname__[4]), cpinfo.CodePageName, l); # else /*PIString en(getenv("LANG")); if (!en.isEmpty()) en = en.mid(en.find(".") + 1); PIByteArray enba = en.toByteArray(); memcpy(__syslocname__, enba.data(), enba.size_s());*/ # endif //piCout << __syslocname__; //piCout << __sysoemname__; #endif #ifdef MAC_OS host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &__pi_mac_clock); #endif char cbuff[1024]; memset(cbuff, 0, 1024); if (gethostname(cbuff, 1023) == 0) sinfo->hostname = cbuff; #ifdef WINDOWS SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); sinfo->processorsCount = sysinfo.dwNumberOfProcessors; switch (sysinfo.wProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_AMD64: sinfo->architecture = PIStringAscii("x64"); break; case PROCESSOR_ARCHITECTURE_ARM: sinfo->architecture = PIStringAscii("ARM"); break; case PROCESSOR_ARCHITECTURE_IA64: sinfo->architecture = PIStringAscii("Intel Itanium-based"); break; case PROCESSOR_ARCHITECTURE_INTEL: sinfo->architecture = PIStringAscii("x86"); break; case PROCESSOR_ARCHITECTURE_UNKNOWN: default: sinfo->architecture = PIStringAscii("unknown"); break; } int argc_(0); wchar_t ** argv_ = CommandLineToArgvW(GetCommandLineW(), &argc_); if (argc_ > 0 && argv_ != 0) sinfo->execCommand = argv_[0]; LocalFree(argv_); memset(cbuff, 0, 1024); ulong unlen = 1023; if (GetUserName(cbuff, &unlen) != 0) sinfo->user = cbuff; #else sinfo->processorsCount = piMaxi(1, int(sysconf(_SC_NPROCESSORS_ONLN))); passwd * ps = getpwuid(getuid()); if (ps) sinfo->user = ps->pw_name; else { memset(cbuff, 0, 1024); char * l = getlogin(); if (l) sinfo->user = l; } struct utsname uns; if (uname(&uns) == 0) { sinfo->OS_version = uns.release; sinfo->architecture = uns.machine; } #endif sinfo->OS_name = #ifdef WINDOWS PIStringAscii("Windows"); #else # ifdef QNX PIStringAscii("QNX"); # else # ifdef MAC_OS PIStringAscii("MacOS"); # else # ifdef ANDROID PIStringAscii("Android"); # else # ifdef FREE_BSD PIStringAscii("FreeBSD"); # else uns.sysname; # endif # endif # endif # endif #endif } PIInit::~PIInit() { if (file_charset) delete file_charset; file_charset = 0; PIResourcesStorage::instance()->clear(); #ifdef WINDOWS WSACleanup(); //if (setTimerResolution) setTimerResolutionAddr(PRIVATE->prev_res, TRUE, &(PRIVATE->prev_res)); if (PRIVATE->ntlib) FreeLibrary(PRIVATE->ntlib); PRIVATE->ntlib = 0; #endif #ifdef MAC_OS mach_port_deallocate(mach_task_self(), __pi_mac_clock); #endif #ifdef PIP_ICU if (__syslocname__) delete __syslocname__; if (__sysoemname__) delete __sysoemname__; u_cleanup(); #endif //if (currentLocale_t != 0) freelocale(currentLocale_t); } bool PIInit::isBuildOptionEnabled(PIInit::BuildOption o) { switch (o) { case ICU: return #ifdef PIP_ICU true; #else false; #endif case USB: return #ifdef PIP_USB true; #else false; #endif case STL: return #ifdef PIP_CONTAINERS_STL true; #else false; #endif case Crypt: return #ifdef PIP_CRYPT true; #else false; #endif case IntrospectionContainers: return #ifdef PIP_INTROSPECTION_CONTAINERS true; #else false; #endif case IntrospectionThreads: return #ifdef PIP_INTROSPECTION_THREADS true; #else false; #endif default: return false; } return false; } void PIInit::setFileCharset(const char *charset) { if (file_charset) delete file_charset; file_charset = 0; if (charset) { file_charset = new char[1024]; memset(file_charset, 0, 1024); strcpy(file_charset, charset); } } bool PIInit::fileExists(const PIString & p) { FILE * f = fopen(p.data(), "r"); if (f == 0) return false; fclose(f); return true; } int __PIInit_Initializer__::count_(0); PIInit * __PIInit_Initializer__::__instance__(0); __PIInit_Initializer__::__PIInit_Initializer__() { count_++; if (count_ > 1) return; //piCout << "create PIInit"; __instance__ = new PIInit(); } __PIInit_Initializer__::~__PIInit_Initializer__() { count_--; if (count_ > 0) return; //piCout << "delete PIInit"; if (__instance__ != 0) { delete __instance__; __instance__ = 0; } }