int main(int argc, char *argv[]) { int exitcode = EXIT_FAILURE; init_early_config(argc, argv, BB_RUN_APP); /* Setup signal handling before anything else */ signal(SIGHUP, handle_signal); signal(SIGTERM, handle_signal); signal(SIGINT, handle_signal); signal(SIGQUIT, handle_signal); bb_init_log(); /* Initializing configuration */ init_config(argc, argv); bbconfig_parse_opts(argc, argv, PARSE_STAGE_PRECONF); GKeyFile *bbcfg = bbconfig_parse_conf(); /* XXX load the driver (or even better, the ldpath) through the protocol */ bbconfig_parse_opts(argc, argv, PARSE_STAGE_DRIVER); driver_detect(); if (bbcfg) { bbconfig_parse_conf_driver(bbcfg, bb_config.driver); g_key_file_free(bbcfg); } bbconfig_parse_opts(argc, argv, PARSE_STAGE_OTHER); config_dump(); bb_log(LOG_DEBUG, "%s version %s starting...\n", "optirun", GITVERSION); /* Connect to listening daemon */ bb_status.bb_socket = socketConnect(bb_config.socket_path, SOCK_NOBLOCK); if (bb_status.bb_socket < 0) { bb_log(LOG_ERR, "Could not connect to bumblebee daemon - is it running?\n"); run_fallback(argv + optind); bb_closelog(); return exitcode; } /* Request status */ if (bb_status.runmode == BB_RUN_STATUS) { exitcode = report_daemon_status(); } /* Run given application */ if (bb_status.runmode == BB_RUN_APP) { if (optind >= argc) { bb_log(LOG_ERR, "Missing argument: application to run\n"); print_usage(EXIT_FAILURE); } else { exitcode = run_app(argc, argv); } } bb_closelog(); bb_stop_all(); //stop any started processes that are left return exitcode; }
/** * Starts a program with Bumblebee if possible * * @param argc The number of arguments * @param argv The values of arguments * @return The exitcode of the program on success, EXIT_FAILURE if the program * could not be started */ static int run_app(int argc, char *argv[]) { int exitcode = EXIT_FAILURE; char buffer[BUFFER_SIZE]; int r; int ranapp = 0; r = snprintf(buffer, BUFFER_SIZE, "Checking availability..."); socketWrite(&bb_status.bb_socket, buffer, r + 1); while (bb_status.bb_socket != -1) { r = socketRead(&bb_status.bb_socket, buffer, BUFFER_SIZE); if (r > 0) { bb_log(LOG_INFO, "Response: %s\n", buffer); switch (buffer[0]) { case 'N': //No, run normally. bb_log(LOG_ERR, "Cannot access secondary GPU%s\n", buffer+2); socketClose(&bb_status.bb_socket); if (!bb_config.fallback_start) { bb_log(LOG_ERR, "Aborting because fallback start is disabled.\n"); } break; case 'Y': //Yes, run through vglrun bb_log(LOG_INFO, "Running application through vglrun.\n"); ranapp = 1; //run vglclient if any method other than proxy is used if (strncmp(bb_config.vgl_compress, "proxy", BUFFER_SIZE) != 0) { char * vglclient_args[] = { "vglclient", "-detach", 0 }; bb_run_fork(vglclient_args, 1); } /* number of options passed to --vgl-options */ unsigned int vglrun_opts_count = 0; char *next_arg = bb_config.vglrun_options; /* read vglrun options only if there is an arguments list */ if (next_arg && next_arg[0]) { do { ++vglrun_opts_count; } while ((next_arg = strchr(next_arg + 1, ' '))); } /* position of next option */ unsigned int optno = 0; /* 7 for the first options, 1 for the -- and 1 for the trailing 0 */ char ** vglrun_args = malloc(sizeof (char *) * (9 + vglrun_opts_count + argc - optind)); vglrun_args[0] = "vglrun"; vglrun_args[1] = "-c"; vglrun_args[2] = bb_config.vgl_compress; vglrun_args[3] = "-d"; vglrun_args[4] = bb_config.x_display; vglrun_args[5] = "-ld"; vglrun_args[6] = bb_config.ld_path; optno = 7; next_arg = bb_config.vglrun_options; if (next_arg && next_arg[0]) { char *current_arg; do { current_arg = next_arg; next_arg = strchr(current_arg, ' '); /* cut the string if a space is found */ if (next_arg) { *next_arg = 0; /* the next argument starts at the position after the space */ next_arg++; } vglrun_args[optno++] = current_arg; } while (next_arg); } vglrun_args[optno++] = "--"; for (r = 0; r < argc - optind; r++) { vglrun_args[r + optno] = argv[optind + r]; } vglrun_args[optno+=r] = 0; exitcode = bb_run_fork(vglrun_args, 0); free(vglrun_args); socketClose(&bb_status.bb_socket); break; default: //Something went wrong - output and exit. bb_log(LOG_ERR, "Problem: %*s\n", r, buffer); socketClose(&bb_status.bb_socket); break; } } } if (!ranapp) { exitcode = run_fallback(argv + optind); } return exitcode; }
int main(int argc, char *argv[]) { int exitcode = EXIT_FAILURE; init_early_config(argc, argv, BB_RUN_APP); /* Setup signal handling before anything else */ signal(SIGHUP, handle_signal); signal(SIGTERM, handle_signal); signal(SIGINT, handle_signal); signal(SIGQUIT, handle_signal); bb_init_log(); /* Initializing configuration */ init_config(argc, argv); bbconfig_parse_opts(argc, argv, PARSE_STAGE_PRECONF); __unused GKeyFile *bbcfg = bbconfig_parse_conf(); /* Connect to listening daemon */ bb_status.bb_socket = socketConnect(bb_config.socket_path, SOCK_BLOCK); if (bb_status.bb_socket < 0) { bb_log(LOG_ERR, "Could not connect to bumblebee daemon - is it running?\n"); run_fallback(argv + optind); bb_closelog(); return exitcode; } free_and_set_value(&bb_config.ld_path, malloc(BUFFER_SIZE)); if (bbsocket_query("LibraryPath", bb_config.ld_path, BUFFER_SIZE)) { bb_log(LOG_ERR, "Failed to retrieve LibraryPath setting.\n"); return EXIT_FAILURE; } free_and_set_value(&bb_config.x_display, malloc(BUFFER_SIZE)); if (bbsocket_query("VirtualDisplay", bb_config.x_display, BUFFER_SIZE)) { bb_log(LOG_ERR, "Failed to retrieve VirtualDisplay setting.\n"); return EXIT_FAILURE; } /* parse remaining common and optirun-specific options */ bbconfig_parse_opts(argc, argv, PARSE_STAGE_OTHER); bb_log(LOG_DEBUG, "%s version %s starting...\n", "optirun", GITVERSION); config_dump(); /* Request status */ if (bb_status.runmode == BB_RUN_STATUS) { exitcode = report_daemon_status(); } /* Run given application */ if (bb_status.runmode == BB_RUN_APP) { if (optind >= argc) { bb_log(LOG_ERR, "Missing argument: application to run\n"); print_usage(EXIT_FAILURE); } else { exitcode = run_app(argc, argv); } } bb_closelog(); bb_stop_all(); //stop any started processes that are left return exitcode; }