int main(int argc, char **argv) { char *command_name; rlwrap_command_line = unsplit_with(argc, argv, " "); init_completer(); /* Harvest options and leave optind pointing to first non-option argument: */ command_name = read_options_and_command_name(argc, argv); /* by now, optind points to slave <command>, and &argv[optind] is <command>'s argv. Remember slave command line: */ command_line = unsplit_with(argc - optind, argv, " "); /* if stdin is not a tty, just execute <command>: */ if (!isatty(STDIN_FILENO) && execvp(argv[optind], &argv[optind]) < 0) myerror(FATAL|USE_ERRNO, "Cannot execute %s", argv[optind]); init_rlwrap(rlwrap_command_line); install_signal_handlers(); block_all_signals(); fork_child(command_name, argv); /* this will unblock most signals most of the time */ if (filter_command) spawn_filter(filter_command); main_loop(); return 42; /* The Answer, but, sadly, we'll never get there.... */ }
int main(int argc, char **argv) { char *command_name; init_completer(); command_name = read_options_and_command_name(argc, argv); /* by now, optind points to <command>, and &argv[optind] is <command>'s argv */ if (!isatty(STDIN_FILENO) && execvp(argv[optind], &argv[optind]) < 0) /* if stdin is not a tty, just execute <command> */ myerror("Cannot execute %s", argv[optind]); init_rlwrap(); install_signal_handlers(); block_all_signals(); fork_child(command_name, argv); if (filter_command) spawn_filter(filter_command); main_loop(); return 42; /* not reached, but some compilers are unhappy without this ... */ }
char * read_options_and_command_name(int argc, char **argv) { int c; char *opt_C = NULL; int option_count = 0; int opt_b = FALSE; int opt_f = FALSE; int remaining = -1; /* remaining number of arguments on command line */ int longindex = -1; /* index of current option in longopts[], set by getopt_long */ full_program_name = mysavestring(argv[0]); program_name = mybasename(full_program_name); /* normally "rlwrap"; needed by myerror() */ rl_basic_word_break_characters = " \t\n\r(){}[],+-=&^%$#@\";|\\"; opterr = 0; /* we do our own error reporting */ while (1) { #ifdef HAVE_GETOPT_LONG c = getopt_long(argc, argv, optstring, longopts, &longindex); #else c = getopt(argc, argv, optstring); #endif if (c == EOF) break; option_count++; last_option_didnt_have_optional_argument = FALSE; remaining = argc - optind; last_opt = c; switch (c) { case 'a': always_readline = TRUE; if (check_optarg('a', remaining)) password_prompt_search_string = mysavestring(optarg); break; case 'A': ansi_colour_aware = TRUE; break; case 'b': rl_basic_word_break_characters = add3strings("\r\n \t", optarg, ""); opt_b = TRUE; break; case 'c': complete_filenames = TRUE; break; case 'C': opt_C = mysavestring(optarg); break; case 'd': #ifdef DEBUG if (option_count > 1) myerror("-d or --debug option has to be the *first* rlwrap option"); if (check_optarg('d', remaining)) debug = atoi(optarg); else debug = DEBUG_DEFAULT; #else myerror ("To use -d( for debugging), configure %s with --enable-debug and rebuild", program_name); #endif break; case 'D': history_duplicate_avoidance_policy=atoi(optarg); if (history_duplicate_avoidance_policy < 0 || history_duplicate_avoidance_policy > 2) myerror("%s option with illegal value %d, should be 0, 1 or 2", current_option('D', longindex), history_duplicate_avoidance_policy); break; case 'f': if (strncmp(optarg, ".", 10) == 0) feed_history_into_completion_list = TRUE; else feed_file_into_completion_list(optarg); opt_f = TRUE; break; case 'F': myerror("The -F (--history-format) option is obsolete. Use -z \"history_format '%s'\" instead", optarg); case 'g': forget_regexp = mysavestring(optarg); match_regexp("just testing", forget_regexp, 1); break; case 'h': usage(EXIT_SUCCESS); /* will call exit() */ case 'H': history_filename = mysavestring(optarg); break; case 'i': if (opt_f) myerror("-i option has to precede -f options"); completion_is_case_sensitive = FALSE; break; case 'I': pass_on_sigINT_as_sigTERM = TRUE; break; case 'l': open_logfile(optarg); break; case 'n': nowarn = TRUE; break; case 'm': #ifndef HAVE_SYSTEM mywarn("the -m option doesn't work on this system"); #endif multiline_separator = (check_optarg('m', remaining) ? mysavestring(optarg) : " \\ "); break; case 'N': commands_children_not_wrapped = TRUE; break; case 'o': one_shot_rlwrap = TRUE; impatient_prompt = FALSE; wait_before_prompt = 200; break; case 'O': prompt_regexp = mysavestring(optarg); match_regexp("just testing", prompt_regexp, 1); break; case 'p': colour_the_prompt = TRUE; initialise_colour_codes(check_optarg('p', remaining) ? colour_name_to_ansi_code(optarg) : colour_name_to_ansi_code("Red")); break; case 'P': pre_given = mysavestring(optarg); always_readline = TRUE; /* pre_given does not work well with transparent mode */ break; case 'q': rl_basic_quote_characters = mysavestring(optarg); break; case 'r': remember_for_completion = TRUE; break; case 'R': renice = TRUE; break; case 's': histsize = atoi(optarg); if (histsize < 0) { write_histfile = 0; histsize = -histsize; } break; case 'S': substitute_prompt = mysavestring(optarg);break; case 't': client_term_name=mysavestring(optarg);break; #ifdef DEBUG case 'T': test_terminal(); exit(EXIT_SUCCESS); #endif case 'v': printf("rlwrap %s\n", VERSION); exit(EXIT_SUCCESS); case 'w': wait_before_prompt = atoi(optarg); if (wait_before_prompt < 0) { wait_before_prompt *= -1; impatient_prompt = FALSE; } break; case 'z': filter_command = mysavestring(optarg); break; case '?': assert(optind > 0); myerror("unrecognised option %s\ntry '%s --help' for more information", argv[optind-1], full_program_name); case ':': assert(optind > 0); myerror ("option %s requires an argument \ntry '%s --help' for more information", argv[optind-1], full_program_name); default: usage(EXIT_FAILURE); } } if (!complete_filenames && !opt_b) { /* use / and . as default breaking characters whenever we don't complete filenames */ rl_basic_word_break_characters = add2strings(rl_basic_word_break_characters, "/."); } if (optind >= argc) { /* rlwrap -a -b -c with no command specified */ if (filter_command) { /* rlwrap -z filter with no command specified */ mysignal(SIGALRM, &handle_sigALRM); /* needed for read_patiently2 */ spawn_filter(filter_command); pass_through_filter(TAG_OUTPUT,""); /* ignore result but allow TAG_OUTPUT_OUT_OF_BAND */ cleanup_rlwrap_and_exit(EXIT_SUCCESS); } else { usage(EXIT_FAILURE); } } if (opt_C) { int countback = atoi(opt_C); /* investigate whether -C option argument is numeric */ if (countback > 0) { /* e.g -C 1 or -C 12 */ if (argc - countback < optind) /* -C 666 */ myerror("when using -C %d you need at least %d non-option arguments", countback, countback); else if (argv[argc - countback][0] == '-') /* -C 2 perl -d blah.pl */ myerror("the last argument minus %d appears to be an option!", countback); else { /* -C 1 perl test.cgi */ command_name = mysavestring(mybasename(argv[argc - countback])); } } else if (countback == 0) { /* -C name1 name2 or -C 0 */ if (opt_C[0] == '0' && opt_C[1] == '\0') /* -C 0 */ myerror("-C 0 makes no sense"); else if (strlen(mybasename(opt_C)) != strlen(opt_C)) /* -C dir/name */ myerror("-C option argument should not contain directory components"); else if (opt_C[0] == '-') /* -C -d (?) */ myerror("-C option needs argument"); else /* -C name */ command_name = opt_C; } else { /* -C -2 */ myerror ("-C option needs string or positive number as argument, perhaps you meant -C %d?", -countback); } } else { /* no -C option given, use command name */ command_name = mysavestring(mybasename(argv[optind])); } assert(command_name != NULL); return command_name; }