summaryrefslogtreecommitdiff
path: root/src/base/OSHelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/OSHelper.cpp')
-rw-r--r--src/base/OSHelper.cpp308
1 files changed, 308 insertions, 0 deletions
diff --git a/src/base/OSHelper.cpp b/src/base/OSHelper.cpp
new file mode 100644
index 0000000..377e725
--- /dev/null
+++ b/src/base/OSHelper.cpp
@@ -0,0 +1,308 @@
+//
+// libavg - Media Playback Engine.
+// Copyright (C) 2003-2014 Ulrich von Zadow
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Current versions can be found at www.libavg.de
+//
+
+#include "OSHelper.h"
+#include "FileHelper.h"
+#include "Logger.h"
+#include "FileHelper.h"
+#include "Exception.h"
+
+#if defined(_WIN32)
+#include <windows.h>
+#include <psapi.h>
+#undef ERROR
+#undef WARNING
+#elif defined(__APPLE__)
+#include <mach-o/dyld.h>
+#include <mach/mach.h>
+#include <sys/utsname.h>
+#elif defined(__linux)
+#include <fstream>
+#include <unistd.h>
+#include <string.h>
+#endif
+
+#include <stdlib.h>
+#include <iostream>
+#include <cstdlib>
+
+using namespace std;
+
+namespace avg {
+
+#ifdef _WIN32
+string getWinErrMsg(unsigned err)
+{
+ LPVOID lpMsgBuf;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+ 0, NULL );
+ string sMsg((char*)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ return sMsg;
+}
+#endif
+
+#if defined(__linux)
+// Adapted from binreloc
+static char *
+_br_find_exe_for_symbol (const void *symbol)
+{
+ #define SIZE 1024
+ FILE *f;
+ size_t address_string_len;
+ char *address_string, line[SIZE], *found;
+
+ if (symbol == NULL)
+ return (char *) NULL;
+
+ f = fopen ("/proc/self/maps", "r");
+ if (f == NULL)
+ return (char *) NULL;
+
+ address_string_len = 4;
+ address_string = (char *) malloc(address_string_len);
+ found = (char *) NULL;
+
+
+ while (!feof (f)) {
+ char *start_addr, *end_addr, *end_addr_end, *file;
+ void *start_addr_p, *end_addr_p;
+ size_t len;
+
+ if (fgets (line, SIZE, f) == NULL)
+ break;
+
+ /* Sanity check. */
+ if (strstr (line, " r-xp ") == NULL || strchr (line, '/') == NULL)
+ continue;
+
+ /* Parse line. */
+ start_addr = line;
+ end_addr = strchr (line, '-');
+ file = strchr (line, '/');
+
+ /* More sanity check. */
+ if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-'))
+ continue;
+
+ end_addr[0] = '\0';
+ end_addr++;
+ end_addr_end = strchr (end_addr, ' ');
+ if (end_addr_end == NULL)
+ continue;
+
+ end_addr_end[0] = '\0';
+ len = strlen (file);
+ if (len == 0)
+ continue;
+ if (file[len - 1] == '\n')
+ file[len - 1] = '\0';
+
+ /* Get rid of "(deleted)" from the filename. */
+ len = strlen (file);
+ if (len > 10 && strcmp (file + len - 10, " (deleted)") == 0)
+ file[len - 10] = '\0';
+
+ /* I don't know whether this can happen but better safe than sorry. */
+ len = strlen (start_addr);
+ if (len != strlen (end_addr))
+ continue;
+
+
+ /* Transform the addresses into a string in the form of 0xdeadbeef,
+ * then transform that into a pointer. */
+ if (address_string_len < len + 3) {
+ address_string_len = len + 3;
+ address_string = (char *) realloc (address_string, address_string_len);
+ }
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, start_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &start_addr_p);
+
+ memcpy (address_string, "0x", 2);
+ memcpy (address_string + 2, end_addr, len);
+ address_string[2 + len] = '\0';
+ sscanf (address_string, "%p", &end_addr_p);
+
+
+ if (symbol >= start_addr_p && symbol < end_addr_p) {
+ found = file;
+ break;
+ }
+ }
+
+ free (address_string);
+ fclose (f);
+
+ if (found == NULL)
+ return (char *) NULL;
+ else
+ return strdup (found);
+}
+#endif
+
+string getAvgLibPath()
+{
+#if defined(_WIN32)
+ HMODULE hModule = GetModuleHandle("avg.pyd");
+ char szFilename[1024];
+ DWORD ok = GetModuleFileName(hModule, szFilename, sizeof(szFilename));
+ if (ok == 0) {
+ AVG_LOG_ERROR("getAvgLibPath(): " << getWinErrMsg(GetLastError()));
+ exit(5);
+ }
+ string sPath=getPath(szFilename);
+ return sPath;
+#elif defined(__APPLE__)
+ // We need to iterate through all images attached to the current executable
+ // and figure out which one is the one we are interested in.
+ uint32_t numImages = _dyld_image_count();
+ for (uint32_t i=0; i<numImages; i++) {
+ const char * pszImageName = _dyld_get_image_name(i);
+ string sFilePart=getFilenamePart(pszImageName);
+ if (sFilePart == "avg.so" || sFilePart == "avg.0.so"
+ || sFilePart == "avg.0.0.0.so")
+ {
+ return getPath(pszImageName);
+ }
+ }
+ char path[1024];
+ uint32_t pathLen = sizeof(path);
+ _NSGetExecutablePath(path, &pathLen);
+ return getPath(path);
+#else
+ char* pszFilename;
+ pszFilename = _br_find_exe_for_symbol((const void *)"");
+ return pszFilename;
+#endif
+}
+
+bool getEnv(const string & sName, string & sVal)
+{
+ const char * pszVal = getenv(sName.c_str());
+ if (pszVal) {
+ sVal = pszVal;
+ }
+ return (pszVal != 0);
+}
+
+void setEnv(const string & sName, const string & sVal)
+{
+#ifdef _WIN32
+ SetEnvironmentVariable(sName.c_str(), sVal.c_str());
+#else
+ setenv(sName.c_str(), sVal.c_str(), true);
+#endif
+}
+
+size_t getMemoryUsage()
+{
+#ifdef __APPLE__
+ kern_return_t rc;
+ mach_port_t task;
+ rc = task_for_pid(mach_task_self(), getpid(), &task);
+ AVG_ASSERT(rc == KERN_SUCCESS);
+ struct task_basic_info taskInfo;
+ mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
+ rc = task_info(task, TASK_BASIC_INFO, (task_info_t)&taskInfo, &count);
+ AVG_ASSERT(rc == KERN_SUCCESS);
+ return taskInfo.resident_size;
+#else
+#ifdef _WIN32
+ DWORD pid = GetCurrentProcessId();
+ HANDLE hProcess;
+ PROCESS_MEMORY_COUNTERS pmc;
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+ BOOL bOk = GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
+ CloseHandle(hProcess);
+ return pmc.WorkingSetSize;
+#else
+ unsigned vmsize;
+ unsigned rssize;
+ // See 'man proc' for a documentation of this file's contents.
+ std::ifstream f("/proc/self/statm");
+ f >> vmsize >> rssize;
+ return rssize*(size_t)(getpagesize());
+#endif
+#endif
+}
+
+std::string convertUTF8ToFilename(const std::string & sName)
+{
+#ifdef _WIN32
+ // Conversion from utf-8 to something windows can use:
+ // utf-8 long filename -> utf-16 long filename -> utf-16 short filename (8.3)
+ // -> utf-8 short filename (= ASCII short filename).
+ wchar_t wideString[2048];
+ int err1 = MultiByteToWideChar(CP_UTF8, 0, sName.c_str(), sName.size()+1,
+ wideString, 2048);
+ if (err1 == 0) {
+ AVG_LOG_WARNING("Error in unicode conversion (MultiByteToWideChar): " <<
+ getWinErrMsg(GetLastError()));
+ return sName;
+ }
+ wchar_t wideShortFName[2048];
+ DWORD err2 = GetShortPathNameW(wideString, wideShortFName, 1024);
+ if (err2 != 0) {
+ char pShortName[1024];
+ err1 = WideCharToMultiByte(CP_UTF8, 0, wideShortFName, -1, pShortName,
+ 1024, 0, 0);
+ if (err1 == 0) {
+ AVG_LOG_WARNING("Error in unicode conversion (MultiByteToWideChar): " <<
+ getWinErrMsg(GetLastError()));
+ }
+ return pShortName;
+ } else {
+ return sName;
+ }
+#else
+ return sName;
+#endif
+}
+
+#ifdef __APPLE__
+int reallyGetOSXMajorVersion()
+{
+ utsname sysInfo;
+ int rc = uname(&sysInfo);
+ AVG_ASSERT(rc == 0);
+// cerr << sysInfo.sysname << ", " << sysInfo.nodename << ", " << sysInfo.release <<
+// ", " << sysInfo.version << ", " << sysInfo.machine << endl;
+ istringstream ss(sysInfo.release);
+ int major;
+ int minor;
+ int dot;
+ char c;
+ ss >> major >> c >> minor >> c >> dot;
+ return major;
+}
+
+int getOSXMajorVersion()
+{
+ static int major = reallyGetOSXMajorVersion(); // only called once for speed reasons.
+ return major;
+}
+#endif
+}