git-svn-id: svn://db.shs.com.ru/pip@400 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
371
src_main/core/piinit.cpp
Normal file
371
src_main/core/piinit.cpp
Normal file
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Initialization
|
||||
Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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"
|
||||
#ifdef WINDOWS
|
||||
# include <winsock2.h>
|
||||
extern FILETIME __pi_ftjan1970;
|
||||
extern PINtSetTimerResolution setTimerResolutionAddr;
|
||||
#else
|
||||
# include <pwd.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <pthread.h>
|
||||
# ifdef BLACKBERRY
|
||||
# include <signal.h>
|
||||
# else
|
||||
# include <csignal>
|
||||
# endif
|
||||
#endif
|
||||
#ifdef MAC_OS
|
||||
# include <mach/mach_traps.h>
|
||||
# include <mach/mach.h>
|
||||
# include <mach/clock.h>
|
||||
//# include <crt_externs.h>
|
||||
extern clock_serv_t __pi_mac_clock;
|
||||
#endif
|
||||
#ifdef PIP_ICU
|
||||
# include <unicode/uclean.h>
|
||||
# include <unicode/ucnv.h>
|
||||
#endif
|
||||
/*
|
||||
#ifdef WINDOWS
|
||||
# include <conio.h>
|
||||
# include <io.h>
|
||||
# include <windows.h>
|
||||
# include <wincon.h>
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <pthread.h>
|
||||
#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) setTimerResolutionAddr = (PINtSetTimerResolution)GetProcAddress(PRIVATE->ntlib, "NtSetTimerResolution");
|
||||
/*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);
|
||||
//piCout << cpinfo.CodePageName;
|
||||
# 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;
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user