Esempio n. 1
0
int main(int argc, char **argv) {
    int res = 1;
    int my_optind = 0;

    program_name = L"fish";
    set_main_thread();
    setup_fork_guards();
    signal_unblock_all();
    setlocale(LC_ALL, "");
    fish_setlocale();

    // struct stat tmp;
    // stat("----------FISH_HIT_MAIN----------", &tmp);

    if (!argv[0]) {
        static const char *dummy_argv[2] = {"fish", NULL};
        argv = (char **)dummy_argv;  //!OCLINT(parameter reassignment)
        argc = 1;                    //!OCLINT(parameter reassignment)
    }
    fish_cmd_opts_t opts;
    my_optind = fish_parse_opt(argc, argv, &opts);

    // No-exec is prohibited when in interactive mode.
    if (is_interactive_session && no_exec) {
        debug(1, _(L"Can not use the no-execute mode when running an interactive session"));
        no_exec = 0;
    }

    // Only save (and therefore restore) the fg process group if we are interactive. See issues
    // #197 and #1002.
    if (is_interactive_session) {
        save_term_foreground_process_group();
    }

    const struct config_paths_t paths = determine_config_directory_paths(argv[0]);
    env_init(&paths);
    // Set features early in case other initialization depends on them.
    // Start with the ones set in the environment, then those set on the command line (so the
    // command line takes precedence).
    if (auto features_var = env_get(L"fish_features")) {
        for (const wcstring &s : features_var->as_list()) {
            mutable_fish_features().set_from_string(s);
        }
    }
    mutable_fish_features().set_from_string(opts.features);
    proc_init();
    builtin_init();
    misc_init();
    reader_init();

    parser_t &parser = parser_t::principal_parser();

    const io_chain_t empty_ios;
    if (read_init(paths)) {
        // Stomp the exit status of any initialization commands (issue #635).
        proc_set_last_status(STATUS_CMD_OK);

        // Run post-config commands specified as arguments, if any.
        if (!opts.postconfig_cmds.empty()) {
            res = run_command_list(&opts.postconfig_cmds, empty_ios);
        }

        if (!opts.batch_cmds.empty()) {
            // Run the commands specified as arguments, if any.
            if (is_login) {
                // Do something nasty to support OpenSUSE assuming we're bash. This may modify cmds.
                fish_xdm_login_hack_hack_hack_hack(&opts.batch_cmds, argc - my_optind,
                                                   argv + my_optind);
            }
            res = run_command_list(&opts.batch_cmds, empty_ios);
            reader_exit(0, 0);
        } else if (my_optind == argc) {
            // Implicitly interactive mode.
            res = reader_read(STDIN_FILENO, empty_ios);
        } else {
            char *file = *(argv + (my_optind++));
            int fd = open(file, O_RDONLY);
            if (fd == -1) {
                perror(file);
            } else {
                // OK to not do this atomically since we cannot have gone multithreaded yet.
                set_cloexec(fd);

                wcstring_list_t list;
                for (char **ptr = argv + my_optind; *ptr; ptr++) {
                    list.push_back(str2wcstring(*ptr));
                }
                env_set(L"argv", ENV_DEFAULT, list);

                const wcstring rel_filename = str2wcstring(file);

                reader_push_current_filename(rel_filename.c_str());

                res = reader_read(fd, empty_ios);

                if (res) {
                    debug(1, _(L"Error while reading file %ls\n"),
                          reader_current_filename() ? reader_current_filename()
                                                    : _(L"Standard input"));
                }
                reader_pop_current_filename();
            }
        }
    }

    int exit_status = res ? STATUS_CMD_UNKNOWN : proc_get_last_status();

    // TODO: The generic process-exit event is useless and unused.
    // Remove this in future.
    proc_fire_event(L"PROCESS_EXIT", EVENT_EXIT, getpid(), exit_status);
    event_fire_generic(L"fish_exit");

    restore_term_mode();
    restore_term_foreground_process_group();

    if (g_profiling_active) {
        parser.emit_profiling(s_profiling_output_filename);
    }

    history_save_all();
    proc_destroy();
    exit_without_destructors(exit_status);
    return EXIT_FAILURE;  // above line should always exit
}
Esempio n. 2
0
int main(int argc, char **argv)
{
    int res=1;
    const char *cmd=0;
    int my_optind=0;

    set_main_thread();
    setup_fork_guards();
    save_term_foreground_process_group();

    wsetlocale(LC_ALL, L"");
    is_interactive_session=1;
    program_name=L"fish";

    //struct stat tmp;
    //stat("----------FISH_HIT_MAIN----------", &tmp);

    my_optind = fish_parse_opt(argc, argv, &cmd);

    /*
      No-exec is prohibited when in interactive mode
    */
    if (is_interactive_session && no_exec)
    {
        debug(1, _(L"Can not use the no-execute mode when running an interactive session"));
        no_exec = 0;
    }

    const struct config_paths_t paths = determine_config_directory_paths(argv[0]);

    proc_init();
    event_init();
    wutil_init();
    builtin_init();
    function_init();
    env_init(&paths);
    reader_init();
    history_init();

    parser_t &parser = parser_t::principal_parser();

    if (g_log_forks)
        printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);

    const io_chain_t empty_ios;
    if (read_init(paths))
    {
        if (cmd != NULL)
        {
            const wcstring cmd_wcs = str2wcstring(cmd);
            res = parser.eval(cmd_wcs, empty_ios, TOP);
            reader_exit(0, 0);
        }
        else
        {
            if (my_optind == argc)
            {
                res = reader_read(STDIN_FILENO, empty_ios);
            }
            else
            {
                char **ptr;
                char *file = *(argv+(my_optind++));
                int i;
                int fd;


                if ((fd = open(file, O_RDONLY)) == -1)
                {
                    wperror(L"open");
                    return 1;
                }

                // OK to not do this atomically since we cannot have gone multithreaded yet
                set_cloexec(fd);

                if (*(argv+my_optind))
                {
                    wcstring sb;
                    for (i=1,ptr = argv+my_optind; *ptr; i++, ptr++)
                    {
                        if (i != 1)
                            sb.append(ARRAY_SEP_STR);
                        sb.append(str2wcstring(*ptr));
                    }

                    env_set(L"argv", sb.c_str(), 0);
                }

                const wcstring rel_filename = str2wcstring(file);
                const wchar_t *abs_filename = wrealpath(rel_filename, NULL);

                if (!abs_filename)
                {
                    abs_filename = wcsdup(rel_filename.c_str());
                }

                reader_push_current_filename(intern(abs_filename));
                free((void *)abs_filename);

                res = reader_read(fd, empty_ios);

                if (res)
                {
                    debug(1,
                          _(L"Error while reading file %ls\n"),
                          reader_current_filename()?reader_current_filename(): _(L"Standard input"));
                }
                reader_pop_current_filename();
            }
        }
    }

    proc_fire_event(L"PROCESS_EXIT", EVENT_EXIT, getpid(), res);

    restore_term_foreground_process_group();
    history_destroy();
    proc_destroy();
    builtin_destroy();
    reader_destroy();
    parser.destroy();
    wutil_destroy();
    event_destroy();

    env_destroy();

    if (g_log_forks)
        printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);

    return res?STATUS_UNKNOWN_COMMAND:proc_get_last_status();
}
Esempio n. 3
0
int main(int argc, char **argv)
{
    int res=1;
    int my_optind=0;

    set_main_thread();
    setup_fork_guards();

    wsetlocale(LC_ALL, L"");
    is_interactive_session=1;
    program_name=L"fish";

    //struct stat tmp;
    //stat("----------FISH_HIT_MAIN----------", &tmp);

    std::vector<std::string> cmds;
    my_optind = fish_parse_opt(argc, argv, &cmds);

    /*
      No-exec is prohibited when in interactive mode
    */
    if (is_interactive_session && no_exec)
    {
        debug(1, _(L"Can not use the no-execute mode when running an interactive session"));
        no_exec = 0;
    }

    /* Only save (and therefore restore) the fg process group if we are interactive. See #197, #1002 */
    if (is_interactive_session)
    {
        save_term_foreground_process_group();
    }

    const struct config_paths_t paths = determine_config_directory_paths(argv[0]);

    proc_init();
    event_init();
    wutil_init();
    builtin_init();
    function_init();
    env_init(&paths);
    reader_init();
    history_init();
    /* For setcolor to support term256 in config.fish (#1022) */
    update_fish_term256();

    parser_t &parser = parser_t::principal_parser();

    if (g_log_forks)
        printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);

    const io_chain_t empty_ios;
    if (read_init(paths))
    {
        /* Stop the exit status of any initialization commands (#635) */
        proc_set_last_status(STATUS_BUILTIN_OK);

        /* Run the commands specified as arguments, if any */
        if (! cmds.empty())
        {
            /* Do something nasty to support OpenSUSE assuming we're bash. This may modify cmds. */
            if (is_login)
            {
                fish_xdm_login_hack_hack_hack_hack(&cmds, argc - my_optind, argv + my_optind);
            }
            for (size_t i=0; i < cmds.size(); i++)
            {
                const wcstring cmd_wcs = str2wcstring(cmds.at(i));
                res = parser.eval(cmd_wcs, empty_ios, TOP);
            }
            reader_exit(0, 0);
        }
        else
        {
            if (my_optind == argc)
            {
                res = reader_read(STDIN_FILENO, empty_ios);
            }
            else
            {
                char **ptr;
                char *file = *(argv+(my_optind++));
                int i;
                int fd;


                if ((fd = open(file, O_RDONLY)) == -1)
                {
                    wperror(L"open");
                    return 1;
                }

                // OK to not do this atomically since we cannot have gone multithreaded yet
                set_cloexec(fd);

                if (*(argv+my_optind))
                {
                    wcstring sb;
                    for (i=1,ptr = argv+my_optind; *ptr; i++, ptr++)
                    {
                        if (i != 1)
                            sb.append(ARRAY_SEP_STR);
                        sb.append(str2wcstring(*ptr));
                    }

                    env_set(L"argv", sb.c_str(), 0);
                }

                const wcstring rel_filename = str2wcstring(file);
                const wchar_t *abs_filename = wrealpath(rel_filename, NULL);

                if (!abs_filename)
                {
                    abs_filename = wcsdup(rel_filename.c_str());
                }

                reader_push_current_filename(intern(abs_filename));
                free((void *)abs_filename);

                res = reader_read(fd, empty_ios);

                if (res)
                {
                    debug(1,
                          _(L"Error while reading file %ls\n"),
                          reader_current_filename()?reader_current_filename(): _(L"Standard input"));
                }
                reader_pop_current_filename();
            }
        }
    }

    proc_fire_event(L"PROCESS_EXIT", EVENT_EXIT, getpid(), res);

    restore_term_mode();
    restore_term_foreground_process_group();
    history_destroy();
    proc_destroy();
    builtin_destroy();
    reader_destroy();
    parser.destroy();
    wutil_destroy();
    event_destroy();

    env_destroy();

    if (g_log_forks)
        printf("%d: g_fork_count: %d\n", __LINE__, g_fork_count);

    exit_without_destructors(res ? STATUS_UNKNOWN_COMMAND : proc_get_last_status());
    return EXIT_FAILURE; //above line should always exit
}
Esempio n. 4
0
/**
   The main mathod. Run the program.
 */
int main(int argc, char **argv)
{
    int do_indent=1;
    set_main_thread();
    setup_fork_guards();

    wsetlocale(LC_ALL, L"");
    program_name=L"fish_indent";

    while (1)
    {
        static struct option
                long_options[] =
        {
            {
                "no-indent", no_argument, 0, 'i'
            }
            ,
            {
                "help", no_argument, 0, 'h'
            }
            ,
            {
                "version", no_argument, 0, 'v'
            }
            ,
            {
                0, 0, 0, 0
            }
        }
        ;

        int opt_index = 0;

        int opt = getopt_long(argc,
                              argv,
                              GETOPT_STRING,
                              long_options,
                              &opt_index);

        if (opt == -1)
            break;

        switch (opt)
        {
            case 0:
            {
                break;
            }

            case 'h':
            {
                print_help("fish_indent", 1);
                exit(0);
                break;
            }

            case 'v':
            {
                fwprintf(stderr,
                         _(L"%ls, version %s\n"),
                         program_name,
                         FISH_BUILD_VERSION);
                exit(0);
            }

            case 'i':
            {
                do_indent = 0;
                break;
            }


            case '?':
            {
                exit(1);
            }

        }
    }

    wcstring sb_in, sb_out;
    read_file(stdin, sb_in);

    wutil_init();

    if (!indent(sb_out, sb_in, do_indent))
    {
        trim(sb_out);
        fwprintf(stdout, L"%ls", sb_out.c_str());
    }
    else
    {
        /*
          Indenting failed - print original input
        */
        fwprintf(stdout, L"%ls", sb_in.c_str());
    }


    wutil_destroy();

    return 0;
}
Esempio n. 5
0
/**
   Main function for fishd
*/
int main(int argc, char ** argv)
{
    int child_socket;
    struct sockaddr_un remote;
    socklen_t t;
    uid_t sock_euid;
    gid_t sock_egid;
    int max_fd;
    int update_count=0;

    fd_set read_fd, write_fd;

    set_main_thread();
    setup_fork_guards();

    program_name=L"fishd";
    wsetlocale(LC_ALL, L"");

    /*
      Parse options
    */
    while (1)
    {
        static struct option
                long_options[] =
        {
            {
                "help", no_argument, 0, 'h'
            }
            ,
            {
                "version", no_argument, 0, 'v'
            }
            ,
            {
                0, 0, 0, 0
            }
        }
        ;

        int opt_index = 0;

        int opt = getopt_long(argc,
                              argv,
                              GETOPT_STRING,
                              long_options,
                              &opt_index);

        if (opt == -1)
            break;

        switch (opt)
        {
            case 0:
                break;

            case 'h':
                print_help(argv[0], 1);
                exit(0);

            case 'v':
                debug(0, L"%ls, version %s\n", program_name, FISH_BUILD_VERSION);
                exit(0);

            case '?':
                return 1;

        }
    }

    init();
    while (1)
    {
        int res;

        t = sizeof(remote);

        FD_ZERO(&read_fd);
        FD_ZERO(&write_fd);
        FD_SET(sock, &read_fd);
        max_fd = sock+1;
        for (connection_list_t::const_iterator iter = connections.begin(); iter != connections.end(); ++iter)
        {
            const connection_t &c = *iter;
            FD_SET(c.fd, &read_fd);
            max_fd = maxi(max_fd, c.fd+1);

            if (! c.unsent.empty())
            {
                FD_SET(c.fd, &write_fd);
            }
        }

        while (1)
        {
            res=select(max_fd, &read_fd, &write_fd, 0, 0);

            if (quit)
            {
                save();
                exit(0);
            }

            if (res != -1)
                break;

            if (errno != EINTR)
            {
                wperror(L"select");
                exit(1);
            }
        }

        if (FD_ISSET(sock, &read_fd))
        {
            if ((child_socket =
                        accept(sock,
                               (struct sockaddr *)&remote,
                               &t)) == -1)
            {
                wperror(L"accept");
                exit(1);
            }
            else
            {
                debug(4, L"Connected with new child on fd %d", child_socket);

                if (((getpeereid(child_socket, &sock_euid, &sock_egid) != 0) || sock_euid != geteuid()))
                {
                    debug(1, L"Wrong credentials for child on fd %d", child_socket);
                    close(child_socket);
                }
                else if (make_fd_nonblocking(child_socket) != 0)
                {
                    wperror(L"fcntl");
                    close(child_socket);
                }
                else
                {
                    connections.push_front(connection_t(child_socket));
                    connection_t &newc = connections.front();
                    send(newc.fd, GREETING, strlen(GREETING), MSG_DONTWAIT);
                    enqueue_all(&newc);
                }
            }
        }

        for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter)
        {
            if (FD_ISSET(iter->fd, &write_fd))
            {
                try_send_all(&*iter);
            }
        }

        for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter)
        {
            if (FD_ISSET(iter->fd, &read_fd))
            {
                read_message(&*iter);

                /*
                  Occasionally we save during normal use, so that we
                  won't lose everything on a system crash
                */
                update_count++;
                if (update_count >= 64)
                {
                    save();
                    update_count = 0;
                }
            }
        }

        for (connection_list_t::iterator iter = connections.begin(); iter != connections.end();)
        {
            if (iter->killme)
            {
                debug(4, L"Close connection %d", iter->fd);

                while (! iter->unsent.empty())
                {
                    message_t *msg = iter->unsent.front();
                    iter->unsent.pop();
                    msg->count--;
                    if (! msg->count)
                        free(msg);
                }

                connection_destroy(&*iter);
                iter = connections.erase(iter);
            }
            else
            {
                ++iter;
            }
        }

        if (connections.empty())
        {
            debug(0, L"No more clients. Quitting");
            save();
            break;
        }

    }
}
Esempio n. 6
0
int main(int argc, char *argv[]) {
    program_name = L"fish_indent";
    set_main_thread();
    setup_fork_guards();
    // Using the user's default locale could be a problem if it doesn't use UTF-8 encoding. That's
    // because the fish project assumes Unicode UTF-8 encoding in all of its scripts.
    //
    // TODO: Auto-detect the encoding of the script. We should look for a vim style comment
    // (e.g., "# vim: set fileencoding=<encoding-name>:") or an emacs style comment
    // (e.g., "# -*- coding: <encoding-name> -*-").
    setlocale(LC_ALL, "");
    env_init();

    // Types of output we support.
    enum {
        output_type_plain_text,
        output_type_file,
        output_type_ansi,
        output_type_html
    } output_type = output_type_plain_text;
    const char *output_location = "";
    bool do_indent = true;

    const char *short_opts = "+d:hvwiD:";
    const struct option long_opts[] = {{"debug-level", required_argument, NULL, 'd'},
                                       {"debug-stack-frames", required_argument, NULL, 'D'},
                                       {"dump-parse-tree", no_argument, NULL, 'P'},
                                       {"no-indent", no_argument, NULL, 'i'},
                                       {"help", no_argument, NULL, 'h'},
                                       {"version", no_argument, NULL, 'v'},
                                       {"write", no_argument, NULL, 'w'},
                                       {"html", no_argument, NULL, 1},
                                       {"ansi", no_argument, NULL, 2},
                                       {NULL, 0, NULL, 0}};

    int opt;
    while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
        switch (opt) {
            case 'P': {
                dump_parse_tree = true;
                break;
            }
            case 'h': {
                print_help("fish_indent", 1);
                exit(0);
                break;
            }
            case 'v': {
                fwprintf(stderr, _(L"%ls, version %s\n"), program_name, get_fish_version());
                exit(0);
                break;
            }
            case 'w': {
                output_type = output_type_file;
                break;
            }
            case 'i': {
                do_indent = false;
                break;
            }
            case 1: {
                output_type = output_type_html;
                break;
            }
            case 2: {
                output_type = output_type_ansi;
                break;
            }
            case 'd': {
                char *end;
                long tmp;

                errno = 0;
                tmp = strtol(optarg, &end, 10);

                if (tmp >= 0 && tmp <= 10 && !*end && !errno) {
                    debug_level = (int)tmp;
                } else {
                    fwprintf(stderr, _(L"Invalid value '%s' for debug-level flag"), optarg);
                    exit(1);
                }
                break;
            }
            case 'D': {
                char *end;
                long tmp;

                errno = 0;
                tmp = strtol(optarg, &end, 10);

                if (tmp > 0 && tmp <= 128 && !*end && !errno) {
                    debug_stack_frames = (int)tmp;
                } else {
                    fwprintf(stderr, _(L"Invalid value '%s' for debug-stack-frames flag"), optarg);
                    exit(1);
                }
                break;
            }
            default: {
                // We assume getopt_long() has already emitted a diagnostic msg.
                exit(1);
                break;
            }
        }
    }

    argc -= optind;
    argv += optind;

    wcstring src;
    if (argc == 0) {
        if (output_type == output_type_file) {
            fwprintf(stderr, _(L"Expected file path to read/write for -w:\n\n $ %ls -w foo.fish\n"),
                     program_name);
            exit(1);
        }
        src = read_file(stdin);
    } else if (argc == 1) {
        FILE *fh = fopen(*argv, "r");
        if (fh) {
            src = read_file(fh);
            fclose(fh);
            output_location = *argv;
        } else {
            fwprintf(stderr, _(L"Opening \"%s\" failed: %s\n"), *argv, strerror(errno));
            exit(1);
        }
    } else {
        fwprintf(stderr, _(L"Too many arguments\n"));
        exit(1);
    }

    const wcstring output_wtext = prettify(src, do_indent);

    // Maybe colorize.
    std::vector<highlight_spec_t> colors;
    if (output_type != output_type_plain_text) {
        highlight_shell_no_io(output_wtext, colors, output_wtext.size(), NULL,
                              env_vars_snapshot_t::current());
    }

    std::string colored_output;
    switch (output_type) {
        case output_type_plain_text: {
            colored_output = no_colorize(output_wtext);
            break;
        }
        case output_type_file: {
            FILE *fh = fopen(output_location, "w");
            if (fh) {
                fputws(output_wtext.c_str(), fh);
                fclose(fh);
                exit(0);
            } else {
                fwprintf(stderr, _(L"Opening \"%s\" failed: %s\n"), output_location,
                         strerror(errno));
                exit(1);
            }
            break;
        }
        case output_type_ansi: {
            colored_output = ansi_colorize(output_wtext, colors);
            break;
        }
        case output_type_html: {
            colored_output = html_colorize(output_wtext, colors);
            break;
        }
    }

    fputws(str2wcstring(colored_output).c_str(), stdout);
    return 0;
}
Esempio n. 7
0
int main(int argc, char **argv) {
    int res = 1;
    int my_optind = 0;

    program_name = L"fish";
    set_main_thread();
    setup_fork_guards();

    setlocale(LC_ALL, "");
    fish_setlocale();

    // struct stat tmp;
    // stat("----------FISH_HIT_MAIN----------", &tmp);

    if (!argv[0]) {
        static const char *dummy_argv[2] = {"fish", NULL};
        argv = (char **)dummy_argv;  //!OCLINT(parameter reassignment)
        argc = 1;                    //!OCLINT(parameter reassignment)
    }
    std::vector<std::string> cmds;
    my_optind = fish_parse_opt(argc, argv, &cmds);

    // No-exec is prohibited when in interactive mode.
    if (is_interactive_session && no_exec) {
        debug(1, _(L"Can not use the no-execute mode when running an interactive session"));
        no_exec = 0;
    }

    // Only save (and therefore restore) the fg process group if we are interactive. See issues
    // #197 and #1002.
    if (is_interactive_session) {
        save_term_foreground_process_group();
    }

    const struct config_paths_t paths = determine_config_directory_paths(argv[0]);

    proc_init();
    event_init();
    builtin_init();
    function_init();
    env_init(&paths);
    reader_init();
    history_init();
    // For set_color to support term256 in config.fish (issue #1022).
    update_fish_color_support();
    misc_init();

    parser_t &parser = parser_t::principal_parser();

    const io_chain_t empty_ios;
    if (read_init(paths)) {
        // Stomp the exit status of any initialization commands (issue #635).
        proc_set_last_status(STATUS_BUILTIN_OK);

        // Run the commands specified as arguments, if any.
        if (!cmds.empty()) {
            // Do something nasty to support OpenSUSE assuming we're bash. This may modify cmds.
            if (is_login) {
                fish_xdm_login_hack_hack_hack_hack(&cmds, argc - my_optind, argv + my_optind);
            }
            for (size_t i = 0; i < cmds.size(); i++) {
                const wcstring cmd_wcs = str2wcstring(cmds.at(i));
                res = parser.eval(cmd_wcs, empty_ios, TOP);
            }
            reader_exit(0, 0);
        } else if (my_optind == argc) {
            // Interactive mode
            check_running_fishd();
            res = reader_read(STDIN_FILENO, empty_ios);
        } else {
            char *file = *(argv + (my_optind++));
            int fd = open(file, O_RDONLY);
            if (fd == -1) {
                perror(file);
            } else {
                // OK to not do this atomically since we cannot have gone multithreaded yet.
                set_cloexec(fd);

                if (*(argv + my_optind)) {
                    wcstring sb;
                    char **ptr;
                    int i;
                    for (i = 1, ptr = argv + my_optind; *ptr; i++, ptr++) {
                        if (i != 1) sb.append(ARRAY_SEP_STR);
                        sb.append(str2wcstring(*ptr));
                    }

                    env_set(L"argv", sb.c_str(), 0);
                }

                const wcstring rel_filename = str2wcstring(file);

                reader_push_current_filename(rel_filename.c_str());

                res = reader_read(fd, empty_ios);

                if (res) {
                    debug(1, _(L"Error while reading file %ls\n"), reader_current_filename()
                                                                       ? reader_current_filename()
                                                                       : _(L"Standard input"));
                }
                reader_pop_current_filename();
            }
        }
    }

    int exit_status = res ? STATUS_UNKNOWN_COMMAND : proc_get_last_status();

    proc_fire_event(L"PROCESS_EXIT", EVENT_EXIT, getpid(), exit_status);

    restore_term_mode();
    restore_term_foreground_process_group();

    if (g_profiling_active) {
        parser.emit_profiling(s_profiling_output_filename);
    }

    history_destroy();
    proc_destroy();
    builtin_destroy();
    reader_destroy();
    event_destroy();
    exit_without_destructors(exit_status);
    return EXIT_FAILURE;  // above line should always exit
}
Esempio n. 8
0
/**
   Main function for fishd
*/
int main(int argc, char ** argv)
{
    int child_socket;
    struct sockaddr_un remote;
    socklen_t t;
    int max_fd;
    int update_count=0;

    fd_set read_fd, write_fd;

    set_main_thread();
    setup_fork_guards();

    program_name=L"fishd";
    wsetlocale(LC_ALL, L"");

    /*
      Parse options
    */
    while (1)
    {
        static struct option
                long_options[] =
        {
            {
                "help", no_argument, 0, 'h'
            }
            ,
            {
                "version", no_argument, 0, 'v'
            }
            ,
            {
                0, 0, 0, 0
            }
        }
        ;

        int opt_index = 0;

        int opt = getopt_long(argc,
                              argv,
                              GETOPT_STRING,
                              long_options,
                              &opt_index);

        if (opt == -1)
            break;

        switch (opt)
        {
            case 0:
                break;

            case 'h':
                print_help(argv[0], 1);
                exit(0);

            case 'v':
                debug(0, L"%ls, version %s\n", program_name, PACKAGE_VERSION);
                exit(0);

            case '?':
                return 1;

        }
    }

    init();
    while (1)
    {
        connection_t *c;
        int res;

        t = sizeof(remote);

        FD_ZERO(&read_fd);
        FD_ZERO(&write_fd);
        FD_SET(sock, &read_fd);
        max_fd = sock+1;
        for (c=conn; c; c=c->next)
        {
            FD_SET(c->fd, &read_fd);
            max_fd = maxi(max_fd, c->fd+1);

            if (! c->unsent->empty())
            {
                FD_SET(c->fd, &write_fd);
            }
        }

        while (1)
        {
            res=select(max_fd, &read_fd, &write_fd, 0, 0);

            if (quit)
            {
                save();
                exit(0);
            }

            if (res != -1)
                break;

            if (errno != EINTR)
            {
                wperror(L"select");
                exit(1);
            }
        }

        if (FD_ISSET(sock, &read_fd))
        {
            if ((child_socket =
                        accept(sock,
                               (struct sockaddr *)&remote,
                               &t)) == -1)
            {
                wperror(L"accept");
                exit(1);
            }
            else
            {
                debug(4, L"Connected with new child on fd %d", child_socket);

                if (fcntl(child_socket, F_SETFL, O_NONBLOCK) != 0)
                {
                    wperror(L"fcntl");
                    close(child_socket);
                }
                else
                {
                    connection_t *newc = (connection_t *)malloc(sizeof(connection_t));
                    connection_init(newc, child_socket);
                    newc->next = conn;
                    send(newc->fd, GREETING, strlen(GREETING), MSG_DONTWAIT);
                    enqueue_all(newc);
                    conn=newc;
                }
            }
        }

        for (c=conn; c; c=c->next)
        {
            if (FD_ISSET(c->fd, &write_fd))
            {
                try_send_all(c);
            }
        }

        for (c=conn; c; c=c->next)
        {
            if (FD_ISSET(c->fd, &read_fd))
            {
                read_message(c);

                /*
                  Occasionally we save during normal use, so that we
                  won't lose everything on a system crash
                */
                update_count++;
                if (update_count >= 64)
                {
                    save();
                    update_count = 0;
                }
            }
        }

        connection_t *prev=0;
        c=conn;

        while (c)
        {
            if (c->killme)
            {
                debug(4, L"Close connection %d", c->fd);

                while (! c->unsent->empty())
                {
                    message_t *msg = c->unsent->front();
                    c->unsent->pop();
                    msg->count--;
                    if (!msg->count)
                        free(msg);
                }

                connection_destroy(c);
                if (prev)
                {
                    prev->next=c->next;
                }
                else
                {
                    conn=c->next;
                }

                free(c);

                c=(prev?prev->next:conn);

            }
            else
            {
                prev=c;
                c=c->next;
            }
        }

        if (!conn)
        {
            debug(0, L"No more clients. Quitting");
            save();
            env_universal_common_destroy();
            break;
        }

    }
}
Esempio n. 9
0
int main(int argc, char *argv[])
{
    set_main_thread();
    setup_fork_guards();

    wsetlocale(LC_ALL, L"");
    program_name=L"fish_indent";

    env_init();
    input_init();

    /* Types of output we support */
    enum
    {
        output_type_plain_text,
        output_type_ansi,
        output_type_html
    } output_type = output_type_plain_text;
    bool do_indent = true;

    const char *short_opts = "+dhvi";
    const struct option long_opts[] =
    {
        { "dump", no_argument, NULL, 'd' },
        { "no-indent", no_argument, NULL, 'i' },
        { "help", no_argument, NULL, 'h' },
        { "version", no_argument, NULL, 'v' },
        { "html", no_argument, NULL, 1 },
        { "ansi", no_argument, NULL, 2 },
        { NULL, 0, NULL, 0 }
    };

    int opt;
    while ((opt = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1)
    {
        switch (opt)
        {
            case 0:
            {
                fwprintf(stderr, _(L"getopt_long() unexpectedly returned zero\n"));
                exit_without_destructors(127);
            }

            case 'd':
            {
                dump_parse_tree = true;
                break;
            }

            case 'h':
            {
                print_help("fish_indent", 1);
                exit_without_destructors(0);
            }

            case 'v':
            {
                fwprintf(stderr, _(L"%ls, version %s\n"), program_name, get_fish_version());
                exit(0);
                assert(0 && "Unreachable code reached");
                break;
            }

            case 'i':
            {
                do_indent = false;
                break;
            }

            case 1:
            {
                output_type = output_type_html;
                break;
            }

            case 2:
            {
                output_type = output_type_ansi;
                break;
            }

            default:
            {
                // We assume getopt_long() has already emitted a diagnostic msg.
                exit_without_destructors(1);
            }
        }
    }

    const wcstring src = read_file(stdin);
    const wcstring output_wtext = prettify(src, do_indent);

    /* Maybe colorize */
    std::vector<highlight_spec_t> colors;
    if (output_type != output_type_plain_text)
    {
        highlight_shell_no_io(output_wtext, colors, output_wtext.size(), NULL, env_vars_snapshot_t::current());
    }

    std::string colored_output;
    switch (output_type)
    {
        case output_type_plain_text:
            colored_output = no_colorize(output_wtext);
            break;

        case output_type_ansi:
            colored_output = ansi_colorize(output_wtext, colors);
            break;

        case output_type_html:
            colored_output = html_colorize(output_wtext, colors);
            break;
    }

    fputs(colored_output.c_str(), stdout);
    return 0;
}
Esempio n. 10
0
int main(int argc, char **argv)
{
    int i;
    int is_quoted=0;
    wcstring_list_t comp;
    wcstring prefix;

    int mangle_descriptors = 0;
    int result_fd = -1;
    set_main_thread();
    setup_fork_guards();

    /*
      This initialization is made early, so that the other init code
      can use global_context for memory managment
    */
    program_name = L"fish_pager";


    wsetlocale(LC_ALL, L"");

    /*
      The call signature for fish_pager is a mess. Because we want
      to be able to upgrade fish without breaking running
      instances, we need to support all previous
      modes. Unfortunatly, the two previous ones are a mess. The
      third one is designed to be extensible, so hopefully it will
      be the last.
    */

    if (argc > 1 && argv[1][0] == '-')
    {
        /*
          Third mode
        */

        int completion_fd = -1;
        FILE *completion_file;

        while (1)
        {
            static struct option
                    long_options[] =
            {
                {
                    "result-fd", required_argument, 0, 'r'
                }
                ,
                {
                    "completion-fd", required_argument, 0, 'c'
                }
                ,
                {
                    "prefix", required_argument, 0, 'p'
                }
                ,
                {
                    "is-quoted", no_argument, 0, 'q'
                }
                ,
                {
                    "help", no_argument, 0, 'h'
                }
                ,
                {
                    "version", no_argument, 0, 'v'
                }
                ,
                {
                    0, 0, 0, 0
                }
            }
            ;

            int opt_index = 0;

            int opt = getopt_long(argc,
                                  argv,
                                  GETOPT_STRING,
                                  long_options,
                                  &opt_index);

            if (opt == -1)
                break;

            switch (opt)
            {
                case 0:
                {
                    break;
                }

                case 'r':
                {
                    result_fd = get_fd(optarg);
                    break;
                }

                case 'c':
                {
                    completion_fd = get_fd(optarg);
                    break;
                }

                case 'p':
                {
                    prefix = str2wcstring(optarg);
                    break;
                }

                case 'h':
                {
                    print_help(argv[0], 1);
                    exit(0);
                }

                case 'v':
                {
                    debug(0, L"%ls, version %s\n", program_name, PACKAGE_VERSION);
                    exit(0);
                }

                case 'q':
                {
                    is_quoted = 1;
                }

            }
        }

        if (completion_fd == -1 || result_fd == -1)
        {
            debug(0, _(L"Unspecified file descriptors"));
            exit(1);
        }


        if ((completion_file = fdopen(completion_fd, "r")))
        {
            read_array(completion_file, comp);
            fclose(completion_file);
        }
        else
        {
            debug(0, _(L"Could not read completions"));
            wperror(L"fdopen");
            exit(1);
        }

    }
    else
    {
        /*
          Second or first mode. These suck, but we need to support
          them for backwards compatibility. At least for some
          time.

          Third mode was implemented in January 2007, and previous
          modes should be considered deprecated from that point
          forward. A reasonable time frame for removal of the code
          below has yet to be determined.
        */

        if (argc < 3)
        {
            print_help(argv[0], 1);
            exit(0);
        }
        else
        {
            mangle_descriptors = 1;

            prefix = str2wcstring(argv[2]);
            is_quoted = strcmp("1", argv[1])==0;

            if (argc > 3)
            {
                /*
                  First mode
                */
                for (i=3; i<argc; i++)
                {
                    wcstring wcs = str2wcstring(argv[i]);
                    comp.push_back(wcs);
                }
            }
            else
            {
                /*
                  Second mode
                */
                read_array(stdin, comp);
            }
        }

    }

//    debug( 3, L"prefix is '%ls'", prefix );

    init(mangle_descriptors, result_fd);

    mangle_descriptions(comp);

    if (prefix == L"-")
        join_completions(comp);

    std::vector<comp_t *> completions = mangle_completions(comp, prefix.c_str());

    /**
       Try to print the completions. Start by trying to print the
       list in PAGER_MAX_COLS columns, if the completions won't
       fit, reduce the number of columns by one. Printing a single
       column never fails.
    */
    for (i = PAGER_MAX_COLS; i>0; i--)
    {
        switch (completion_try_print(i, prefix.c_str(), is_quoted, completions))
        {

            case PAGER_RETRY:
                break;

            case PAGER_DONE:
                i=0;
                break;

            case PAGER_RESIZE:
                /*
                  This means we got a resize event, so we start
                  over from the beginning. Since it the screen got
                  bigger, we might be able to fit all completions
                  on-screen.
                */
                i=PAGER_MAX_COLS+1;
                break;

        }
    }

    fwprintf(out_file, L"%ls", out_buff.c_str());
    if (is_ca_mode)
    {
        writembs(exit_ca_mode);
        pager_flush();
    }
    destroy();

}