From b544a24a749485c33c693b93a14bc3e20a01f34e Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Fri, 12 Jun 2009 00:42:09 +0000 Subject: [PATCH] Mac MGR: strip /n from command field of PROCINFO struct to fix ; KillClient() gets pid from procinfo_setup() except on Windows; restore boinc.jpg file svn path=/trunk/boinc/; revision=18385 --- checkin_notes | 18 + clientgui/BOINCClientManager.cpp | 946 +++++++++++----------- clientscr/res/boinc.jpg | Bin 0 -> 19958 bytes lib/procinfo_mac.cpp | 3 + mac_build/boinc.xcodeproj/project.pbxproj | 2 + 5 files changed, 477 insertions(+), 492 deletions(-) create mode 100644 clientscr/res/boinc.jpg diff --git a/checkin_notes b/checkin_notes index 35bc9f5cfc..3506e48223 100644 --- a/checkin_notes +++ b/checkin_notes @@ -5461,3 +5461,21 @@ Rom 11 June 2009 acct_mgr_url.xml progress.ico ss_config.xml + +Charlie 11 June 2009 + - Mac MGR: strip /n from command field of PROCINFO struct so + log flag works properly on Mac. + - MGR: Change CBOINCClientManager::KillClient() to get client pid from + procinfo_setup() on all non-Windows platforms. + - SCR: restore boinc.jpg file erroneously removed from SVN. + + clientgui/ + BOINCClientManager.cpp + clientscr/ + res/ + boinc.jpg (restored) + lib/ + procinfo_mac.cpp + mac_build/ + boinc.xcodeproj/ + project.pbxproj diff --git a/clientgui/BOINCClientManager.cpp b/clientgui/BOINCClientManager.cpp index 501adaa71e..1beed6749f 100644 --- a/clientgui/BOINCClientManager.cpp +++ b/clientgui/BOINCClientManager.cpp @@ -1,492 +1,454 @@ -// This file is part of BOINC. -// http://boinc.berkeley.edu -// Copyright (C) 2008 University of California -// -// BOINC 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 3 of the License, or (at your option) any later version. -// -// BOINC 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 BOINC. If not, see . - -#if defined(__GNUG__) && !defined(__APPLE__) -#pragma implementation "BOINCClientManager.h" -#endif - -#include "stdwx.h" -#include "diagnostics.h" -#include "LogBOINC.h" -#include "BOINCGUIApp.h" -#include "MainDocument.h" -#include "BOINCBaseFrame.h" -#include "AdvancedFrame.h" -#include "BOINCClientManager.h" -#include "error_numbers.h" - -#include "filesys.h" -#include "util.h" - -#ifdef __WXMAC__ -enum { - NewStyleDaemon = 1, - OldStyleDaemon -}; -#endif - -#ifdef __WXMSW__ -#include "win_util.h" -#include "diagnostics_win.h" - -extern int diagnostics_get_process_information(PVOID* ppBuffer, PULONG pcbBuffer); -EXTERN_C BOOL IsBOINCServiceInstalled(); -EXTERN_C BOOL IsBOINCServiceStarting(); -EXTERN_C BOOL IsBOINCServiceRunning(); -EXTERN_C BOOL IsBOINCServiceStopping(); -EXTERN_C BOOL IsBOINCServiceStopped(); -EXTERN_C BOOL StartBOINCService(); -EXTERN_C BOOL StopBOINCService(); -#endif - -CBOINCClientManager::CBOINCClientManager() { - wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::CBOINCClientManager - Function Begin")); - - m_bBOINCStartedByManager = false; - m_lBOINCCoreProcessId = 0; - -#ifdef __WXMSW__ - m_hBOINCCoreProcess = NULL; -#endif - - wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::CBOINCClientManager - Function End")); -} - - -CBOINCClientManager::~CBOINCClientManager() { - wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::~CBOINCClientManager - Function Begin")); - - wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::~CBOINCClientManager - Function End")); -} - - -bool CBOINCClientManager::AutoRestart() { - if (IsBOINCCoreRunning()) return true; -#ifndef __WXMAC__ // Mac can restart Client as a daemon - if (! m_bBOINCStartedByManager) return false; -#endif - m_lBOINCCoreProcessId = 0; - StartupBOINCCore(); - return true; -} - - -bool CBOINCClientManager::IsSystemBooting() { - bool bReturnValue = false; -#if defined(__WXMSW__) - if (GetTickCount() < (1000*60*5)) bReturnValue = true; // If system has been up for less than 5 minutes -#elif defined(__WXMAC__) - if (TickCount() < (120*60)) bReturnValue = true; // If system has been up for less than 2 minutes -#endif - return bReturnValue; -} - - -int CBOINCClientManager::IsBOINCConfiguredAsDaemon() { - bool bReturnValue = false; -#if defined(__WXMSW__) - if (IsBOINCServiceInstalled()) bReturnValue = 1; -#elif defined(__WXMAC__) - if ( boinc_file_exists("/Library/LaunchDaemons/edu.berkeley.boinc.plist")) { - bReturnValue = NewStyleDaemon; // New-style daemon uses launchd - } - if (boinc_file_exists("/Library/StartupItems/boinc/boinc") ) { - bReturnValue = OldStyleDaemon; // Old-style daemon uses StartupItem - } -#endif - return bReturnValue; -} - - -bool CBOINCClientManager::IsBOINCCoreRunning() { - wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function Begin")); - bool running = false; - -#ifdef __WXMSW__ - char buf[MAX_PATH] = ""; - - if (IsBOINCServiceInstalled()) { - running = (FALSE != IsBOINCServiceStarting()) || (FALSE != IsBOINCServiceRunning()); - } else { - // Global mutex on Win2k and later - // - if (IsWindows2000Compatible()) { - strcpy(buf, "Global\\"); - } - strcat( buf, RUN_MUTEX); - - HANDLE h = CreateMutexA(NULL, true, buf); - DWORD err = GetLastError(); - if ((h==0) || (err == ERROR_ALREADY_EXISTS)) { - running = true; - } - if (h) { - CloseHandle(h); - } - } -#else - char path[1024]; - static FILE_LOCK file_lock; - - sprintf(path, "%s/%s", (char *)wxGetApp().GetDataDirectory().char_str(), LOCK_FILE_NAME); - if (file_lock.lock(path)) { - running = true; - } else { - file_lock.unlock(path); - } -#endif - wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Returning '%d'"), (int)running); - wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function End")); - return running; -} - - -bool CBOINCClientManager::StartupBOINCCore() { - wxLogTrace(wxT("Function Start/End"), wxT("CMainDocument::StartupBOINCCore - Function Begin")); - - bool bReturnValue = false; - wxString strExecute = wxEmptyString; - - if (IsBOINCCoreRunning()) return true; - -#if defined(__WXMSW__) - LPTSTR szExecute = NULL; - LPTSTR szDataDirectory = NULL; - - if (IsBOINCConfiguredAsDaemon()) { - StartBOINCService(); - - m_bBOINCStartedByManager = true; - bReturnValue = IsBOINCCoreRunning(); - } else { - - // Append boinc.exe to the end of the strExecute string and get ready to rock - strExecute.Printf( - wxT("\"%s\\boinc.exe\" --redirectio --launched_by_manager %s"), - wxGetApp().GetRootDirectory().c_str(), - wxGetApp().GetArguments().c_str() - ); - - PROCESS_INFORMATION pi; - STARTUPINFO si; - BOOL bProcessStarted; - - memset(&pi, 0, sizeof(pi)); - memset(&si, 0, sizeof(si)); - - si.cb = sizeof(si); - si.dwFlags = STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; - - szExecute = (LPTSTR)strExecute.c_str(); - if (wxGetApp().GetDataDirectory().empty()) { - szDataDirectory = NULL; - } else { - szDataDirectory = (LPTSTR)wxGetApp().GetDataDirectory().c_str(); - } - - wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szExecute '%s'\n"), szExecute); - wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szDataDirectory '%s'\n"), szDataDirectory); - - bProcessStarted = CreateProcess( - NULL, - szExecute, - NULL, - NULL, - FALSE, - CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW, - NULL, - szDataDirectory, - &si, - &pi - ); - - if (bProcessStarted) { - m_lBOINCCoreProcessId = pi.dwProcessId; - m_hBOINCCoreProcess = pi.hProcess; - } - } - -#elif defined(__WXMAC__) - -#if 0 // The Mac version of wxExecute(wxString& ...) crashes if there is a space in the path - wxChar buf[1024]; - wxChar *argv[5]; -#else - char buf[1024]; - char *argv[5]; -#endif - ProcessSerialNumber ourPSN; - FSRef ourFSRef; - OSErr err; - - if (IsBOINCConfiguredAsDaemon() == NewStyleDaemon) { - system ("launchctl load /Library/LaunchDaemons/edu.berkeley.boinc.plist"); - system ("launchctl start edu.berkeley.boinc"); - bReturnValue = IsBOINCCoreRunning(); - } else { - - // Get the full path to core client inside this application's bundle - err = GetCurrentProcess (&ourPSN); - if (err == noErr) { - err = GetProcessBundleLocation(&ourPSN, &ourFSRef); - } - if (err == noErr) { - err = FSRefMakePath (&ourFSRef, (UInt8*)buf, sizeof(buf)); - } - if (err == noErr) { -#if 0 // The Mac version of wxExecute(wxString& ...) crashes if there is a space in the path - strExecute = wxT("\""); - strExecute += wxT(buf); - strExecute += wxT("/Contents/Resources/boinc\" --redirectio --launched_by_manager"); - m_lBOINCCoreProcessId = ::wxExecute(strExecute); -#else // Use wxExecute(wxChar **argv ...) instead of wxExecute(wxString& ...) - strcat(buf, "/Contents/Resources/boinc"); - argv[0] = buf; - argv[1] = "--redirectio"; - argv[2] = "--launched_by_manager"; - argv[3] = NULL; -#ifdef SANDBOX - if (!g_use_sandbox) { - argv[3] = "--insecure"; - argv[4] = NULL; - } -#endif - // Under wxMac-2.8.0, wxExecute starts a separate thread - // to wait for child's termination. - // That wxProcessTerminationThread uses a huge amount of processor - // time (about 11% of one CPU on 2GHz Intel Dual-Core Mac). -// m_lBOINCCoreProcessId = ::wxExecute(argv); - run_program( - "/Library/Application Support/BOINC Data", - buf, argv[3] ? 4 : 3, argv, 0.0, m_lBOINCCoreProcessId - ); -#endif - } else { - buf[0] = '\0'; - } - } - -#else // Unix based systems - - // Append boinc.exe to the end of the strExecute string and get ready to rock - strExecute = ::wxGetCwd() + wxT("/boinc --redirectio --launched_by_manager"); -#ifdef SANDBOX - if (!g_use_sandbox) { - strExecute += wxT(" --insecure"); - } -#endif - - wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szExecute '%s'\n"), strExecute.c_str()); - wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szDataDirectory '%s'\n"), ::wxGetCwd().c_str()); - - m_lBOINCCoreProcessId = ::wxExecute(strExecute); - -#endif - - if (0 != m_lBOINCCoreProcessId) { - m_bBOINCStartedByManager = true; - bReturnValue = true; - // Allow time for daemon to start up so we don't keep relaunching it - for (int i=0; i<100; i++) { // Wait up to 1 seccond in 10 ms increments - boinc_sleep(0.01); - if (IsBOINCCoreRunning()) break; - } - } - - wxLogTrace(wxT("Function Start/End"), wxT("CMainDocument::StartupBOINCCore - Function End")); - return bReturnValue; -} - - -#ifdef __WXMSW__ -static tstring downcase_string(tstring& orig) { - tstring retval = orig; - for (size_t i=0; i < retval.length(); i++) { - retval[i] = tolower(retval[i]); - } - return retval; -} - - -void CBOINCClientManager::KillClient() { - ULONG cbBuffer = 128*1024; // 128k initial buffer - PVOID pBuffer = NULL; - PSYSTEM_PROCESSES pProcesses = NULL; - - if (m_hBOINCCoreProcess != NULL) { - kill_program(m_hBOINCCoreProcess); - return; - } - - // Get a snapshot of the process and thread information. - diagnostics_get_process_information(&pBuffer, &cbBuffer); - - // Lets start walking the structures to find the good stuff. - pProcesses = (PSYSTEM_PROCESSES)pBuffer; - do { - if (pProcesses->ProcessId) { - tstring strProcessName = pProcesses->ProcessName.Buffer; - if (downcase_string(strProcessName) == tstring(_T("boinc.exe"))) { - TerminateProcessById(pProcesses->ProcessId); - break; - } - } - - // Move to the next structure if one exists - if (!pProcesses->NextEntryDelta) { - break; - } - pProcesses = (PSYSTEM_PROCESSES)(((LPBYTE)pProcesses) + pProcesses->NextEntryDelta); - } while (pProcesses); - - // Release resources - if (pBuffer) HeapFree(GetProcessHeap(), NULL, pBuffer); -} - -#else - -static char * PersistentFGets(char *buf, size_t buflen, FILE *f) { - char *p = buf; - size_t len = buflen; - size_t datalen = 0; - - *buf = '\0'; - while (datalen < (buflen - 1)) { - fgets(p, len, f); - if (feof(f)) break; - if (ferror(f) && (errno != EINTR)) break; - if (strchr(buf, '\n')) break; - datalen = strlen(buf); - p = buf + datalen; - len -= datalen; - } - return (buf[0] ? buf : NULL); -} - - -// On Mac, wxProcess::Exists returns true for zombies -// because kill(pid, 0) returns OK for zombies -// If we don't have a pid, searches by name. -void CBOINCClientManager::KillClient() { - FILE *f; - char buf[1024]; - char name[] = "boinc"; - size_t n = strlen(name); - char *bufp; - pid_t apPID; - - if (m_lBOINCCoreProcessId) { - kill_program(m_lBOINCCoreProcessId); - return; - } - - // ToDo: the following command line works properly on Mac - // and on Ubuntu (under VMWare) but needs testing on other - // UNIX and Linux platforms. We want a command that lists - // processes (including boinc) in 2 columns: executable - // name only (not the entire command line)starting in column 1 - // and pid. So the line showing boinc would look like this: - // boinc 1234 - f = popen("ps -a -x -c -o command,pid", "r"); - if (f == NULL) - return; - - while (PersistentFGets(buf, sizeof(buf), f)) - { - if (strncmp(buf, name, n) == 0) - { - bufp = buf+n-1; - while (*++bufp == ' '); // Skip over white space - apPID = atol(bufp); - kill_program(apPID); - break; - } - } - pclose(f); -} -#endif - - -void CBOINCClientManager::ShutdownBOINCCore() { - wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::ShutdownBOINCCore - Function Begin")); - - CMainDocument* pDoc = wxGetApp().GetDocument(); - wxInt32 iCount = 0; - bool bClientQuit = false; - wxString strConnectedCompter = wxEmptyString; - wxString strPassword = wxEmptyString; - - wxASSERT(pDoc); - wxASSERT(wxDynamicCast(pDoc, CMainDocument)); - - if (m_bBOINCStartedByManager) { -#ifdef __WXMSW__ - if (IsBOINCConfiguredAsDaemon()) { - StopBOINCService(); - bClientQuit = true; - } else -#endif - { - pDoc->GetConnectedComputerName(strConnectedCompter); - if (!pDoc->IsComputerNameLocal(strConnectedCompter)) { - RPC_CLIENT rpc; - if (!rpc.init("localhost")) { - pDoc->m_pNetworkConnection->GetLocalPassword(strPassword); - rpc.authorize((const char*)strPassword.mb_str()); - if (IsBOINCCoreRunning()) { - rpc.quit(); - for (iCount = 0; iCount <= 10; iCount++) { - if (!bClientQuit && !IsBOINCCoreRunning()) { - wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - (localhost) Application Exit Detected")); - bClientQuit = true; - break; - } - wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - (localhost) Application Exit NOT Detected, Sleeping...")); - ::wxSleep(1); - } - } else { - bClientQuit = true; - } - } - rpc.close(); - } else { - if (IsBOINCCoreRunning()) { - pDoc->CoreClientQuit(); - for (iCount = 0; iCount <= 10; iCount++) { - if (!bClientQuit && !IsBOINCCoreRunning()) { - wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - Application Exit Detected")); - bClientQuit = true; - break; - } - wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - Application Exit NOT Detected, Sleeping...")); - ::wxSleep(1); - } - } else { - bClientQuit = true; - } - } - } - - if (!bClientQuit) { - KillClient(); - } - m_lBOINCCoreProcessId = 0; - } - - wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::ShutdownBOINCCore - Function End")); -} +// This file is part of BOINC. +// http://boinc.berkeley.edu +// Copyright (C) 2008 University of California +// +// BOINC 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 3 of the License, or (at your option) any later version. +// +// BOINC 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 BOINC. If not, see . + +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma implementation "BOINCClientManager.h" +#endif + +#include "stdwx.h" +#include "diagnostics.h" +#include "LogBOINC.h" +#include "BOINCGUIApp.h" +#include "MainDocument.h" +#include "BOINCBaseFrame.h" +#include "AdvancedFrame.h" +#include "BOINCClientManager.h" +#include "error_numbers.h" +#include "procinfo.h" + +#include "filesys.h" +#include "util.h" + +#ifdef __WXMAC__ +enum { + NewStyleDaemon = 1, + OldStyleDaemon +}; +#endif + +#ifdef __WXMSW__ +#include "win_util.h" +#include "diagnostics_win.h" + +extern int diagnostics_get_process_information(PVOID* ppBuffer, PULONG pcbBuffer); +EXTERN_C BOOL IsBOINCServiceInstalled(); +EXTERN_C BOOL IsBOINCServiceStarting(); +EXTERN_C BOOL IsBOINCServiceRunning(); +EXTERN_C BOOL IsBOINCServiceStopping(); +EXTERN_C BOOL IsBOINCServiceStopped(); +EXTERN_C BOOL StartBOINCService(); +EXTERN_C BOOL StopBOINCService(); +#endif + +CBOINCClientManager::CBOINCClientManager() { + wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::CBOINCClientManager - Function Begin")); + + m_bBOINCStartedByManager = false; + m_lBOINCCoreProcessId = 0; + +#ifdef __WXMSW__ + m_hBOINCCoreProcess = NULL; +#endif + + wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::CBOINCClientManager - Function End")); +} + + +CBOINCClientManager::~CBOINCClientManager() { + wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::~CBOINCClientManager - Function Begin")); + + wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::~CBOINCClientManager - Function End")); +} + + +bool CBOINCClientManager::AutoRestart() { + if (IsBOINCCoreRunning()) return true; +#ifndef __WXMAC__ // Mac can restart Client as a daemon + if (! m_bBOINCStartedByManager) return false; +#endif + m_lBOINCCoreProcessId = 0; + StartupBOINCCore(); + return true; +} + + +bool CBOINCClientManager::IsSystemBooting() { + bool bReturnValue = false; +#if defined(__WXMSW__) + if (GetTickCount() < (1000*60*5)) bReturnValue = true; // If system has been up for less than 5 minutes +#elif defined(__WXMAC__) + if (TickCount() < (120*60)) bReturnValue = true; // If system has been up for less than 2 minutes +#endif + return bReturnValue; +} + + +int CBOINCClientManager::IsBOINCConfiguredAsDaemon() { + bool bReturnValue = false; +#if defined(__WXMSW__) + if (IsBOINCServiceInstalled()) bReturnValue = 1; +#elif defined(__WXMAC__) + if ( boinc_file_exists("/Library/LaunchDaemons/edu.berkeley.boinc.plist")) { + bReturnValue = NewStyleDaemon; // New-style daemon uses launchd + } + if (boinc_file_exists("/Library/StartupItems/boinc/boinc") ) { + bReturnValue = OldStyleDaemon; // Old-style daemon uses StartupItem + } +#endif + return bReturnValue; +} + + +bool CBOINCClientManager::IsBOINCCoreRunning() { + wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function Begin")); + bool running = false; + +#ifdef __WXMSW__ + char buf[MAX_PATH] = ""; + + if (IsBOINCServiceInstalled()) { + running = (FALSE != IsBOINCServiceStarting()) || (FALSE != IsBOINCServiceRunning()); + } else { + // Global mutex on Win2k and later + // + if (IsWindows2000Compatible()) { + strcpy(buf, "Global\\"); + } + strcat( buf, RUN_MUTEX); + + HANDLE h = CreateMutexA(NULL, true, buf); + DWORD err = GetLastError(); + if ((h==0) || (err == ERROR_ALREADY_EXISTS)) { + running = true; + } + if (h) { + CloseHandle(h); + } + } +#else + char path[1024]; + static FILE_LOCK file_lock; + + sprintf(path, "%s/%s", (char *)wxGetApp().GetDataDirectory().char_str(), LOCK_FILE_NAME); + if (file_lock.lock(path)) { + running = true; + } else { + file_lock.unlock(path); + } +#endif + wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Returning '%d'"), (int)running); + wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::IsBOINCCoreRunning - Function End")); + return running; +} + + +bool CBOINCClientManager::StartupBOINCCore() { + wxLogTrace(wxT("Function Start/End"), wxT("CMainDocument::StartupBOINCCore - Function Begin")); + + bool bReturnValue = false; + wxString strExecute = wxEmptyString; + + if (IsBOINCCoreRunning()) return true; + +#if defined(__WXMSW__) + LPTSTR szExecute = NULL; + LPTSTR szDataDirectory = NULL; + + if (IsBOINCConfiguredAsDaemon()) { + StartBOINCService(); + + m_bBOINCStartedByManager = true; + bReturnValue = IsBOINCCoreRunning(); + } else { + + // Append boinc.exe to the end of the strExecute string and get ready to rock + strExecute.Printf( + wxT("\"%s\\boinc.exe\" --redirectio --launched_by_manager %s"), + wxGetApp().GetRootDirectory().c_str(), + wxGetApp().GetArguments().c_str() + ); + + PROCESS_INFORMATION pi; + STARTUPINFO si; + BOOL bProcessStarted; + + memset(&pi, 0, sizeof(pi)); + memset(&si, 0, sizeof(si)); + + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + + szExecute = (LPTSTR)strExecute.c_str(); + if (wxGetApp().GetDataDirectory().empty()) { + szDataDirectory = NULL; + } else { + szDataDirectory = (LPTSTR)wxGetApp().GetDataDirectory().c_str(); + } + + wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szExecute '%s'\n"), szExecute); + wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szDataDirectory '%s'\n"), szDataDirectory); + + bProcessStarted = CreateProcess( + NULL, + szExecute, + NULL, + NULL, + FALSE, + CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW, + NULL, + szDataDirectory, + &si, + &pi + ); + + if (bProcessStarted) { + m_lBOINCCoreProcessId = pi.dwProcessId; + m_hBOINCCoreProcess = pi.hProcess; + } + } + +#elif defined(__WXMAC__) + +#if 0 // The Mac version of wxExecute(wxString& ...) crashes if there is a space in the path + wxChar buf[1024]; + wxChar *argv[5]; +#else + char buf[1024]; + char *argv[5]; +#endif + ProcessSerialNumber ourPSN; + FSRef ourFSRef; + OSErr err; + + if (IsBOINCConfiguredAsDaemon() == NewStyleDaemon) { + system ("launchctl load /Library/LaunchDaemons/edu.berkeley.boinc.plist"); + system ("launchctl start edu.berkeley.boinc"); + bReturnValue = IsBOINCCoreRunning(); + } else { + + // Get the full path to core client inside this application's bundle + err = GetCurrentProcess (&ourPSN); + if (err == noErr) { + err = GetProcessBundleLocation(&ourPSN, &ourFSRef); + } + if (err == noErr) { + err = FSRefMakePath (&ourFSRef, (UInt8*)buf, sizeof(buf)); + } + if (err == noErr) { +#if 0 // The Mac version of wxExecute(wxString& ...) crashes if there is a space in the path + strExecute = wxT("\""); + strExecute += wxT(buf); + strExecute += wxT("/Contents/Resources/boinc\" --redirectio --launched_by_manager"); + m_lBOINCCoreProcessId = ::wxExecute(strExecute); +#else // Use wxExecute(wxChar **argv ...) instead of wxExecute(wxString& ...) + strcat(buf, "/Contents/Resources/boinc"); + argv[0] = buf; + argv[1] = "--redirectio"; + argv[2] = "--launched_by_manager"; + argv[3] = NULL; +#ifdef SANDBOX + if (!g_use_sandbox) { + argv[3] = "--insecure"; + argv[4] = NULL; + } +#endif + // Under wxMac-2.8.0, wxExecute starts a separate thread + // to wait for child's termination. + // That wxProcessTerminationThread uses a huge amount of processor + // time (about 11% of one CPU on 2GHz Intel Dual-Core Mac). +// m_lBOINCCoreProcessId = ::wxExecute(argv); + run_program( + "/Library/Application Support/BOINC Data", + buf, argv[3] ? 4 : 3, argv, 0.0, m_lBOINCCoreProcessId + ); +#endif + } else { + buf[0] = '\0'; + } + } + +#else // Unix based systems + + // Append boinc.exe to the end of the strExecute string and get ready to rock + strExecute = ::wxGetCwd() + wxT("/boinc --redirectio --launched_by_manager"); +#ifdef SANDBOX + if (!g_use_sandbox) { + strExecute += wxT(" --insecure"); + } +#endif + + wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szExecute '%s'\n"), strExecute.c_str()); + wxLogTrace(wxT("Function Status"), wxT("CMainDocument::StartupBOINCCore - szDataDirectory '%s'\n"), ::wxGetCwd().c_str()); + + m_lBOINCCoreProcessId = ::wxExecute(strExecute); + +#endif + + if (0 != m_lBOINCCoreProcessId) { + m_bBOINCStartedByManager = true; + bReturnValue = true; + // Allow time for daemon to start up so we don't keep relaunching it + for (int i=0; i<100; i++) { // Wait up to 1 seccond in 10 ms increments + boinc_sleep(0.01); + if (IsBOINCCoreRunning()) break; + } + } + + wxLogTrace(wxT("Function Start/End"), wxT("CMainDocument::StartupBOINCCore - Function End")); + return bReturnValue; +} + + +#ifdef __WXMSW__ +static tstring downcase_string(tstring& orig) { + tstring retval = orig; + for (size_t i=0; i < retval.length(); i++) { + retval[i] = tolower(retval[i]); + } + return retval; +} + + +void CBOINCClientManager::KillClient() { + ULONG cbBuffer = 128*1024; // 128k initial buffer + PVOID pBuffer = NULL; + PSYSTEM_PROCESSES pProcesses = NULL; + + if (m_hBOINCCoreProcess != NULL) { + kill_program(m_hBOINCCoreProcess); + return; + } + + // Get a snapshot of the process and thread information. + diagnostics_get_process_information(&pBuffer, &cbBuffer); + + // Lets start walking the structures to find the good stuff. + pProcesses = (PSYSTEM_PROCESSES)pBuffer; + do { + if (pProcesses->ProcessId) { + tstring strProcessName = pProcesses->ProcessName.Buffer; + if (downcase_string(strProcessName) == tstring(_T("boinc.exe"))) { + TerminateProcessById(pProcesses->ProcessId); + break; + } + } + + // Move to the next structure if one exists + if (!pProcesses->NextEntryDelta) { + break; + } + pProcesses = (PSYSTEM_PROCESSES)(((LPBYTE)pProcesses) + pProcesses->NextEntryDelta); + } while (pProcesses); + + // Release resources + if (pBuffer) HeapFree(GetProcessHeap(), NULL, pBuffer); +} + +#else + +void CBOINCClientManager::KillClient() { + std::vector piv; + int retval; + + if (m_lBOINCCoreProcessId) { + kill_program(m_lBOINCCoreProcessId); + return; + } + + retval = procinfo_setup(piv); + if (retval) return; // Should never happen + + for (unsigned int i=0; iGetConnectedComputerName(strConnectedCompter); + if (!pDoc->IsComputerNameLocal(strConnectedCompter)) { + RPC_CLIENT rpc; + if (!rpc.init("localhost")) { + pDoc->m_pNetworkConnection->GetLocalPassword(strPassword); + rpc.authorize((const char*)strPassword.mb_str()); + if (IsBOINCCoreRunning()) { + rpc.quit(); + for (iCount = 0; iCount <= 10; iCount++) { + if (!bClientQuit && !IsBOINCCoreRunning()) { + wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - (localhost) Application Exit Detected")); + bClientQuit = true; + break; + } + wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - (localhost) Application Exit NOT Detected, Sleeping...")); + ::wxSleep(1); + } + } else { + bClientQuit = true; + } + } + rpc.close(); + } else { + if (IsBOINCCoreRunning()) { + pDoc->CoreClientQuit(); + for (iCount = 0; iCount <= 10; iCount++) { + if (!bClientQuit && !IsBOINCCoreRunning()) { + wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - Application Exit Detected")); + bClientQuit = true; + break; + } + wxLogTrace(wxT("Function Status"), wxT("CBOINCClientManager::ShutdownBOINCCore - Application Exit NOT Detected, Sleeping...")); + ::wxSleep(1); + } + } else { + bClientQuit = true; + } + } + } + + if (!bClientQuit) { + KillClient(); + } + m_lBOINCCoreProcessId = 0; + } + + wxLogTrace(wxT("Function Start/End"), wxT("CBOINCClientManager::ShutdownBOINCCore - Function End")); +} diff --git a/clientscr/res/boinc.jpg b/clientscr/res/boinc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..556968a5f644494ac4f63163144ced945b231800 GIT binary patch literal 19958 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 pi) { FILE* fd; PROCINFO p; int c, real_mem, virtual_mem, hours; + char* lf; #if SHOW_TIMING UnsignedWide start, end, elapsed; @@ -101,6 +102,8 @@ int procinfo_setup(vector& pi) { &virtual_mem, &p.page_fault_count, &hours, &p.user_time); if (c < 7) break; if (fgets(p.command, sizeof(p.command) , fd) == NULL) break; + lf = strchr(p.command, '\n'); + if (lf) *lf = '\0'; // Strip trailing linefeed p.working_set_size = (double)real_mem * 1024.; p.swap_size = (double)virtual_mem * 1024.; p.user_time += 60. * (float)hours; diff --git a/mac_build/boinc.xcodeproj/project.pbxproj b/mac_build/boinc.xcodeproj/project.pbxproj index 2e09c79938..50246b9b5d 100755 --- a/mac_build/boinc.xcodeproj/project.pbxproj +++ b/mac_build/boinc.xcodeproj/project.pbxproj @@ -245,6 +245,7 @@ DD8917F60F3B21EF00DE5B1C /* texture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD4EC60F08A0A083009AA08F /* texture.cpp */; }; DD8917F80F3B21F500DE5B1C /* txf_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD65020809F599B9008E8A3A /* txf_util.cpp */; }; DD9AB0340EB7D5DE00AF1616 /* rr_sim.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD9AB0320EB7D5DE00AF1616 /* rr_sim.cpp */; }; + DDA0C8350FE1D704001E02E6 /* procinfo_mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB6934F0ABFE9C600689FD8 /* procinfo_mac.cpp */; }; DDA12A6D0A36974600FBDD12 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD1929D80918A2F100C31BCF /* Security.framework */; }; DDA12AA20A369B5500FBDD12 /* SetupSecurity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD7748B40A356D6C0025D05E /* SetupSecurity.cpp */; }; DDA12AAE0A369C5800FBDD12 /* SecurityUtility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA12AAD0A369C5800FBDD12 /* SecurityUtility.cpp */; }; @@ -2404,6 +2405,7 @@ DDDE43B10EC04C1800083520 /* DlgExitMessage.cpp in Sources */, DDC836E60EDEA5DB001C2EF9 /* TermsOfUsePage.cpp in Sources */, DD377E090F6F95650089CE9A /* ViewNews.cpp in Sources */, + DDA0C8350FE1D704001E02E6 /* procinfo_mac.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };