/* PIP - Platform Independent Primitives Initialization Copyright (C) 2015 Ivan Pelipenko peri4ko@gmail.com 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 "piplatform.h" #include "piinit.h" #include "pisignals.h" #include "piobject.h" #include "pisysteminfo.h" #include "pidir.h" #include "piprocess.h" #ifdef WINDOWS # include extern FILETIME __pi_ftjan1970; #else # include # include # include # include #endif #ifdef MAC_OS # include # include # include //# include extern clock_serv_t __pi_mac_clock; #endif /* #ifdef WINDOWS # include # include # include # include #else # include # include # include #endif*/ #ifdef HAS_LOCALE static locale_t currentLocale_t = 0; #endif 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 + "_PIP_DUMP_" + PIString::fromNumber(PIProcess::currentPID())); } PIInit::PIInit() { PISystemInfo * sinfo = PISystemInfo::instance(); sinfo->execDateTime = PIDateTime::current(); 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 << "/bin/ifconfig" << "/sbin/ifconfig" << "/usr/bin/ifconfig" << "/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(dwMajorVersion) + "." + PIString(dwMinorVersion); // WinSock inint WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); // Timers init SYSTEMTIME jan1970 = {1970, 1, 4, 1, 0, 14, 15, 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 ntlib = LoadLibrary("ntdll.dll"); if (ntlib) setTimerResolutionAddr = (PINtSetTimerResolution)GetProcAddress(ntlib, "NtSetTimerResolution"); /*if (setTimerResolution) setTimerResolutionAddr(1, TRUE, &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 #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 = "x64"; break; case PROCESSOR_ARCHITECTURE_ARM: sinfo->architecture = "ARM"; break; case PROCESSOR_ARCHITECTURE_IA64: sinfo->architecture = "Intel Itanium-based"; break; case PROCESSOR_ARCHITECTURE_INTEL: sinfo->architecture = "x86"; break; case PROCESSOR_ARCHITECTURE_UNKNOWN: default: sinfo->architecture = "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); if (getlogin_r(cbuff, 1023) == 0) sinfo->user = cbuff; } struct utsname uns; if (uname(&uns) == 0) { sinfo->OS_version = uns.release; sinfo->architecture = uns.machine; } #endif sinfo->OS_name = #ifdef WINDOWS "Windows"; #else # ifdef QNX "QNX"; # else # ifdef MAC_OS "MacOS"; # else # ifdef ANDROID "Android"; # else uns.sysname; # endif # endif # endif #endif } PIInit::~PIInit() { #ifdef WINDOWS WSACleanup(); //if (setTimerResolution) setTimerResolutionAddr(prev_res, TRUE, &prev_res); if (ntlib) FreeLibrary(ntlib); ntlib = 0; #endif #ifdef MAC_OS mach_port_deallocate(mach_task_self(), __pi_mac_clock); #endif //if (currentLocale_t != 0) freelocale(currentLocale_t); } 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_ > 1) return; //piCout << "delete PIInit"; if (__instance__ != 0) { delete __instance__; __instance__ = 0; } }