Exemple #1
0
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;
}
Exemple #3
0
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;
}