int main(int argc, char *argv[]) { const char *app_type = NULL; int prog_argc = 0; uint32_t magic_options = 0; bool wait_term = true; unsigned int delay = EXIT_DELAY; unsigned int respawn_delay = RESPAWN_DELAY; char **prog_argv = NULL; char *prog_name = NULL; char *splash_file = NULL; char *landscape_splash_file = NULL; struct stat file_stat; bool test_mode = false; // wait-term parameter by default magic_options |= INVOKER_MSG_MAGIC_OPTION_WAIT; // Called with a different name (old way of using invoker) ? if (!strstr(argv[0], PROG_NAME_INVOKER) ) { die(1, "Incorrect use of invoker, don't use symlinks. " "Run invoker explicitly from e.g. a D-Bus service file instead.\n"); } // Stops parsing args as soon as a non-option argument is encountered putenv("POSIXLY_CORRECT=1"); // Options recognized struct option longopts[] = { {"help", no_argument, NULL, 'h'}, {"wait-term", no_argument, NULL, 'w'}, {"no-wait", no_argument, NULL, 'n'}, {"global-syms", no_argument, NULL, 'G'}, {"deep-syms", no_argument, NULL, 'D'}, {"single-instance", no_argument, NULL, 's'}, {"daemon-mode", no_argument, NULL, 'o'}, {"test-mode", no_argument, NULL, 'T'}, {"type", required_argument, NULL, 't'}, {"delay", required_argument, NULL, 'd'}, {"respawn", required_argument, NULL, 'r'}, {"splash", required_argument, NULL, 'S'}, {"splash-landscape", required_argument, NULL, 'L'}, {0, 0, 0, 0} }; // Parse options // TODO: Move to a function int opt; while ((opt = getopt_long(argc, argv, "hcwnGDsoTd:t:r:S:L:", longopts, NULL)) != -1) { switch(opt) { case 'h': usage(0); break; case 'w': // nothing to do, it's by default now break; case 'o': magic_options |= INVOKER_MSG_MAGIC_OPTION_OOM_ADJ_DISABLE; break; case 'n': wait_term = false; magic_options &= (~INVOKER_MSG_MAGIC_OPTION_WAIT); break; case 'G': magic_options |= INVOKER_MSG_MAGIC_OPTION_DLOPEN_GLOBAL; break; case 'D': magic_options |= INVOKER_MSG_MAGIC_OPTION_DLOPEN_DEEP; break; case 'T': test_mode = true; break; case 't': app_type = optarg; break; case 'd': delay = get_delay(optarg, "delay", MIN_EXIT_DELAY, MAX_EXIT_DELAY); break; case 'r': respawn_delay = get_delay(optarg, "respawn delay", MIN_RESPAWN_DELAY, MAX_RESPAWN_DELAY); break; case 's': magic_options |= INVOKER_MSG_MAGIC_OPTION_SINGLE_INSTANCE; break; case 'S': magic_options |= INVOKER_MSG_MAGIC_OPTION_SPLASH_SCREEN; splash_file = optarg; break; case 'L': magic_options |= INVOKER_MSG_MAGIC_OPTION_LANDSCAPE_SPLASH_SCREEN; landscape_splash_file = optarg; break; case '?': usage(1); } } // Option processing stops as soon as application name is encountered if (optind < argc) { prog_name = search_program(argv[optind]); prog_argc = argc - optind; prog_argv = &argv[optind]; } // Check if application name isn't defined if (!prog_name) { report(report_error, "Application's name is not defined.\n"); usage(1); } // Check if application exists if (stat(prog_name, &file_stat)) { report(report_error, "%s: not found\n", prog_name); return EXIT_STATUS_APPLICATION_NOT_FOUND; } // Check that if (!S_ISREG(file_stat.st_mode) && !S_ISLNK(file_stat.st_mode)) { report(report_error, "%s: not a file\n", prog_name); return EXIT_STATUS_APPLICATION_NOT_FOUND; } if (!app_type) { report(report_error, "Application type must be specified with --type.\n"); usage(1); } // Translate 'qt' and 'm' types to 'q' for compatibility if (!strcmp(app_type, "qt") || !strcmp(app_type, "m")) app_type = "q"; // Check if application type is unknown. Only accept one character types. if (!app_type[0] || app_type[1]) { report(report_error, "Application's type is unknown.\n"); usage(1); } if (pipe(g_signal_pipe) == -1) { report(report_error, "Creating a pipe for Unix signals failed!\n"); exit(EXIT_FAILURE); } // Send commands to the launcher daemon info("Invoking execution: '%s'\n", prog_name); int ret_val = invoke(prog_argc, prog_argv, prog_name, *app_type, magic_options, wait_term, respawn_delay, splash_file, landscape_splash_file, test_mode); // Sleep for delay before exiting if (delay) { // DBUS cannot cope some times if the invoker exits too early. debug("Delaying exit for %d seconds..\n", delay); sleep(delay); } return ret_val; }
int main(int argc, char *argv[]) { enum APP_TYPE app_type = UNKNOWN_APP; int prog_argc = 0; uint32_t magic_options = 0; bool wait_term = true; unsigned int delay = DEFAULT_DELAY; unsigned int respawn_delay = RESPAWN_DELAY; char **prog_argv = NULL; char *prog_name = NULL; struct stat file_stat; // wait-term parameter by default magic_options |= INVOKER_MSG_MAGIC_OPTION_WAIT; // Called with a different name (old way of using invoker) ? if (!strstr(argv[0], PROG_NAME_INVOKER) ) { die(1, "Incorrect use of invoker, don't use symlinks. " "Run invoker explicitly from e.g. a D-Bus service file instead.\n"); } // Stops parsing args as soon as a non-option argument is encountered putenv("POSIXLY_CORRECT=1"); // Options recognized struct option longopts[] = { {"help", no_argument, NULL, 'h'}, {"creds", no_argument, NULL, 'c'}, {"wait-term", no_argument, NULL, 'w'}, {"no-wait", no_argument, NULL, 'n'}, {"global-syms", no_argument, NULL, 'G'}, {"deep-syms", no_argument, NULL, 'D'}, {"single-instance", no_argument, NULL, 's'}, {"type", required_argument, NULL, 't'}, {"delay", required_argument, NULL, 'd'}, {"respawn", required_argument, NULL, 'r'}, {0, 0, 0, 0} }; // Parse options // TODO: Move to a function int opt; while ((opt = getopt_long(argc, argv, "hcwnGDsd:t:r:", longopts, NULL)) != -1) { switch(opt) { case 'h': usage(0); break; case 'c': show_credentials(); break; case 'w': // nothing to do, it's by default now break; case 'n': wait_term = false; magic_options &= (~INVOKER_MSG_MAGIC_OPTION_WAIT); break; case 'G': magic_options |= INVOKER_MSG_MAGIC_OPTION_DLOPEN_GLOBAL; break; case 'D': magic_options |= INVOKER_MSG_MAGIC_OPTION_DLOPEN_DEEP; break; case 't': if (strcmp(optarg, "m") == 0) app_type = M_APP; else if (strcmp(optarg, "q") == 0 || strcmp(optarg, "qt") == 0) app_type = QT_APP; else if (strcmp(optarg, "d") == 0) app_type = QDECL_APP; else { report(report_error, "Unknown application type: %s \n", optarg); usage(1); } break; case 'd': delay = get_delay(optarg, "delay"); break; case 'r': respawn_delay = get_delay(optarg, "respawn delay"); if (respawn_delay > MAX_RESPAWN_DELAY) { report(report_error, "Booster respawn delay exceeds max possible time.\n"); usage(1); } break; case 's': magic_options |= INVOKER_MSG_MAGIC_OPTION_SINGLE_INSTANCE; break; case '?': usage(1); } } // Option processing stops as soon as application name is encountered if (optind < argc) { prog_name = search_program(argv[optind]); if (!prog_name) { report(report_error, "Can't find application to invoke.\n"); usage(0); } prog_argc = argc - optind; prog_argv = &argv[optind]; } // Check if application name isn't defined if (!prog_name) { report(report_error, "Application's name is not defined.\n"); usage(1); } // Check if application exists if (stat(prog_name, &file_stat)) { report(report_error, "%s: not found\n", prog_name); return EXIT_STATUS_APPLICATION_NOT_FOUND; } // Check that if (!S_ISREG(file_stat.st_mode) && !S_ISLNK(file_stat.st_mode)) { report(report_error, "%s: not a file\n", prog_name); return EXIT_STATUS_APPLICATION_NOT_FOUND; } // Check if application type is unknown if (app_type == UNKNOWN_APP) { report(report_error, "Application's type is unknown.\n"); usage(1); } // Send commands to the launcher daemon info("Invoking execution: '%s'\n", prog_name); int ret_val = invoke(prog_argc, prog_argv, prog_name, app_type, magic_options, wait_term, respawn_delay); // Sleep for delay before exiting if (delay) { // DBUS cannot cope some times if the invoker exits too early. debug("Delaying exit for %d seconds..\n", delay); sleep(delay); } return ret_val; }
int main(int argc, char *argv[]) { const char *app_type = NULL; int prog_argc = 0; uint32_t magic_options = 0; bool wait_term = true; unsigned int delay = EXIT_DELAY; unsigned int respawn_delay = RESPAWN_DELAY; char **prog_argv = NULL; char *prog_name = NULL; struct stat file_stat; bool test_mode = false; // wait-term parameter by default magic_options |= INVOKER_MSG_MAGIC_OPTION_WAIT; // Called with a different name (old way of using invoker) ? if (!strstr(argv[0], PROG_NAME_INVOKER) ) { die(1, "Incorrect use of invoker, don't use symlinks. " "Run invoker explicitly from e.g. a D-Bus service file instead.\n"); } // Stops parsing args as soon as a non-option argument is encountered putenv("POSIXLY_CORRECT=1"); // Options recognized struct option longopts[] = { {"help", no_argument, NULL, 'h'}, {"wait-term", no_argument, NULL, 'w'}, {"no-wait", no_argument, NULL, 'n'}, {"global-syms", no_argument, NULL, 'G'}, {"deep-syms", no_argument, NULL, 'D'}, {"single-instance", no_argument, NULL, 's'}, {"keep-oom-score", no_argument, NULL, 'o'}, {"daemon-mode", no_argument, NULL, 'o'}, // Legacy alias {"test-mode", no_argument, NULL, 'T'}, {"type", required_argument, NULL, 't'}, {"delay", required_argument, NULL, 'd'}, {"respawn", required_argument, NULL, 'r'}, {"splash", required_argument, NULL, 'S'}, {"splash-landscape", required_argument, NULL, 'L'}, {0, 0, 0, 0} }; // Parse options // TODO: Move to a function int opt; while ((opt = getopt_long(argc, argv, "hcwnGDsoTd:t:r:S:L:", longopts, NULL)) != -1) { switch(opt) { case 'h': usage(0); break; case 'w': // nothing to do, it's by default now break; case 'o': magic_options |= INVOKER_MSG_MAGIC_OPTION_OOM_ADJ_DISABLE; break; case 'n': wait_term = false; magic_options &= (~INVOKER_MSG_MAGIC_OPTION_WAIT); break; case 'G': magic_options |= INVOKER_MSG_MAGIC_OPTION_DLOPEN_GLOBAL; break; case 'D': magic_options |= INVOKER_MSG_MAGIC_OPTION_DLOPEN_DEEP; break; case 'T': test_mode = true; break; case 't': app_type = optarg; break; case 'd': delay = get_delay(optarg, "delay", MIN_EXIT_DELAY, MAX_EXIT_DELAY); break; case 'r': respawn_delay = get_delay(optarg, "respawn delay", MIN_RESPAWN_DELAY, MAX_RESPAWN_DELAY); break; case 's': magic_options |= INVOKER_MSG_MAGIC_OPTION_SINGLE_INSTANCE; break; case 'S': case 'L': // Removed splash support. Ignore. break; case '?': usage(1); } } // Option processing stops as soon as application name is encountered if (optind < argc) { prog_name = search_program(argv[optind]); prog_argc = argc - optind; prog_argv = &argv[optind]; // Force argv[0] of application to be the absolute path to allow the // application to find out its installation directory from there prog_argv[0] = prog_name; } // Check if application name isn't defined if (!prog_name) { report(report_error, "Application's name is not defined.\n"); usage(1); } // Check if application exists if (stat(prog_name, &file_stat)) { report(report_error, "%s: not found\n", prog_name); return EXIT_STATUS_APPLICATION_NOT_FOUND; } // Check that if (!S_ISREG(file_stat.st_mode) && !S_ISLNK(file_stat.st_mode)) { report(report_error, "%s: not a file\n", prog_name); return EXIT_STATUS_APPLICATION_NOT_FOUND; } // If it's a launcher, append its first argument to the name // (at this point, we have already checked if it exists and is a file) if (strcmp(prog_name, "/usr/bin/sailfish-qml") == 0) { if (prog_argc < 2) { report(report_error, "%s: requires an argument\n", prog_name); return EXIT_STATUS_APPLICATION_NOT_FOUND; } // Must not free() the existing prog_name, as it's pointing to prog_argv[0] prog_name = (char *)malloc(strlen(prog_argv[0]) + strlen(prog_argv[1]) + 2); sprintf(prog_name, "%s %s", prog_argv[0], prog_argv[1]); } if (!app_type) { report(report_error, "Application type must be specified with --type.\n"); usage(1); } if (pipe(g_signal_pipe) == -1) { report(report_error, "Creating a pipe for Unix signals failed!\n"); exit(EXIT_FAILURE); } // Send commands to the launcher daemon info("Invoking execution: '%s'\n", prog_name); int ret_val = invoke(prog_argc, prog_argv, prog_name, app_type, magic_options, wait_term, respawn_delay, test_mode); // Sleep for delay before exiting if (delay) { // DBUS cannot cope some times if the invoker exits too early. debug("Delaying exit for %d seconds..\n", delay); sleep(delay); } return ret_val; }