/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit(void) { FILE *el_err; #define editing (Eflag || Vflag) if (iflag == 1) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(histsizeval()); else out2str("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ char *term, *shname; INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_out == NULL) goto bad; el_err = el_out; #if DEBUG if (tracefile) el_err = tracefile; #endif term = lookupvar("TERM"); if (term) setenv("TERM", term, 1); else unsetenv("TERM"); shname = arg0; if (shname[0] == '-') shname++; el = el_init(shname, el_in, el_out, el_err); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); el_set(el, EL_SIGNAL, 1); el_set(el, EL_ALIAS_TEXT, alias_text, NULL); el_set(el, EL_ADDFN, "rl-complete", "ReadLine compatible completion function", _el_fn_complete); } else { bad: out2str("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { el_source(el, NULL); if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_BIND, "^I", tabcomplete ? "rl-complete" : "ed-insert", NULL); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }
/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit(void) { #define editing (Eflag || Vflag) if (iflag) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(histsizeval()); else out2fmt_flush("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ char *term; INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_err == NULL) el_err = fdopen(1, "w"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_err == NULL || el_out == NULL) goto bad; term = lookupvar("TERM"); if (term) { if (setenv("TERM", term, 1) == -1) error("setenv: cannot set TERM=1"); } else unsetenv("TERM"); el = el_init(arg0, el_in, el_out, el_err); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); el_set(el, EL_ADDFN, "rl-complete", "ReadLine compatible completion function", _el_fn_complete); } else { bad: out2fmt_flush("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_BIND, "^I", tabcomplete ? "rl-complete" : "ed-insert", NULL); el_source(el, NULL); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }
/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit() { #define editing (Eflag || Vflag) if (iflag) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(histsizeval()); else out2str("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_out == NULL) goto bad; el = el_init(arg0, el_in, el_out); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); } else { bad: out2str("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }
static void setspec(struct tbl *vp) { mksh_ari_u num; char *s; int st; switch ((st = special(vp->name))) { #if HAVE_PERSISTENT_HISTORY case V_HISTFILE: sethistfile(str_val(vp)); return; #endif case V_IFS: setctypes(s = str_val(vp), C_IFS); ifs0 = *s; return; case V_PATH: if (path) afree(path, APERM); s = str_val(vp); strdupx(path, s, APERM); /* clear tracked aliases */ flushcom(true); return; case V_TMPDIR: if (tmpdir) { afree(tmpdir, APERM); tmpdir = NULL; } /* * Use tmpdir iff it is an absolute path, is writable * and searchable and is a directory... */ { struct stat statb; s = str_val(vp); /* LINTED use of access */ if (mksh_abspath(s) && access(s, W_OK|X_OK) == 0 && stat(s, &statb) == 0 && S_ISDIR(statb.st_mode)) strdupx(tmpdir, s, APERM); } return; /* common sub-cases */ case V_COLUMNS: case V_LINES: if (vp->flag & IMPORT) { /* do not touch */ unspecial(vp->name); vp->flag &= ~SPECIAL; return; } /* FALLTHROUGH */ case V_HISTSIZE: case V_LINENO: case V_OPTIND: case V_RANDOM: case V_SECONDS: case V_TMOUT: vp->flag &= ~SPECIAL; if (getint(vp, &num, false) == -1) { s = str_val(vp); if (st != V_RANDOM) errorf("%s: %s: %s", vp->name, "bad number", s); num.u = hash(s); } vp->flag |= SPECIAL; break; default: /* do nothing, do not touch vp at all */ return; } /* process the singular parts of the common cases */ switch (st) { case V_COLUMNS: if (num.i >= MIN_COLS) x_cols = num.i; break; case V_HISTSIZE: sethistsize(num.i); break; case V_LINENO: /* The -1 is because line numbering starts at 1. */ user_lineno = num.u - (mksh_uari_t)current_lineno - 1; break; case V_LINES: if (num.i >= MIN_LINS) x_lins = num.i; break; case V_OPTIND: getopts_reset((int)num.i); break; case V_RANDOM: /* * mksh R39d+ no longer has the traditional repeatability * of $RANDOM sequences, but always retains state */ rndset((unsigned long)num.u); break; case V_SECONDS: { struct timeval tv; mksh_TIME(tv); seconds = tv.tv_sec - num.i; } break; case V_TMOUT: ksh_tmout = num.i >= 0 ? num.i : 0; break; } }
/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit(void) { #define editing (Eflag || Vflag) if (iflag) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(histsizeval()); else out2fmt_flush("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ char *term; INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_out == NULL) goto bad; term = lookupvar("TERM"); if (term) setenv("TERM", term, 1); else unsetenv("TERM"); el = el_init(arg0, el_in, el_out, el_out); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); el_set(el, EL_ADDFN, "sh-complete", "Filename completion", _el_fn_sh_complete); } else { bad: out2fmt_flush("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); /* * Set CTRL+R to history search for compatibility with * other operating systems' default shells. */ el_set(el, EL_BIND, "^R", "em-inc-search-prev", NULL); el_set(el, EL_BIND, "^I", "sh-complete", NULL); el_source(el, NULL); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }
/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit(void) { #define editing (Eflag || Vflag) if (iflag) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(histsizeval()); else out2str("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_err == NULL) el_err = fdopen(1, "w"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_err == NULL || el_out == NULL) goto bad; el = el_init(arg0, el_in, el_out, el_err); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); } else { bad: out2str("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_ADDFN, "ed-do-complete", "Complete Argument", complete); el_set(el, EL_ADDFN, "ed-list-complete", "List Argument Completions", complete_list); el_set(el, EL_ADDFN, "ed-maybe-complete", "Complete Argument Or List Completions", complete_or_list); el_set(el, EL_ADDFN, "ed-expand", "Expand Completions", complete_expand); el_set(el, EL_BIND, "^I", "ed-maybe-complete", NULL); el_set(el, EL_BIND, "-a", "=", "ed-list-complete", NULL); el_set(el, EL_BIND, "-a", "\\\\", "ed-do-complete", NULL); el_set(el, EL_BIND, "-a", "*", "ed-expand", NULL); el_source(el, NULL); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }