//------------------------------------------------------------------------------ void save_history() { int max_history; char buffer[1024]; const char* c; if (get_clink_setting_int("persist_history") == 0) { return; } get_history_file_name(buffer, sizeof(buffer)); // Get max history size. c = rl_variable_value("history-size"); max_history = (c != NULL) ? atoi(c) : 1000; // Write new history to the file, and truncate to our maximum. if (append_history(g_new_history_count, buffer) != 0) { write_history(buffer); } history_truncate_file(buffer, max_history); }
//------------------------------------------------------------------------------ void save_history() { int max_history; char buffer[512]; get_history_file_name(buffer, sizeof(buffer)); // Get max history size. max_history = get_clink_setting_int("history_file_lines"); max_history = (max_history == 0) ? INT_MAX : max_history; if (max_history < 0) { unlink(buffer); return; } // Write new history to the file, and truncate to our maximum. if (append_history(g_new_history_count, buffer) != 0) { write_history(buffer); } if (max_history != INT_MAX) { history_truncate_file(buffer, max_history); } g_new_history_count = 0; }
static int cmd_loop(int in_argc, const char *in_argv[]) { int argc; char *input, **argv; int quit = 0; char *history_path; history_path = load_history(); while (!quit) { input = readline("> "); append_history(history_path, input); if ((tokenize_command_line(input, &argc, &argv) == -1) || argc < 1) { free(input); continue; } int cmd = str_to_cmd(argv[0]); if (cmd == CMD_UNKNOWN || CMD_INTERACTIVE) { warnx("'%s': unknown command", argv[0]); free(argv); free(input); continue; } do_cmd(cmd, --argc, (const char **) ++argv); free(--argv); free(input); } return AFC_E_SUCCESS; }
static PyObject * append_history_file(PyObject *self, PyObject *args) { int nelements; PyObject *filename_obj = Py_None, *filename_bytes; char *filename; int err; if (!PyArg_ParseTuple(args, "i|O:append_history_file", &nelements, &filename_obj)) return NULL; if (filename_obj != Py_None) { if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) return NULL; filename = PyBytes_AsString(filename_bytes); } else { filename_bytes = NULL; filename = NULL; } errno = err = append_history(nelements, filename); if (!err && _history_length >= 0) history_truncate_file(filename, _history_length); Py_XDECREF(filename_bytes); errno = err; if (errno) return PyErr_SetFromErrno(PyExc_IOError); Py_RETURN_NONE; }
/* * Here's our exit function. Just make sure everything * is freed, and any open files are closed. Added exit * message if you have anything to say, if you don't * you can pass it NULL and nothing will be printed. */ void exit_clean(int ret_no, const char *exit_message){ /*This is a bit hacky, try to append_history. *if that doesn't work, write history, which creates *the file, then writes to it. Should suffice for now. */ if(history){ if(append_history(1000, history_filename) != 0) if(write_history(history_filename) != 0){ write_to_log(SHELL_OOPS, "could not write history"); perror("history"); } } if(input) free(input); if(history_filename) free(history_filename); if(env) free(env); if(rc_file) fclose(rc_file); if(PS1 && specified_PS1 == 1) free(PS1); if(log_open) fclose(log_file); if(exit_message) fprintf(stderr,"%s", exit_message); exit(ret_no); }
/* Read a string, and return a pointer to it. Returns NULL on EOF. */ char * vtysh_rl_gets () { HIST_ENTRY *last; /* If the buffer has already been allocated, return the memory * to the free pool. */ if (line_read) { free (line_read); line_read = NULL; } /* Get a line from the user. Change prompt according to node. XXX. */ line_read = readline (vtysh_prompt ()); /* If the line has any text in it, save it on the history. But only if * last command in history isn't the same one. */ if (line_read && *line_read) { using_history(); last = previous_history(); if (!last || strcmp (last->line, line_read) != 0) { add_history (line_read); append_history(1,history_file); } } return (line_read); }
static int console_update_history(const char *histfile) { int ret = 0; #ifdef HAVE_READLINE int max_history_length, truncate_entries; /* * Calculate how much we should keep in the current history file. */ max_history_length = (me) ? me->history_length : 100; truncate_entries = max_history_length - history_length; if (truncate_entries < 0) { truncate_entries = 0; } /* * First, try to truncate the history file, and if it * fails, the file is probably not present, and we * can use write_history to create it. */ if (history_truncate_file(histfile, truncate_entries) == 0) { ret = append_history(history_length, histfile); } else { ret = write_history(histfile); } #endif return ret; }
static int rtnpw(BW *bw) { W *w = bw->parent; PW *pw = (PW *) bw->object; unsigned char *s; W *win; int *notify; int (*pfunc) (); void *object; long byte; /* Extract entered text from buffer */ p_goto_eol(bw->cursor); byte = bw->cursor->byte; p_goto_bol(bw->cursor); s = brvs(bw->cursor, (int) (byte - bw->cursor->byte)); /* Save text into history buffer */ if (pw->hist) { if (bw->b->changed) { append_history(pw->hist, sv(s)); } else { promote_history(pw->hist, bw->cursor->line); } } /* Do ~ expansion and set new current directory */ if (pw->file_prompt&2) { set_current_dir(s,1); } if (pw->file_prompt) { s = canonical(s); } win = w->win; pfunc = pw->pfunc; object = pw->object; bwrm(bw); joe_free(pw->prompt); joe_free(pw); w->object = NULL; notify = w->notify; w->notify = 0; wabort(w); dostaupd = 1; /* Call callback function */ if (pfunc) { return pfunc(win->object, s, object, notify); } else { return -1; } }
bool ReadLine::get(const String& prompt, String& out) { char *line = readline(prompt.c_str()); if (line == NULL) { return false; } add_history(line); // Add input to in-memory history append_history(1, m_historyPath.c_str()); out = line; return true; }
int FileVorbis::read_samples(double *buffer, int64_t len) { if(!fd) return 0; // printf("FileVorbis::read_samples 1 %d %d %d %d\n", // history_start, // history_size, // file->current_sample, // len); float **vorbis_output; int bitstream; int accumulation = 0; update_pcm_history(len); // Fill history buffer if(decode_start != decode_end) { ov_pcm_seek(&vf, decode_start); decode_end = decode_start; } while(accumulation < decode_len) { int result = ov_read_float(&vf, &vorbis_output, decode_len - accumulation, &bitstream); //printf("FileVorbis::read_samples 1 %d %d %d\n", result, len, accumulation); if(!result) break; append_history(vorbis_output, result); accumulation += result; } read_history(buffer, file->current_sample, file->current_channel, len); // printf("FileVorbis::read_samples 2 %d %d %d %d\n", // history_start, // history_size, // file->current_sample, // len); return 0; }
static void add_history_permanent(char *input) { if (!input || !*input) return; if (last_hist_is_temp) { history_rem(history_length); last_hist_is_temp = 0; } last_hist_offset = -1; HIST_ENTRY *entry = history_get(history_length); if (entry && !strcmp(input, entry->line)) return; last_hist_offset = where_history(); add_history(input); if (history_file) append_history(1, history_file); }
//------------------------------------------------------------------------------ void save_history() { static const int max_history = 200; char buffer[1024]; get_history_file_name(buffer, sizeof(buffer)); // Write new history to the file, and truncate to our maximum. if (append_history(g_new_history_count, buffer) != 0) { write_history(buffer); } history_truncate_file(buffer, max_history); }
void Console::run() { while (!stopping) { QCoreApplication::processEvents(); char *s = readline(QString("%1> ").arg(name).toAscii()); if (s && *s) { add_history(s); int ret; if ((ret = append_history(1, historyFile.toAscii().constData()))) { qDebug() << "Could not append to histoy file " << historyFile.toAscii().constData() << " " << strerror(ret); } } interpreter->handleString(QString(s)); free(s); } QCoreApplication::quit(); }
void append_to_history() { char *hf = tilde_expand(HISTORY_FILE); #ifdef USE_READLINE append_history(1, hf); #else #if defined(RL_READLINE_VERSION) HIST_ENTRY *he = history_get(history_base+history_length-1); #else // libedit-2 segfaults if we add history_base HIST_ENTRY *he = history_get(history_length-1); #endif FILE *fp = fopen(hf, "a"); if (fp) { fprintf(fp, "%s\n", he->line); fclose(fp); } #endif free(hf); }
/* If this is an interactive shell, then append the lines executed this session to the history file. */ int maybe_save_shell_history () { int result = 0; if (history_lines_this_session) { char *hf = get_string_value ("HISTFILE"); if (hf && *hf) { struct stat buf; /* If the file doesn't exist, then create it. */ if (stat (hf, &buf) == -1) { int file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0666); if (file != -1) close (file); } /* Now actually append the lines if the history hasn't been stifled. If the history has been stifled, rewrite the history file. */ using_history (); if (history_lines_this_session <= where_history ()) { result = append_history (history_lines_this_session, hf); history_lines_in_file += history_lines_this_session; } else { result = write_history (hf); history_lines_in_file = history_lines_this_session; } history_lines_this_session = 0; } } return (result); }
/* Write the existing history out to the history file. */ void save_history () { char *hf = get_string_value ("HISTFILE"); if (hf && *hf) { struct stat buf; if (stat (hf, &buf) == 0) { /* Append only the lines that occurred this session to the history file. */ using_history (); if (history_lines_this_session < where_history ()) append_history (history_lines_this_session, hf); else write_history (hf); } } }
void child_hist_trapper_main (int i) { int count; queue_history_entry_t entry; void* history_token; zabbix_log( LOG_LEVEL_DEBUG, "In child_trapper_main()"); zabbix_log( LOG_LEVEL_WARNING, "server #%d started [HistTrapper]", i); queue_fd = queue_get_queue_id (i, 1); key_values = metric_register ("trapper_history_values", i); key_skipped = metric_register ("trapper_history_skipped_bytes", i); metric_update (key_skipped, mtr_skipped); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("Trapper waiting for new history data"); /* First we try to get data from primary queue */ count = trapper_dequeue_history (&entry); if (count) { history_token = NULL; mtr_values += entry.count; metric_update (key_values, mtr_values); for (i = 0; i < entry.count; i++) append_history (entry.server, entry.key, entry.items[i].value, entry.items[i].ts, &history_token); flush_history (&history_token); free (entry.items); } } DBclose(); }
static void eval_event(ferret_list_entry_common_t * e) { //static unsigned short last = -1; //static int count_atomic = 0; //static int count_context = 0; ferret_list_entry_kernel_t * k = (ferret_list_entry_kernel_t *)e; static ferret_utime_t t_start_atomic = 0; static ferret_utime_t t_stop_atomic = 0; static ferret_utime_t t_last_context = 0; static int l4lx_task_id = -1; static int l4lx_tamer_thread_id = -1; static int dump_count = -1; switch (e->major) { case FERRET_L4LX_MAJOR: /* debug stuff ... if (last != FERRET_L4LX_MAJOR) { append_count(count_context); count_context = 0; } count_atomic++; last = FERRET_L4LX_MAJOR; ... debug stuff */ switch (e->minor) { case FERRET_L4LX_ATOMIC_BEGIN: t_start_atomic = e->timestamp; t_stop_atomic = 0; if (l4lx_task_id == -1) // L4Linux kernel's task id { l4lx_task_id = ((l4_threadid_t)(e->data32[0])).id.task; l4lx_tamer_thread_id = ((l4_threadid_t)(e->data32[0])).id.lthread; printf("Tamer TID: %x.%x\n", l4lx_task_id, l4lx_tamer_thread_id); } break; case FERRET_L4LX_ATOMIC_END1: case FERRET_L4LX_ATOMIC_END2: t_stop_atomic = e->timestamp; //printf("%llu:%llu, %llu\n", // t_start_atomic, t_stop_atomic, t_last_context); break; default: //printf("Got other event %hd:%hd:%hd, ignored.\n", // e->major, e->minor, e->instance); break; } break; case FERRET_TBUF_MAJOR: /* debug stuff ... if (last != FERRET_TBUF_MAJOR) { append_count(count_atomic); //printf("Atomic: %d\n", count_atomic); count_atomic = 0; } count_context++; last = FERRET_TBUF_MAJOR; ... debug stuff */ switch (e->minor) { case l4_ktrace_tbuf_context_switch: t_last_context = e->timestamp; if (t_last_context > t_start_atomic && t_stop_atomic == 0 && t_start_atomic != 0) { if (l4lx_task_id == l4_ktrace_get_l4_taskid((void * )k->data32[1]) && l4lx_tamer_thread_id != l4_ktrace_get_l4_lthreadid((void * )k->data32[1])) { if (quiet < 2 ) { printf( l4util_idfmt" -> "l4util_idfmt": " , l4util_idstr(l4_ktrace_get_l4_threadid(k->context)), l4util_idstr(l4_ktrace_get_l4_threadid( (void * )k->data32[1])) ); printf("Atomicity violation: %llu < %llu\n", t_start_atomic, t_last_context); } dump_count = 100; // start count down for dump } } break; default: //printf("Got other event %hd:%hd:%hd, ignored.\n", // e->major, e->minor, e->instance); break; } break; default: //printf("Got other event %hd:%hd:%hd, ignored.\n", // e->major, e->minor, e->instance); break; } append_history(e); if (dump_count > 0) { dump_count--; } if (dump_count == 0) { if (quiet < 1) { uu_dumpz_ringbuffer("atomicity.dump", &history, HISTORY_SIZE * sizeof(history_entry_t), history_position * sizeof(history_entry_t), HISTORY_SIZE * sizeof(history_entry_t)); } dump_count = -1; } }
char *getline() { char *prompt; int len; char *home; int fdh; /* If initialization hasn't been done, do it now: * - We don't want TAB completion */ if (!done_init) { rl_bind_key('\t', rl_insert); /* get history from file */ home = getenv("FVWM_USERDIR"); h_file = safemalloc(strlen(home) + sizeof(HISTFILE) + 1); strcpy(h_file, home); strcat(h_file, HISTFILE); if( access( h_file, F_OK) < 0) { /* if it doesn't exist create it */ fdh = creat( h_file, S_IRUSR | S_IWUSR ); if( fdh != -1 ) { close( fdh ); } } else { read_history_range( h_file, 0, HISTSIZE ); } done_init = 1; } /* Empty out the previous info */ len = 0; *cmd = '\0'; prompt = PS1; while (1) { int linelen = 0; /* If the buffer has already been allocated, free the memory. */ if (line != (char *)NULL) free(line); /* Get a line from the user. */ line = readline(prompt); if (line == NULL) return (NULL); /* Make sure we have enough space for the new line */ linelen = strlen(line); if (len + linelen > MAX_COMMAND_SIZE-2 ) { fprintf( stderr, "line too long %d chars max %d \a\n", len+linelen, MAX_COMMAND_SIZE-2 ); strncat(cmd, line, MAX_COMMAND_SIZE-len-2); add_history(cmd); break; } /* Copy the new line onto the end of the current line */ strcat(cmd, line); /* If the current line doesn't end with a backslash, we're done */ len = strlen(cmd); if (cmd[len-1] != '\\') break; /* Otherwise, remove it and wait for more (add a space if needed) */ prompt = PS2; cmd[len-1] = (cmd[len-2]==' ' || cmd[len-2]=='\t') ? '\0' : ' '; } /* If the command has any text in it, save it on the history. */ if (*cmd != '\0') { add_history(cmd); append_history( 1,h_file ); history_truncate_file( h_file, HISTSIZE ); } cmd[len] = '\n'; cmd[len+1] = '\0'; return (cmd); }
int shell() { int err = 0; extern PCBDLL **PRIORITY_QUEUES; // Makin ur queues PCBDLL_CREATION PRIORITY_QUEUES = PCBDLL_creation( TDF_QUEUES ); buffer_size = BUFFER_SIZE; EXIT_PROMPT_LOOP = 0; strcpy(EXIT_STRING, "exit\0"); welcome_message(); // Debugging check // givemeready(); while (!EXIT_PROMPT_LOOP) { display_prompt(); // `tdf:$ ' currently SYS_REQ_ERR = sys_req(READ, TERMINAL, BUFFER, &buffer_size); err = append_history(BUFFER); PARSER_ERROR = parse_buffer(BUFFER, PARSED_CMD, ARGUMENTS); // The most trivial case if (!strcmp(BUFFER,"\n\0")) { //Just a New Line continue; } switch (PARSER_ERROR) { case PARSER_FAIL_WHITESPACE: continue; break; case PARSER_FAIL_LONGNAME: printf("Invalid command name entered. Must be less than 9 characters.\n"); continue; break; case PARSER_WIN_SINGLETON: //This is linked to PARSER_WIN_HAS_ARGS which follows case PARSER_WIN_HAS_ARGS: if (!strcmp(PARSED_CMD,EXIT_STRING)) { //Equal to EXIT_STRING if(exit_confirmation() == SHELL_EXIT_CONFIRM) { EXIT_PROMPT_LOOP = !EXIT_PROMPT_LOOP; break; } else { continue; } } break; default: printf("I have no idea how you got here. File a bug report!\n"); printf("Parser exited wth status of: %d\n", PARSER_ERROR); continue; break; } if (!strcmp(PARSED_CMD, "date")) { date(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "dispatch")) { dispatch ( ); } else if (!strcmp(PARSED_CMD, "display") || !strcmp(PARSED_CMD, "ls")) { display(ARGUMENTS); continue; } else if (!strcmp(PARSED_CMD, "hossgive")){ givemeready(); } else if (!strcmp(PARSED_CMD, "load")) { load( ARGUMENTS ); } else if (!strcmp(PARSED_CMD, "loadr3")) { loadr3 ( ); } else if (!strcmp(PARSED_CMD, "history")) { history(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "pblock")) { pblock(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "pcreate")) { pcreate(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "pdelete")) { pdelete(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "presume")) { presume(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "psetprio")) { psetprio(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "pshow")) { pshow(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "pshowall")) { pshowall(); } else if (!strcmp(PARSED_CMD, "pshowblk")) { pshowblk(); } else if (!strcmp(PARSED_CMD, "pshowrd")) { pshowrd(); } else if (!strcmp(PARSED_CMD, "psuspend")) { psuspend(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "punblock")) { punblock(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "version")) { version(ARGUMENTS); } else if (!strcmp(PARSED_CMD, "help")) { help(ARGUMENTS); } else { //printf("Command not found.\n"); continue; } } departing_message(); // Clean up our queues PCBDLL_freeall( ); return err; }
int main(int argc, char **real_argv, char **envv) { CAP *cap; unsigned char **argv = (unsigned char **)real_argv; struct stat sbuf; unsigned char *s; unsigned char *t; long time_rc; unsigned char *run; #ifdef __MSDOS__ unsigned char *rundir; #endif SCRN *n; int opened = 0; int omid; int backopt; int c; init_bufs(); for (c = 1; argv[c] != NULL; ++c) { if (0 == zcmp((unsigned char*)argv[c], USTR "-nosys")) { read_sys_configs = 0; } else if (0 == zcmp((unsigned char*)argv[c], USTR "-nouser")) { read_user_configs = 0; } else { argv[--c] = argv[0]; argv += c; argc -= c; break; } } if (read_user_configs) { s = (unsigned char *)getenv("HOME"); if (s) { s = vsncpy(NULL, 0, sz(s)); s = vsncpy(sv(s), sc("/.joe-p37/only.rc")); if (!stat((char*)s, &sbuf)) read_sys_configs = 0; vsrm(s); } } joe_locale(); mainenv = (unsigned char **)envv; #ifdef __MSDOS__ _fmode = O_BINARY; zcpy(stdbuf, argv[0]); joesep(stdbuf); run = namprt(stdbuf); rundir = dirprt(stdbuf); for (c = 0; run[c]; ++c) if (run[c] == '.') { run = vstrunc(run, c); break; } #else run = namprt(argv[0]); #endif env_lines = 0; if ((s = (unsigned char *)getenv("LINES")) != NULL && sscanf((char *)s, "%d", &env_lines) != 1) env_lines = 0; env_columns = 0; if ((s = (unsigned char *)getenv("COLUMNS")) != NULL && sscanf((char *)s, "%d", &env_columns) != 1) env_columns = 0; if ((s = (unsigned char *)getenv("BAUD")) != NULL) sscanf((char *)s, "%u", (unsigned *)&Baud); if (getenv("DOPADDING")) dopadding = 1; if (getenv("NOXON")) noxon = 1; if ((s = (unsigned char *)getenv("JOETERM")) != NULL) joeterm = s; #ifndef __MSDOS__ if (!(cap = my_getcap(NULL, 9600, NULL, NULL))) { fprintf(stderr, (char *)joe_gettext(_("Couldn't load termcap/terminfo entry\n"))); return 1; } #endif #ifdef __MSDOS__ s = vsncpy(NULL, 0, sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c == 0) goto donerc; if (c == 1) { unsigned char buf[8]; fprintf(stderr, (char *)joe_gettext(_("There were errors in '%s'. Use it anyway?")), s); fflush(stderr); if (NULL == fgets(buf, 8, stdin) || yn_checks(yes_key, buf)) goto donerc; } vsrm(s); s = vsncpy(NULL, 0, sv(rundir)); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c != 0 && c != 1) { /* If built-in *fancyjoerc not present, process builtin *joerc, * which is always present. */ s = vstrunc(s, 0); s = vsncpy(sv(s), sc("*joerc")); c = procrc(cap, s); } if (c == 0) goto donerc; if (c == 1) { unsigned char buf[8]; fprintf(stderr, (char *)joe_gettext(_("There were errors in '%s'. Use it anyway?")), s); fflush(stderr); if (NULL == fgets(buf, 8, stdin) || yn_checks(yes_key, buf)) goto donerc; } #else /* Name of system joerc file. Try to find one with matching language... */ /* Try full language: like joerc.de_DE */ time_rc = 0; if (!read_sys_configs) { t = NULL; goto skip_joerc; } t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc.")); t = vsncpy(sv(t), sz(locale_msgs)); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else { /* Try generic language: like joerc.de */ if (locale_msgs[0] && locale_msgs[1] && locale_msgs[2]=='_') { vsrm(t); t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc.")); t = vsncpy(sv(t), locale_msgs, 2); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else goto nope; } else { nope: vsrm(t); /* Try Joe's bad english */ t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc")); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else { /* If built-in *fancyjoerc not present, process builtin *joerc, * which is always present. */ t = vstrunc(s, 0); t = vsncpy(sv(s), sc("*joerc")); time_rc = stat((char *)t,&sbuf) ? 0 : sbuf.st_mtime; } } } skip_joerc: /* User's joerc file */ s = (unsigned char *)getenv("HOME"); if (s && !read_sys_configs) { if (read_user_configs) { /* TODO(pts): Don't read /dev/null */ s = vsncpy(NULL, 0, sz(s)); s = vsncpy(sv(s), sc("/.joe-p37/rc")); } else { s = vsncpy(NULL, 0, sc("/dev/null/missing")); } goto process_user_rc; } else if (!read_user_configs) { s = vsncpy(NULL, 0, sc("/dev/null/missing")); goto process_user_rc; } else if (s) { unsigned char buf[8]; s = vsncpy(NULL, 0, sz(s)); s = vsncpy(sv(s), sc("/.")); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); if (!stat((char *)s,&sbuf)) { if (sbuf.st_mtime < time_rc) { fprintf(stderr,(char *)joe_gettext(_("Warning: %s is newer than your %s.\n")),t,s); fprintf(stderr,(char *)joe_gettext(_("You should update or delete %s\n")),s); fprintf(stderr,(char *)joe_gettext(_("Hit enter to continue with %s ")),t); fflush(stderr); (void)!fgets((char *)buf, 8, stdin); goto use_sys; } } process_user_rc: c = procrc(cap, s); if (c == 0) { vsrm(t); goto donerc; } if (c == 1) { fprintf(stderr,(char *)joe_gettext(_("There were errors in '%s'. Use it anyway (y,n)? ")), s); fflush(stderr); if (NULL == fgets((char *)buf, 8, stdin) || ynchecks(yes_key, buf)) { vsrm(t); goto donerc; } } } use_sys: vsrm(s); s = t; c = s ? procrc(cap, s) : -1; if (c == 0) goto donerc; if (c == 1) { unsigned char buf[8]; fprintf(stderr,(char *)joe_gettext(_("There were errors in '%s'. Use it anyway (y,n)? ")), s); fflush(stderr); if (NULL == fgets((char *)buf, 8, stdin) || ynchecks(yes_key, buf)) goto donerc; } /* Try built-in *fancyjoerc, e.g. "*joe-p37rc" */ vsrm(s); s = vsncpy(NULL, 0, sc("*")); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c != 0 && c != 1) { /* If built-in *fancyjoerc not present, process builtin "*joerc", * which is always present. */ s = vstrunc(s, 0); s = vsncpy(sv(s), sc("*joerc")); c = procrc(cap, s); } if (c == 0) goto donerc; if (c == 1) { unsigned char buf[8]; fprintf(stderr,(char *)joe_gettext(_("There were errors in '%s'. Use it anyway (y,n)? ")), s); fflush(stderr); if (NULL == fgets((char *)buf, 8, stdin) || ynchecks(yes_key, buf)) goto donerc; } #endif fprintf(stderr,(char *)joe_gettext(_("Couldn't open '%s'\n")), s); vsrm(s); return 1; donerc: vsrm(s); if (validate_rc()) { fprintf(stderr,(char *)joe_gettext(_("rc file has no :main key binding section or no bindings. Bye.\n"))); return 1; } if (!isatty(fileno(stdin))) idleout = 0; for (c = 1; argv[c]; ++c) { if (argv[c][0] == '-') { if (argv[c][1]) switch (glopt(argv[c] + 1, argv[c + 1], NULL, 1)) { case 0: fprintf(stderr,(char *)joe_gettext(_("Unknown option '%s'\n")), argv[c]); break; case 1: break; case 2: ++c; break; } else idleout = 0; } } if (!dspasis) { /* Open all files as ASCII by default if `joe --asis' is specified. This is to avoid writing control characters to the UTF-8 terminal. */ fdefault.charmap = pdefault.charmap = find_charmap(USTR "ascii"); fdefault.map_name = pdefault.map_name = USTR "ascii"; } /* initialize mouse support */ if (xmouse && (s=(unsigned char *)getenv("TERM")) && strstr((char *)s,"xterm")) usexmouse=1; if (!(n = nopen(cap))) return 1; maint = screate(n); vmem = vtmp(); startup_log = bfind_scratch_incref(USTR "* Startup Log *"); startup_log->internal = 1; load_state(); /* It would be better if this ran uedit() to load files */ /* The business with backopt is to load the file first, then apply file * local options afterwords */ /* orphan is not compatible with exemac()- macros need a window to exist */ for (c = 1, backopt = 0; argv[c]; ++c) if (argv[c][0] == '+' && argv[c][1]>='0' && argv[c][1]<='9') { if (!backopt) backopt = c; } else if (argv[c][0] == '-' && argv[c][1]) { if (!backopt) backopt = c; if (glopt(argv[c] + 1, argv[c + 1], NULL, 0) == 2) ++c; } else { B *b = bfind_incref(argv[c]); BW *bw = NULL; int er = berror; /* This is too annoying */ /* set_current_dir(argv[c],1); */ setup_history(&filehist); append_history(filehist,sz(argv[c])); /* wmktw_takeref() inserts the window before maint->curwin */ if (!orphan || !opened) { bw = wmktw_takeref(maint, b); if (er) msgnwt(bw->parent, joe_gettext(msgs[-er])); } else { long line; b->orphan = 1; b->oldcur = pdup(b->bof, USTR "main"); pline(b->oldcur, get_file_pos(b->name)); line = b->oldcur->line - (maint->h - 1) / 2; if (line < 0) line = 0; b->oldtop = pdup(b->oldcur, USTR "main"); pline(b->oldtop, line); p_goto_bol(b->oldtop); } if (bw) { long lnum = 0; bw->o.readonly = bw->b->rdonly; if (backopt) { while (backopt != c) { if (argv[backopt][0] == '+') { sscanf((char *)(argv[backopt] + 1), "%ld", &lnum); ++backopt; } else { if (glopt(argv[backopt] + 1, argv[backopt + 1], &bw->o, 0) == 2) backopt += 2; else backopt += 1; lazy_opts(bw->b, &bw->o); } } } bw->b->o = bw->o; bw->b->rdonly = bw->o.readonly; /* Put cursor in window, so macros work properly */ maint->curwin = bw->parent; /* Execute macro */ if (er == -1 && bw->o.mnew) exmacro(bw->o.mnew,1); if (er == 0 && bw->o.mold) exmacro(bw->o.mold,1); /* Hmm... window might not exist any more... depends on what macro does... */ if (lnum > 0) pline(bw->cursor, lnum - 1); else pline(bw->cursor, get_file_pos(bw->b->name)); p_goto_bol(bw->cursor); /* Go back to first window so windows are in same order as command line */ if (opened) wnext(maint); } opened = 1; backopt = 0; } if (opened) { wshowall(maint); omid = mid; mid = 1; dofollows(); mid = omid; } else { BW *bw = wmktw_takeref(maint, bfind_incref(USTR "")); if (bw->o.mnew) exmacro(bw->o.mnew,1); } maint->curwin = maint->topwin; if (startup_log->eof->byte) { BW *bw = wmktw_takeref(maint, startup_log); startup_log = NULL; maint->curwin = bw->parent; wshowall(maint); uparserr(bw); } if (help) { help_on(maint); } if (!nonotice) { joe_snprintf_3(msgbuf,JOE_MSGBUFSIZE,joe_gettext(_("\\i** Joe's Own Editor v%s ** (%s) ** Copyright %s 2008 **\\i")),VERSION,locale_map->name,(locale_map->type ? "©" : "(C)")); msgnw(((BASE *)lastw(maint)->object)->parent, msgbuf); } if (!idleout) { if (!isatty(fileno(stdin)) && modify_logic(maint->curwin->object, ((BW *)maint->curwin->object)->b)) { /* Start shell going in first window */ unsigned char **a; unsigned char *cmd; a = vamk(10); cmd = vsncpy(NULL, 0, sc("/bin/sh")); a = vaadd(a, cmd); cmd = vsncpy(NULL, 0, sc("-c")); a = vaadd(a, cmd); cmd = vsncpy(NULL, 0, sc("/bin/cat")); a = vaadd(a, cmd); cstart (maint->curwin->object, USTR "/bin/sh", a, NULL, NULL, 0, 1); } } edloop(0); save_state(); /* Delete all buffer so left over locks get eliminated */ brmall(); vclose(vmem); nclose(n); if (exmsg) fprintf(stderr, "\n%s\n", exmsg); return 0; }
/* * This function saves the readline history when user * runs \s command or when psql exits. * * fname: pathname of history file. (Should really be "const char *", * but some ancient versions of readline omit the const-decoration.) * * max_lines: if >= 0, limit history file to that many entries. * * appendFlag: if true, try to append just our new lines to the file. * If false, write the whole available history. * * encodeFlag: whether to encode \n as \x01. For \s calls we don't wish * to do that, but must do so when saving the final history file. */ bool saveHistory(char *fname, int max_lines, bool appendFlag, bool encodeFlag) { #ifdef USE_READLINE /* * Suppressing the write attempt when HISTFILE is set to /dev/null may * look like a negligible optimization, but it's necessary on e.g. Darwin, * where write_history will fail because it tries to chmod the target * file. */ if (useHistory && fname && strcmp(fname, DEVNULL) != 0) { if (encodeFlag) encode_history(); /* * On newer versions of libreadline, truncate the history file as * needed and then append what we've added. This avoids overwriting * history from other concurrent sessions (although there are still * race conditions when two sessions exit at about the same time). If * we don't have those functions, fall back to write_history(). * * Note: return value of write_history is not standardized across GNU * readline and libedit. Therefore, check for errno becoming set to * see if the write failed. Similarly for append_history. */ #if defined(HAVE_HISTORY_TRUNCATE_FILE) && defined(HAVE_APPEND_HISTORY) if (appendFlag) { int nlines; int fd; /* truncate previous entries if needed */ if (max_lines >= 0) { nlines = Max(max_lines - history_lines_added, 0); (void) history_truncate_file(fname, nlines); } /* append_history fails if file doesn't already exist :-( */ fd = open(fname, O_CREAT | O_WRONLY | PG_BINARY, 0600); if (fd >= 0) close(fd); /* append the appropriate number of lines */ if (max_lines >= 0) nlines = Min(max_lines, history_lines_added); else nlines = history_lines_added; errno = 0; (void) append_history(nlines, fname); if (errno == 0) return true; } else #endif { /* truncate what we have ... */ if (max_lines >= 0) stifle_history(max_lines); /* ... and overwrite file. Tough luck for concurrent sessions. */ errno = 0; (void) write_history(fname); if (errno == 0) return true; } psql_error("could not save history to file \"%s\": %s\n", fname, strerror(errno)); } #else /* only get here in \s case, so complain */ psql_error("history is not supported by this installation\n"); #endif return false; }
int main(int argc, char **real_argv, char **envv) { CAP *cap; unsigned char **argv = (unsigned char **)real_argv; struct stat sbuf; unsigned char *s; unsigned char *t; long time_rc; unsigned char *run; #ifdef __MSDOS__ unsigned char *rundir; #endif SCRN *n; int opened = 0; int omid; int backopt; int c; joe_locale(); mainenv = (unsigned char **)envv; vmem = vtmp(); startup_log = bfind_scratch(USTR "* Startup Log *"); startup_log->internal = 1; #ifdef __MSDOS__ _fmode = O_BINARY; zlcpy(stdbuf, sizeof(stdbuf), argv[0]); joesep(stdbuf); run = namprt(stdbuf); rundir = dirprt(stdbuf); for (c = 0; run[c]; ++c) if (run[c] == '.') { run = vstrunc(run, c); break; } #else run = namprt(argv[0]); #endif if ((s = (unsigned char *)getenv("LINES")) != NULL) sscanf((char *)s, "%d", &lines); if ((s = (unsigned char *)getenv("COLUMNS")) != NULL) sscanf((char *)s, "%d", &columns); if ((s = (unsigned char *)getenv("BAUD")) != NULL) sscanf((char *)s, "%u", (unsigned *)&Baud); if (getenv("DOPADDING")) dopadding = 1; if (getenv("NOXON")) noxon = 1; if ((s = (unsigned char *)getenv("JOETERM")) != NULL) joeterm = s; #ifndef __MSDOS__ if (!(cap = my_getcap(NULL, 9600, NULL, NULL))) { logerror_0((char *)joe_gettext(_("Couldn't load termcap/terminfo entry\n"))); goto exit_errors; } #endif #ifdef __MSDOS__ s = vsncpy(NULL, 0, sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c == 0) goto donerc; if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } vsrm(s); s = vsncpy(NULL, 0, sv(rundir)); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c == 0) goto donerc; if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } #else /* Name of system joerc file. Try to find one with matching language... */ /* Try full language: like joerc.de_DE */ t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc.")); t = vsncpy(sv(t), sz(locale_msgs)); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else { /* Try generic language: like joerc.de */ if (locale_msgs[0] && locale_msgs[1] && locale_msgs[2]=='_') { vsrm(t); t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc.")); t = vsncpy(sv(t), locale_msgs, 2); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else goto nope; } else { nope: vsrm(t); /* Try Joe's bad english */ t = vsncpy(NULL, 0, sc(JOERC)); t = vsncpy(sv(t), sv(run)); t = vsncpy(sv(t), sc("rc")); if (!stat((char *)t,&sbuf)) time_rc = sbuf.st_mtime; else time_rc = 0; } } /* User's joerc file */ s = (unsigned char *)getenv("HOME"); if (s) { s = vsncpy(NULL, 0, sz(s)); s = vsncpy(sv(s), sc("/.")); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); if (!stat((char *)s,&sbuf)) { if (sbuf.st_mtime < time_rc) { logmessage_2((char *)joe_gettext(_("Warning: %s is newer than your %s.\n")),t,s); } } c = procrc(cap, s); if (c == 0) { vsrm(t); goto donerc; } if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } } vsrm(s); s = t; c = procrc(cap, s); if (c == 0) goto donerc; if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } /* Try built-in joerc */ s = vsncpy(NULL, 0, sc("*")); s = vsncpy(sv(s), sv(run)); s = vsncpy(sv(s), sc("rc")); c = procrc(cap, s); if (c != 0 && c != 1) { /* If *fancyjoerc not present, use *joerc which is always there */ s = vstrunc(s, 0); s = vsncpy(sv(s),sc("*joerc")); c = procrc(cap, s); } if (c == 0) goto donerc; if (c == 1) { logerror_1((char *)joe_gettext(_("There were errors in '%s'. Falling back on default.\n")), s); } #endif logerror_1((char *)joe_gettext(_("Couldn't open '%s'\n")), s); goto exit_errors; return 1; donerc: if (validate_rc()) { logerror_0((char *)joe_gettext(_("rc file has no :main key binding section or no bindings. Bye.\n"))); goto exit_errors; } { unsigned char buf[10]; int x; zlcpy(buf, sizeof(buf), USTR "\"`\" ` "); type_backtick = mparse(0, buf, &x, 0); } shell_kbd = mkkbd(kmap_getcontext(USTR "shell")); if (!isatty(fileno(stdin))) idleout = 0; for (c = 1; argv[c]; ++c) { if (argv[c][0] == '-') { if (argv[c][1]) switch (glopt(argv[c] + 1, argv[c + 1], NULL, 1)) { case 0: logerror_1((char *)joe_gettext(_("Unknown option '%s'\n")), argv[c]); break; case 1: break; case 2: ++c; break; } else idleout = 0; } } /* initialize mouse support */ if (xmouse && (s=(unsigned char *)getenv("TERM")) && strstr((char *)s,"xterm")) usexmouse=1; if (!(n = nopen(cap))) goto exit_errors; maint = screate(n); load_state(); /* It would be better if this ran uedit() to load files */ /* The business with backopt is to load the file first, then apply file * local options afterwords */ /* orphan is not compatible with exemac()- macros need a window to exist */ for (c = 1, backopt = 0; argv[c]; ++c) if (argv[c][0] == '+' && argv[c][1]>='0' && argv[c][1]<='9') { if (!backopt) backopt = c; } else if (argv[c][0] == '-' && argv[c][1]) { if (!backopt) backopt = c; if (glopt(argv[c] + 1, argv[c + 1], NULL, 0) == 2) ++c; } else { B *b = bfind(argv[c]); BW *bw = NULL; int er = berror; /* This is too annoying */ /* set_current_dir(argv[c],1); */ setup_history(&filehist); append_history(filehist,sz(argv[c])); /* wmktw inserts the window before maint->curwin */ if (!orphan || !opened) { bw = wmktw(maint, b); if (er) msgnwt(bw->parent, joe_gettext(msgs[-er])); } else { long line; b->orphan = 1; b->oldcur = pdup(b->bof, USTR "main"); pline(b->oldcur, get_file_pos(b->name)); p_goto_bol(b->oldcur); line = b->oldcur->line - (maint->h - 1) / 2; if (line < 0) line = 0; b->oldtop = pdup(b->oldcur, USTR "main"); pline(b->oldtop, line); p_goto_bol(b->oldtop); } if (bw) { long lnum = 0; bw->o.readonly = bw->b->rdonly; if (backopt) { while (backopt != c) { if (argv[backopt][0] == '+') { sscanf((char *)(argv[backopt] + 1), "%ld", &lnum); ++backopt; } else { if (glopt(argv[backopt] + 1, argv[backopt + 1], &bw->o, 0) == 2) backopt += 2; else backopt += 1; lazy_opts(bw->b, &bw->o); } } } bw->b->o = bw->o; bw->b->rdonly = bw->o.readonly; /* Put cursor in window, so macros work properly */ maint->curwin = bw->parent; /* Execute macro */ if (er == -1 && bw->o.mnew) exmacro(bw->o.mnew,1); if (er == 0 && bw->o.mold) exmacro(bw->o.mold,1); /* Hmm... window might not exist any more... depends on what macro does... */ if (lnum > 0) pline(bw->cursor, lnum - 1); else pline(bw->cursor, get_file_pos(bw->b->name)); p_goto_bol(bw->cursor); /* Go back to first window so windows are in same order as command line */ if (opened) wnext(maint); } opened = 1; backopt = 0; } if (opened) { wshowall(maint); omid = mid; mid = 1; dofollows(); mid = omid; } else { BW *bw = wmktw(maint, bfind(USTR "")); if (bw->o.mnew) exmacro(bw->o.mnew,1); } maint->curwin = maint->topwin; if (logerrors) { B *copied = bcpy(startup_log->bof, startup_log->eof); BW *bw = wmktw(maint, copied); copied->name = zdup(startup_log->name); copied->internal = 1; maint->curwin = bw->parent; wshowall(maint); } if (help) { help_on(maint); } if (!nonotice) { joe_snprintf_3(msgbuf,JOE_MSGBUFSIZE,joe_gettext(_("\\i** Joe's Own Editor v%s ** (%s) ** Copyright %s 2015 **\\i")),VERSION,locale_map->name,(locale_map->type ? "©" : "(C)")); msgnw(((BASE *)lastw(maint)->object)->parent, msgbuf); } if (!idleout) { if (!isatty(fileno(stdin)) && modify_logic(maint->curwin->object, ((BW *)maint->curwin->object)->b)) { /* Start shell going in first window */ unsigned char **a; unsigned char *cmd; a = vamk(10); cmd = vsncpy(NULL, 0, sc("/bin/sh")); a = vaadd(a, cmd); cmd = vsncpy(NULL, 0, sc("-c")); a = vaadd(a, cmd); cmd = vsncpy(NULL, 0, sc("/bin/cat")); a = vaadd(a, cmd); cstart (maint->curwin->object, USTR "/bin/sh", a, NULL, NULL, 0, 1, NULL, 0); } } edloop(0); save_state(); /* Delete all buffer so left over locks get eliminated */ brmall(); vclose(vmem); nclose(n); if (noexmsg) { if (notite) fprintf(stderr, "\n"); } else { if (exmsg) fprintf(stderr, "\n%s\n", exmsg); else if (notite) fprintf(stderr, "\n"); } return 0; exit_errors: /* Write out error log to console if we are exiting with errors. */ if (startup_log && startup_log->eof->byte) bsavefd(startup_log->bof, 2, startup_log->eof->byte); return 1; }
int gnu_readline_append_history(char *filename) { return append_history(gnu_history_newlines, filename); }
int do_cmd(char *input, char *cwd, history_t history, FILE *in, FILE *out) { char *tokens[SIZE]; char *trim; int len; int num_tokens; int pid; int backgnd = 0; // trim leading whitespace trim = input; while (*trim == ' ') trim++; len = strlen(trim); if (len == 1) return 0; // remove trailing newlines if (trim[len-1] == '\n') trim[len-1] = '\0'; // check to see if the user is trying to replay history right away if (strncmp(trim, "!", 1) == 0) { if (replay_history(history, get_val(trim + sizeof(char)), input)) { fprintf(stderr, "Line '%s' not found\n", trim + sizeof(char)); return 0; } return do_cmd(input, cwd, history, in, out); } // don't store history replay's in the history append_history(history, trim); // tokenize num_tokens = tokenize(trim, tokens); // built-ins // internal exit command if (!strncmp(tokens[0], "quit", 5) || !strncmp(tokens[0], "exit", 5) ) { return EXIT_NORMAL; } // print working directory if (!strncmp(tokens[0], "pwd", 4)) { printf("%s\n", cwd); return 0; } // print all history if (!strncmp(tokens[0], "history", 8)) { print_history(history); return 0; } // print all jobs if (!strncmp(tokens[0], "jobs", 5)) { print_job_list(); return 0; } // change to a directory if (strncmp(tokens[0], "cd", 2) == 0) { if (num_tokens > 2) { if (chdir(tokens[1])) { perror("No such file or directory"); } else { // on success, reset cwd if (getcwd(cwd, sizeof(char) * SIZE) == NULL) { perror("getcwd() error"); return 1; } } } return 0; } // do some token scraping for redirection if (check_for_specials(tokens, num_tokens, &in, &out, &backgnd)) return 0; if ((pid = fork()) < 0) { perror("fork failure"); return 1; } else if (pid == 0) { // allow inpout and output redirection if (in) dup2(fileno(in), STDIN_FILENO); if (out) dup2(fileno(out), STDOUT_FILENO); // kick off this wild ride if (execvp(tokens[0], tokens) < 0) { fprintf(stderr, "No command \'%s\' found\n", tokens[0]); exit(1); } // here be unreachable } else { // add job to list of running jobs len = add_job(pid, tokens); if (!backgnd) { while(last_corpse != pid); printf("Process returned: %d\n", last_corpse_status); } else { printf("[%d] %d\n", len, pid); } return 0; } // The compiler doesn't see the exec, and thinks a // child could make it here fprintf(stderr, "Warning: child escaped!\n"); return 0; }
static bool saveHistory(char *fname, int max_lines) { int errnum; /* * Suppressing the write attempt when HISTFILE is set to /dev/null may * look like a negligible optimization, but it's necessary on e.g. Darwin, * where write_history will fail because it tries to chmod the target * file. */ if (strcmp(fname, DEVNULL) != 0) { /* * Encode \n, since otherwise readline will reload multiline history * entries as separate lines. (libedit doesn't really need this, but * we do it anyway since it's too hard to tell which implementation we * are using.) */ encode_history(); /* * On newer versions of libreadline, truncate the history file as * needed and then append what we've added. This avoids overwriting * history from other concurrent sessions (although there are still * race conditions when two sessions exit at about the same time). If * we don't have those functions, fall back to write_history(). */ #if defined(HAVE_HISTORY_TRUNCATE_FILE) && defined(HAVE_APPEND_HISTORY) { int nlines; int fd; /* truncate previous entries if needed */ if (max_lines >= 0) { nlines = Max(max_lines - history_lines_added, 0); (void) history_truncate_file(fname, nlines); } /* append_history fails if file doesn't already exist :-( */ fd = open(fname, O_CREAT | O_WRONLY | PG_BINARY, 0600); if (fd >= 0) close(fd); /* append the appropriate number of lines */ if (max_lines >= 0) nlines = Min(max_lines, history_lines_added); else nlines = history_lines_added; errnum = append_history(nlines, fname); if (errnum == 0) return true; } #else /* don't have append support */ { /* truncate what we have ... */ if (max_lines >= 0) stifle_history(max_lines); /* ... and overwrite file. Tough luck for concurrent sessions. */ errnum = write_history(fname); if (errnum == 0) return true; } #endif psql_error("could not save history to file \"%s\": %s\n", fname, strerror(errnum)); } return false; }
/* Warning: May be running setuid root! */ static void _interactive_dsh(opt_t * opt) { pid_t pid; char prompt[64]; char history_filename[MAXPATHLEN]; char *cmd = NULL; int got_history_file = 1; int len; snprintf(prompt, sizeof(prompt), "%s> ", opt->progname); using_history (); len = sizeof (history_filename); if (_history_file_create (history_filename, len) < 0) { got_history_file = 0; } while ((cmd = readline(prompt)) != NULL) { int errnum; char *expansion; if ((errnum = history_expand (cmd, &expansion))) { err ("%p: %s\n", expansion); } free (cmd); if ((errnum < 0) || (errnum == 2)) { free (expansion); continue; } cmd = expansion; if (!strcmp(cmd, "history")) { _history_list (); continue; } add_history (cmd); if (strlen(cmd) == 0) { /* empty line */ free(cmd); continue; } if (!strcmp(cmd, "quit") || !strcmp(cmd, "exit")) { free(cmd); /* quit or exit */ break; } if ((strlen(cmd) != 0) && (got_history_file)) append_history (1, history_filename); /* * fork dsh so we can ignore SIGINT in prompt loop */ switch (pid = fork()) { case -1: /* error */ errx("%p: fork: %m\n"); case 0: /* child - run cmd */ opt->cmd = Strdup(cmd); dsh(opt); Free((void **) &opt->cmd); exit(0); default: /* parent - wait */ while (waitpid(pid, NULL, 0) < 0) { if (errno != EINTR) break; } break; } free (cmd); } }