int main(int argc, char** argv) { int retval = 0; coprocs.set_path_to_client(argv[0]); // Used to launch a child process for --detect_gpus for (int index = 1; index < argc; index++) { if (strcmp(argv[index], "-daemon") == 0 || strcmp(argv[index], "--daemon") == 0) { gstate.executing_as_daemon = true; log_message_startup("BOINC is initializing..."); #if !defined(_WIN32) && !defined(__EMX__) && !defined(__APPLE__) // from <unistd.h>: // Detach from the controlling terminal and run in the background // as system daemon. // Don't change working directory to root ("/"), but redirect // standard input, standard output and standard error to /dev/null. // retval = daemon(1, 0); break; #endif } if (!strcmp(argv[index], "--detect_gpus")) { do_gpu_detection(argc, argv); return 0; } if (!strcmp(argv[index], "--run_test_app")) { read_config_file(true); run_test_app(); } #ifdef _WIN32 // This bit of silliness is required to properly detach when run from within a command // prompt under Win32. The root cause of the problem is that CMD.EXE does not return // control to the user until the spawned program exits, detaching from the console is // not enough. So we need to do the following. If the -detach flag is given, trap it // prior to the main setup in init_core_client. Reinvoke the program, changing the // -detach into -detach_phase_two, and then exit. At this point, cmd.exe thinks all is // well, and returns control to the user. Meanwhile the second invocation will grok the // -detach_phase_two flag, and detach itself from the console, finally getting us to // where we want to be. // FIXME FIXME. Duplicate instances of -detach may cause this to be // executed unnecessarily. At worst, I think it leads to a few extra // processes being created and destroyed. if (strcmp(argv[index], "-detach") == 0 || strcmp(argv[index], "--detach") == 0 || strcmp(argv[index], "-detach_console") == 0 || strcmp(argv[index], "--detach_console") == 0 ) { int i, len; char *commandLine; STARTUPINFO si; PROCESS_INFORMATION pi; argv[index] = "-detach_phase_two"; // start with space for two '"'s len = 2; for (i = 0; i < argc; i++) { len += (int)strlen(argv[i]) + 1; } if ((commandLine = (char *) malloc(len)) == NULL) { // Drop back ten and punt. Can't do the detach thing, so we just carry on. // At least the program will start. break; } commandLine[0] = '"'; // OK, we can safely use strcpy and strcat, since we know that we allocated enough strlcpy(&commandLine[1], argv[0], len); strlcat(commandLine, "\"", len); for (i = 1; i < argc; i++) { strlcat(commandLine, " ", len); strlcat(commandLine, argv[i], len); } memset(&si, 0, sizeof(si)); si.cb = sizeof(si); // If process creation succeeds, we exit, if it fails punt and continue // as usual. We won't detach properly, but the program will run. if (CreateProcess(NULL, commandLine, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { exit(0); } break; } #endif } init_core_client(argc, argv); #ifdef _WIN32 retval = initialize_system_monitor(argc, argv); if (retval) return retval; if ( (argc > 1) && (strcmp(argv[1], "-daemon") == 0 || strcmp(argv[1], "--daemon") == 0) ) { retval = initialize_service_dispatcher(argc, argv); } else { retval = boinc_main_loop(); } #else #ifdef SANDBOX // Make sure owners, groups and permissions are correct // for the current setting of g_use_sandbox // #if defined(_DEBUG) && defined(__APPLE__) // GDB can't attach to applications which are running as a different user // or group, so fix up data with current user and group during debugging // if (check_security(g_use_sandbox, false, NULL, 0)) { SetBOINCDataOwnersGroupsAndPermissions(); } #endif // _DEBUG && __APPLE__ int securityErr = check_security(g_use_sandbox, false, NULL, 0); if (securityErr) { printf( "File ownership or permissions are set in a way that\n" "does not allow sandboxed execution of BOINC applications.\n" "To use BOINC anyway, use the -insecure command line option.\n" "To change ownership/permission, reinstall BOINC" #ifdef __APPLE__ " or run\n the shell script Mac_SA_Secure.sh" #else " or run\n the shell script secure.sh" #endif ". (Error code %d)\n", securityErr ); return ERR_USER_PERMISSION; } #endif // SANDBOX retval = boinc_main_loop(); #endif return retval; }
int main(int argc, char** argv) { int retval = 0; coprocs.set_path_to_client(argv[0]); // Used to launch a child process for --detect_gpus for (int index = 1; index < argc; index++) { if (strcmp(argv[index], "-daemon") == 0 || strcmp(argv[index], "--daemon") == 0) { gstate.executing_as_daemon = true; log_message_startup("BOINC is initializing..."); #if !defined(_WIN32) && !defined(__EMX__) && !defined(__APPLE__) // from <unistd.h>: // Detach from the controlling terminal and run in the background // as system daemon. // Don't change working directory to root ("/"), but redirect // standard input, standard output and standard error to /dev/null. // retval = daemon(1, 0); break; #endif } if (!strcmp(argv[index], "--detect_gpus")) { do_gpu_detection(argc, argv); return 0; } if (!strcmp(argv[index], "--run_test_app")) { read_config_file(true); run_test_app(); } #ifdef _WIN32 // This bit of silliness is required to properly detach when run from within a command // prompt under Win32. The root cause of the problem is that CMD.EXE does not return // control to the user until the spawned program exits, detaching from the console is // not enough. So we need to do the following. If the -detach flag is given, trap it // prior to the main setup in init_core_client. Reinvoke the program, changing the // -detach into -detach_phase_two, and then exit. At this point, cmd.exe thinks all is // well, and returns control to the user. Meanwhile the second invocation will grok the // -detach_phase_two flag, and detach itself from the console, finally getting us to // where we want to be. // FIXME FIXME. Duplicate instances of -detach may cause this to be // executed unnecessarily. At worst, I think it leads to a few extra // processes being created and destroyed. if (strcmp(argv[index], "-detach") == 0 || strcmp(argv[index], "--detach") == 0 || strcmp(argv[index], "-detach_console") == 0 || strcmp(argv[index], "--detach_console") == 0 ) { int i, len=1024; char commandLine[1024]; STARTUPINFO si; PROCESS_INFORMATION pi; argv[index] = "-detach_phase_two"; sprintf(commandLine, "\"%s\"", CLIENT_EXEC_FILENAME); for (i = 1; i < argc; i++) { strlcat(commandLine, " ", len); strlcat(commandLine, argv[i], len); } memset(&si, 0, sizeof(si)); si.cb = sizeof(si); // If process creation succeeds, we exit, if it fails punt and continue // as usual. We won't detach properly, but the program will run. if (CreateProcess(NULL, commandLine, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { exit(0); } break; } #endif } init_core_client(argc, argv); #ifdef _WIN32 retval = initialize_system_monitor(argc, argv); if (retval) return retval; if ( (argc > 1) && (strcmp(argv[1], "-daemon") == 0 || strcmp(argv[1], "--daemon") == 0) ) { retval = initialize_service_dispatcher(argc, argv); } else { retval = boinc_main_loop(); } #else #ifdef SANDBOX // Make sure owners, groups and permissions are correct // for the current setting of g_use_sandbox // // NOTE: GDB and LLDB can't attach to applications which are running as // a different user or group. // Normally, the Mac Development (Debug) builds do not define SANDBOX, so // check_security() is never called. However, it is possible to use GDB // or LLDB on sandbox-specific code, as long as the code is run as the // current user (i.e., not as boinc_master or boinc_project), and the // current user is a member of both groups boinc_master and boinc_project. // However, this has not been thoroughly tested. Please see the comments // in SetupSecurity.cpp and check_security.cpp for more details. int securityErr = check_security(g_use_sandbox, false, NULL, 0); if (securityErr) { #if (defined(__APPLE__) && defined (_DEBUG)) printf( "To debug with sandbox security enabled, the current user\n" "must be a member of both groups boinc_master and boinc_project." ); #else // ! (defined(__APPLE__) && defined (_DEBUG)) printf( "File ownership or permissions are set in a way that\n" "does not allow sandboxed execution of BOINC applications.\n" "To use BOINC anyway, use the -insecure command line option.\n" "To change ownership/permission, reinstall BOINC" #ifdef __APPLE__ " or run\n the shell script Mac_SA_Secure.sh" #else " or run\n the shell script secure.sh" #endif ". (Error code %d)\n", securityErr ); #endif // ! (defined(__APPLE__) && defined (_DEBUG)) return ERR_USER_PERMISSION; } #endif // SANDBOX retval = boinc_main_loop(); #endif return retval; }