Exemple #1
0
int exec_cmd (char * line) {
    int waitres;

    def_prog_mode();
    endwin();

    int my_pipe[2];
    if (pipe(my_pipe) == -1) {
        error("Error creating pipe");
        getchar();
        reset_prog_mode();
        refresh();
        update();
        return -1;
    }

    pid_t child_id = fork();
    if (child_id == -1) {
        error("Fork error");
        getchar();
        reset_prog_mode();
        refresh();
        update();
        return -1;
    }

    if (child_id == 0) {     // we are in the child process
        close(my_pipe[0]);   // child doesn't read
        dup2(my_pipe[1], 1); // redirect stdout

        char * l = line;
        l = rtrim(ltrim(line, ' '), ' ');
        char ** param = split(l, ' ', 1);
        execvp(param[0], param);

        printf("Error executing command. ");
        exit(-1);

    } else {                 // we are in parent process
        close(my_pipe[1]);   // parent doesn't write
        char reading_buf[2];

        while (read(my_pipe[0], reading_buf, 1) > 0)
            write(1, reading_buf, 1);
        
        close(my_pipe[0]);
        wait(&waitres);
        system("echo -n 'Press ENTER to return.'");

        getchar();
        reset_prog_mode();
        refresh();
        update();
    }
    return 0;
}
Exemple #2
0
int
_meta(int bf)
{
	/*
	 * Do the appropriate fiddling with the tty driver to make it send
	 * all 8 bits through.  On SYSV this means clearing ISTRIP, on
	 * V7 you have to resort to RAW mode.
	 */
#ifdef	SYSV
	if (bf)
		PROGTTYS.c_iflag &= ~ISTRIP;
	else
		PROGTTYS.c_iflag |= ISTRIP;
	(void) reset_prog_mode();
#else	/* SYSV */
	if (bf)
		raw();
	else
		noraw();
#endif	/* SYSV */

	/* Do whatever is needed to put the terminal into meta-mode. */

	if ((SP->fl_meta = bf) != 0)
		(void) tputs(meta_on, 1, _outch);
	else
		(void) tputs(meta_off, 1, _outch);
	(void) fflush(SP->term_file);
	return (OK);
}
Exemple #3
0
static int view_driver(struct view *view, int key)
{
	switch (key) 
    {
	case REQ_MOVE_DOWN:
	case REQ_MOVE_UP:
		if (view)
			navigate_view(view, key);
		break;
	case REQ_VIEW_CLOSE:
        quit(0);
        break;
    case REQ_OPEN_VIM:
        report("Shelling out...");
        def_prog_mode();           /* save current tty modes */
        endwin();                  /* end curses mode temporarily */
        system(vim_cmd);           /* run shell */
        report("returned");        /* prepare return message */
        reset_prog_mode();         /* return to the previous tty modes */
        break;
    case REQ_VIEW_MAIN: 
        open_view(view);
        break;
    case REQ_SCREEN_RESIZE:
        resize_display();
        redraw_display(TRUE);
        break;

	default:
		return TRUE;
	}

	return TRUE;
}
Exemple #4
0
t_bool	exec_sh(char *sh, t_menu *menu)
{
  char	**temp;
  char	*path;
  int	status;

  if ((temp = add_tab(menu->list[menu->cur]->name, menu->path)) == NULL)
    return (FALSE);
  if ((path = creat_path(temp)) == NULL)
    return (FALSE);
  def_prog_mode();
  if (fork() == 0)
    {
      if (my_strcmp(sh, "emacs") == 0)
	execlp(sh, sh, "-nw", path);
      else
	execlp(sh, sh, path);	
    }
  else
    {
      wait(&status);
      reset_prog_mode();
      clear();
      init_aff();
      wrefresh(g_ctrl.menu[0].win);
      wrefresh(g_ctrl.menu[1].win);
      refresh();
   }
  return (TRUE);
}
Exemple #5
0
int 
view_control(int key)
{
	switch(key){
		case REQ_MOVE_DOWN:
		case REQ_MOVE_UP:
			fresh_view(key);
			break;
		case REQ_VIEW_CLOSE:
			quit(0);
			break;
		case REQ_OPEN_VIM:
			def_prog_mode();    /*save current tty modes*/
			endwin();			/*temporarily leave curses*/
			system(vim_cmd);	/*run shell*/
			reset_prog_mode();	/*return to the previous tty mode*/
			refresh();
			break;
		case REQ_VIEW_MAIN:
			open_view(); 
			break;
		case REQ_RELOAD_VIEW:
			Reload_info();
			break;
		default:
			return 1;
	}	

	return 1;
}
Exemple #6
0
int
main(int argc, char *argv[])
{
    int ch;
    char buffer[80];
    attr_t underline;
    bool i_option = FALSE;

    setlocale(LC_ALL, "");

    while ((ch = getopt(argc, argv, "i")) != -1) {
	switch (ch) {
	case 'i':
	    i_option = TRUE;
	    break;
	default:
	    usage();
	}
    }

    printf("starting filter program using %s...\n",
	   i_option ? "initscr" : "newterm");
    filter();
    if (i_option) {
	initscr();
    } else {
	(void) newterm((char *) 0, stdout, stdin);
    }
    cbreak();
    keypad(stdscr, TRUE);

    if (has_colors()) {
	int background = COLOR_BLACK;
	start_color();
#if HAVE_USE_DEFAULT_COLORS
	if (use_default_colors() != ERR)
	    background = -1;
#endif
	init_pair(1, COLOR_CYAN, (short) background);
	underline = (attr_t) COLOR_PAIR(1);
    } else {
	underline = A_UNDERLINE;
    }

    while (new_command(buffer, sizeof(buffer) - 1, underline) != ERR
	   && strlen(buffer) != 0) {
	reset_shell_mode();
	printf("\n");
	fflush(stdout);
	IGNORE_RC(system(buffer));
	reset_prog_mode();
	touchwin(stdscr);
	erase();
	refresh();
    }
    printw("done");
    refresh();
    endwin();
    ExitProgram(EXIT_SUCCESS);
}
Exemple #7
0
void run_command_source_cmd(const char *cmdstr) /* {{{ */
{
	/* run commands generated by a command */
	FILE *cmd = popen(cmdstr, "r");

	tnc_fprintf(logfp, LOG_DEBUG, "source: command \"%s\"", cmdstr);

	/* check for a valid fd */
	if (cmdstr == NULL)
	{
		tnc_fprintf(logfp, LOG_ERROR, "source: file \"%s\" could not be opened", cmdstr);
		statusbar_message(cfg.statusbar_timeout, "source: command \"%s\" could not be opened", cmdstr);
		return;
	}


	/* exit window */
	def_prog_mode();
	endwin();

	/* read command file */
	source_fp(cmd);

	/* force redraw */
	reset_prog_mode();
	redraw = true;
	
/* close config file */
	pclose(cmd);
	tnc_fprintf(logfp, LOG_DEBUG, "source complete: \"%s\"", cmdstr);
	statusbar_message(cfg.statusbar_timeout, "source complete: \"%s\"", cmdstr);
} /* }}} */
Exemple #8
0
static void ui_terminal_restore(Ui *ui) {
	UiCurses *uic = (UiCurses*)ui;
	termkey_start(uic->termkey);
	reset_prog_mode();
	wclear(stdscr);
	curs_set(0);
}
Exemple #9
0
bool
open_external_viewer(const char *argv[], const char *dir, bool confirm, bool refresh, const char *notice)
{
    bool ok;

    def_prog_mode();           /* save current tty modes */
    endwin();                  /* restore original tty modes */
    ok = io_run_fg(argv, dir);
    if (confirm || !ok) {
        if (!ok && *notice)
            fprintf(stderr, "%s", notice);
        fprintf(stderr, "Press Enter to continue");
        getc(opt_tty);
    }
    reset_prog_mode();
    if (watch_update(WATCH_EVENT_AFTER_EXTERNAL) && refresh) {
        struct view *view;
        int i;

        foreach_displayed_view (view, i) {
            if (watch_dirty(&view->watch))
                refresh_view(view);
        }
    }
    redraw_display(TRUE);
    return ok;
}
Exemple #10
0
/* Restore windows when returning from an external command. */
void
wins_unprepare_external (void)
{
  reset_prog_mode ();
  clearok (curscr, TRUE);
  curs_set (0);
  ui_mode = UI_CURSES;
  wins_refresh ();
  if (notify_bar ())
    notify_start_main_thread ();
}
Exemple #11
0
void
_setqiflush(int yes)
{
#ifdef SYSV
	if (yes)
		cur_term->Nttybs.c_lflag &= ~NOFLSH;
	else
		cur_term->Nttybs.c_lflag |= NOFLSH;
	(void) reset_prog_mode();
#endif /* SYSV */
}
Exemple #12
0
void
cob_screen_set_mode (const size_t smode)
{
	if (!smode) {
		refresh ();
		def_prog_mode ();
		endwin ();
	} else {
		reset_prog_mode ();
		refresh ();
	}
}
Exemple #13
0
void shell_draw() {
  char *full_path;
  int res;

  /* suspend ncurses mode */
  def_prog_mode();
  endwin();

  full_path = getpath(dirlist_par);
  res = chdir(full_path);
  if (res != 0) {
    reset_prog_mode();
    clear();
    printw("ERROR: Can't change directory: %s (errcode: %d)\n"
           "\n"
           "Press any key to continue.",
           full_path, res);
  } else {
    char *shell = getenv("SHELL");
    if (shell == NULL)
      shell = DEFAULT_SHELL;

    res = system(shell);

    /* resume ncurses mode */
    reset_prog_mode();

    if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) == 127) {
      clear();
      printw("ERROR: Can't execute shell interpreter: %s\n"
             "\n"
             "Press any key to continue.",
             shell);
    }
  }

  refresh();
  pstate = ST_BROWSE;
}
Exemple #14
0
/*
 * set the terminal to timeout in t milliseconds,
 * rounded up to the nearest 10th of a second.
 */
static	void
_settimeout(int num)
{
	PROGTTYS.c_lflag &= ~ICANON;
	if (num > 0) {
		PROGTTYS.c_cc[VMIN] = 0;
		PROGTTYS.c_cc[VTIME] = (num > 25500) ? 255 : (num + 99) / 100;
		cur_term->_fl_rawmode = 3;
	} else {
		PROGTTYS.c_cc[VMIN] = 1;
		PROGTTYS.c_cc[VTIME] = 0;
		cur_term->_fl_rawmode = 1;
	}
	(void) reset_prog_mode();
}
Exemple #15
0
main()
{
	initscr();
	clear();
	mvaddstr(10,20,"hello");
	refresh();
	sleep(5);
	reset_shell_mode();
	system("/bin/sh");
	reset_prog_mode();
	clearok(stdscr,TRUE);
	refresh();
	getch();
	endwin();
}
Exemple #16
0
static void
edition_post_exec (void)
{
    do_enter_ca_mode ();

    /* FIXME: Missing on slang endwin? */
    reset_prog_mode ();
    flushinp ();

    keypad (stdscr, TRUE);
    mc_raw_mode ();
    channels_up ();
    enable_mouse ();
    if (alternate_plus_minus)
	application_keypad_mode ();
}
Exemple #17
0
restartterm(NCURSES_CONST char *termp, int filenum, int *errret)
{
    int result;

    T((T_CALLED("restartterm(%s,%d,%p)"), termp, filenum, errret));

    if (setupterm(termp, filenum, errret) != OK) {
	result = ERR;
    } else if (SP != 0) {
	int saveecho = SP->_echo;
	int savecbreak = SP->_cbreak;
	int saveraw = SP->_raw;
	int savenl = SP->_nl;

	if (saveecho)
	    echo();
	else
	    noecho();

	if (savecbreak) {
	    cbreak();
	    noraw();
	} else if (saveraw) {
	    nocbreak();
	    raw();
	} else {
	    nocbreak();
	    noraw();
	}
	if (savenl)
	    nl();
	else
	    nonl();

	reset_prog_mode();

#if USE_SIZECHANGE
	_nc_update_screensize(SP);
#endif

	result = OK;
    } else {
	result = ERR;
    }
    returnCode(result);
}
Exemple #18
0
int main()
{	
	initscr();			/* Start curses mode 		  */
	printw("Hello World !!!\n");	/* Print Hello World		  */
	refresh();			/* Print it on to the real screen */
	def_prog_mode();		/* Save the tty modes		  */
	endwin();			/* End curses mode temporarily	  */
	system("/bin/sh");		/* Do whatever you like in cooked mode */
	reset_prog_mode();		/* Return to the previous tty mode*/
					/* stored by def_prog_mode() 	  */
	refresh();			/* Do refresh() to restore the	  */
					/* Screen contents		  */
	printw("Another String\n");	/* Back to curses use the full    */
	refresh();			/* capabilities of curses	  */
	endwin();			/* End curses mode		  */

	return 0;
}
Exemple #19
0
bool
open_external_viewer(const char *argv[], const char *dir, bool confirm, const char *notice)
{
	bool ok;

	def_prog_mode();           /* save current tty modes */
	endwin();                  /* restore original tty modes */
	ok = io_run_fg(argv, dir);
	if (confirm) {
		if (!ok && *notice)
			fprintf(stderr, "%s", notice);
		fprintf(stderr, "Press Enter to continue");
		getc(opt_tty);
	}
	reset_prog_mode();
	redraw_display(TRUE);
	return ok;
}
Exemple #20
0
static TACommandVerdict reset_prog_mode_cmd(TAThread thread, TAInputStream stream)
{
    // Prepare
    int res;
    
    START_TARGET_OPERATION(thread);
    
    // Execute
    res = reset_prog_mode();
    
    END_TARGET_OPERATION(thread);
    
    // Response
    writeInt(thread, res);
    sendResponse(thread);
    
    return taDefaultVerdict;
}
Exemple #21
0
int
/* The next line causes a lint warning because errret is not used */
restartterm(char *term, int filenum, int *errret)
/* int	filenum - This is a UNIX file descriptor, not a stdio ptr. */
{
	int	saveecho = SP->fl_echoit;
	int	savecbreak = cur_term->_fl_rawmode;
	int	savenl;

#ifdef	SYSV
	savenl = PROGTTYS.c_iflag & ONLCR;
#else	/* SYSV */
	savenl = PROGTTY.sg_flags & CRMOD;
#endif	/* SYSV */

	_called_before = 0;
	(void) setupterm(term, filenum, (int *) 0);

	/* Restore curses settable flags, leaving other stuff alone. */
	SP->fl_echoit = saveecho;

	(void) nocbreak();
	(void) noraw();
	if (savecbreak == 1)
		(void) cbreak();
	else
		if (savecbreak == 2)
			(void) raw();

	if (savenl)
		(void) nl();
	else
		(void) nonl();

	(void) reset_prog_mode();

	LINES = SP->lsize;
	COLS = columns;
	return (OK);
}
Exemple #22
0
int restartterm(const char *term, int filenum, int *errret)
{
int saveecho = SP->_echo;
int savecbreak = SP->_cbreak;
int saveraw = SP->_raw;
int savenl = SP->_nl;

	T((T_CALLED("restartterm(%s,%d,%p)"), term, filenum, errret));

	setupterm(term, filenum, errret);

	if (saveecho)
		echo();
	else
		noecho();

	if (savecbreak) {
		cbreak();
		noraw();
	} else if (saveraw) {
		nocbreak();
		raw();
	} else {
		nocbreak();
		noraw();
	}
	if (savenl)
		nl();
	else
		nonl();

	reset_prog_mode();

#if USE_SIZECHANGE
	_nc_update_screensize();
#endif

	returnCode(OK);
}
Exemple #23
0
int cui_run_cmd(struct pmenu_item *item)
{
	int result;
	struct cui *cui = cui_from_item(item);
	const char **cmd_argv = item->data;

	nc_scr_status_printf(cui->current, _("Running %s..."), cmd_argv[0]);

	def_prog_mode();

	result = process_run_simple_argv(item, cmd_argv);

	reset_prog_mode();
	redrawwin(cui->current->main_ncw);

	if (result) {
		pb_log("%s: failed: '%s'\n", __func__, cmd_argv[0]);
		nc_scr_status_printf(cui->current, _("Failed: %s"),
				cmd_argv[0]);
	}

	return result;
}
Exemple #24
0
// function that shows text in a child process
void show_text(char * val) {
    int pid;
    char px[MAXCMD];
    char *pager;

    (void) strcpy(px, "| ");
    if (!(pager = getenv("PAGER")))
        pager = DFLT_PAGER;
    (void) strcat(px, pager);
    FILE * f = openfile(px, &pid, NULL);
    if (!f) {
        scerror("Can't open pipe to %s", pager);
        return;
    }
    def_prog_mode();
    endwin();
    fprintf(f, "%s\n", val);
    fprintf(f, "Press 'q' and then ENTER to return.");
    closefile(f, pid, 0);
    getchar();
    reset_prog_mode();
    refresh();
    update(TRUE);
}
Exemple #25
0
void
tty_reset_prog_mode (void)
{
    reset_prog_mode ();
}
Exemple #26
0
int doupdate(void)
{
    int y;
    bool clearall;

    PDC_LOG(("doupdate() - called\n"));

    if (!curscr)
        return ERR;

    if (isendwin())         /* coming back after endwin() called */
    {
        reset_prog_mode();
        clearall = TRUE;
        SP->alive = TRUE;   /* so isendwin() result is correct */
    }
    else
        clearall = curscr->_clear;

    for (y = 0; y < SP->lines; y++)
    {
        PDC_LOG(("doupdate() - Transforming line %d of %d: %s\n",
                 y, SP->lines, (curscr->_firstch[y] != _NO_CHANGE) ?
                 "Yes" : "No"));

        if (clearall || curscr->_firstch[y] != _NO_CHANGE)
        {
            int first, last;

            chtype *src = curscr->_y[y];
            chtype *dest = pdc_lastscr->_y[y];

            if (clearall)
            {
                first = 0;
                last = COLS - 1;
            }
            else
            {
                first = curscr->_firstch[y];
                last = curscr->_lastch[y];
            }

            while (first <= last)
            {
                int len = 0;

                /* build up a run of changed cells; if two runs are
                   separated by a single unchanged cell, ignore the
                   break */

                if (clearall)
                    len = last - first + 1;
                else
                    while (first + len <= last &&
                           (src[first + len] != dest[first + len] ||
                            (len && first + len < last &&
                             src[first + len + 1] != dest[first + len + 1])
                           )
                          )
                        len++;

                /* update the screen, and pdc_lastscr */

                if (len)
                {
                    PDC_transform_line(y, first, len, src + first);
                    memcpy(dest + first, src + first, len * sizeof(chtype));
                    first += len;
                }

                /* skip over runs of unchanged cells */

                while (first <= last && src[first] == dest[first])
                    first++;
            }

            curscr->_firstch[y] = _NO_CHANGE;
            curscr->_lastch[y] = _NO_CHANGE;
        }
    }

    curscr->_clear = FALSE;

    if (SP->visibility)
        PDC_gotoyx(curscr->_cury, curscr->_curx);

    SP->cursrow = curscr->_cury;
    SP->curscol = curscr->_curx;

    return OK;
}
Exemple #27
0
int fixterm(void)
{
    PDC_LOG(("fixterm() - called\n"));

    return reset_prog_mode();
}
Exemple #28
0
// Handle the user input
int handleUserInput() {
    char *editor, *newPath;
    // Get and process user input
    while ((inputChar = getch()) != 'q') {
        switch (inputChar) {
            case 'e':   // Edit
                // Create cmd string using env vars
                editor = getenv("EDITOR");
                if (editor != NULL) {
                    strcpy(cmd, editor);
                    strcat(cmd, " ");
                } else
                    strcpy(cmd, "nano ");
                strcat(cmd, item_name(current_item(menus[FILES])));

                // Temporarily leave curses mode and run syscall
                def_prog_mode();
                endwin();
                errNum = system(cmd);

                // Return to curses mode
                reset_prog_mode();
                refresh();

                if (errNum != 0) {
                    attron(COLOR_PAIR(1));
                    mvprintw(LINES - 1, 0, "Error editing file: %s\n", strerror(errNum));
                    attroff(COLOR_PAIR(1));
                }
                break;
            case 'r':   // Run
                // Temporarily leave curses mode and run syscall
                def_prog_mode();
                endwin();
                errNum = system(item_name(current_item(menus[FILES])));

                // Return to curses mode
                reset_prog_mode();
                refresh();

                if (errNum != 0) {
                    attron(COLOR_PAIR(1));
                    mvprintw(LINES - 1, 0, "Error running file: %s\n", strerror(errNum));
                    attroff(COLOR_PAIR(1));
                    refresh();
                    getch();
                }
                break;
            case 'c':   // Change directory
                strcpy(cmd, "cd ");
                strcat(cmd, item_name(current_item(menus[DIRS])));

                errNum = system(cmd);
                if (errNum != 0) {
                    attron(COLOR_PAIR(1));
                    mvprintw(LINES - 1, 0, "Error changing directory: %s\n", strerror(errNum));
                    attroff(COLOR_PAIR(1));
                } else {
                    newPath = getenv("PWD");
                    strcpy(path, newPath);
                    updateDisplay();
                }
                break;
            case KEY_DOWN:
                menu_driver(menus[current], REQ_DOWN_ITEM);
                wrefresh(cursesWins[current]);
                break;
            case KEY_UP:
                menu_driver(menus[current], REQ_UP_ITEM);
                wrefresh(cursesWins[current]);
                break;
            case KEY_NPAGE:
                menu_driver(menus[current], REQ_SCR_DPAGE);
                wrefresh(cursesWins[current]);
                break;
            case KEY_PPAGE:
                menu_driver(menus[current], REQ_SCR_UPAGE);
                wrefresh(cursesWins[current]);
                break;
            case '\t':
                if (current == FILES)
                    current = DIRS;
                else
                    current = FILES;
                break;
            default:
                move(LINES - 1, 0);
                clrtoeol();
                attron(COLOR_PAIR(1));
                mvprintw(LINES - 1, 0, "Invalid command");
                attroff(COLOR_PAIR(1));
                refresh();
                break;
        }
    }
}
Exemple #29
0
int
run_program(int flags, const char *cmd, ...)
{
	va_list ap;
	struct winsize win;
	int ret;
	WINDOW *actionwin = NULL;
	char *scmd;
	char **args;
	const char *errstr = NULL;

	va_start(ap, cmd);
	vasprintf(&scmd, cmd, ap);
	va_end(ap);
	if (scmd == NULL)
		err(1, "vasprintf(&scmd, \"%s\", ...)", cmd);

	args = make_argv(scmd);

	/* Make curses save tty settings */
	def_prog_mode();

	(void)ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
	/* Apparently, we sometimes get 0x0 back, and that's not useful */
	if (win.ws_row == 0)
		win.ws_row = 24;
	if (win.ws_col == 0)
		win.ws_col = 80;

	if ((flags & RUN_DISPLAY) != 0) {
		if (flags & RUN_FULLSCREEN) {
			wclear(stdscr);
			clearok(stdscr, 1);
			touchwin(stdscr);
			refresh();
			actionwin = stdscr;
		} else
			actionwin = show_cmd(scmd, &win);
	} else
		win.ws_row -= 4;

	ret = launch_subwin(&actionwin, args, &win, flags, scmd, &errstr);
	fpurge(stdin);

	/* If the command failed, show command name */
	if (actionwin == NULL && ret != 0 && !(flags & RUN_ERROR_OK))
		actionwin = show_cmd(scmd, &win);

	if (actionwin != NULL) {
		int y, x;
		getyx(actionwin, y, x);
		if (actionwin != stdscr)
			mvaddstr(0, 4, msg_string(MSG_Status));
		if (ret != 0) {
			if (actionwin == stdscr && x != 0)
				addstr("\n");
			x = 1;	/* force newline below */
			standout();
			addstr(errstr);
			standend();
		} else {
			if (actionwin != stdscr) {
				standout();
				addstr(msg_string(MSG_Finished));
				standend();
			}
		}
		clrtoeol();
		refresh();
		if ((ret != 0 && !(flags & RUN_ERROR_OK)) ||
		    (y + x != 0 && !(flags & RUN_PROGRESS))) {
			if (actionwin != stdscr)
				move(getbegy(actionwin) - 2, 5);
			else if (x != 0)
				addstr("\n");
			addstr(msg_string(MSG_Hit_enter_to_continue));
			refresh();
			getchar();
		} else {
			if (y + x != 0) {
				/* give user 1 second to see messages */
				refresh();
				sleep(1);
			}
		}
	}

	/* restore tty setting we saved earlier */
	reset_prog_mode();

	/* clean things up */
	if (actionwin != NULL) {
		if (actionwin != stdscr)
			delwin(actionwin);
		if (errstr == 0 || !(flags & RUN_NO_CLEAR)) {
			wclear(stdscr);
			touchwin(stdscr);
			clearok(stdscr, 1);
			refresh();
		}
	}

	free(scmd);
	free_argv(args);

	if (ret != 0 && flags & RUN_FATAL)
		exit(ret);
	return ret;
}
Exemple #30
0
/*
 * launch a program inside a subwindow, and report its return status when done
 */
static int
launch_subwin(WINDOW **actionwin, char **args, struct winsize *win, int flags,
    const char *scmd, const char **errstr)
{
	int n, i;
	int selectfailed;
	int status, master, slave;
	fd_set active_fd_set, read_fd_set;
	pid_t child, pid;
	char ibuf[MAXBUF];
	char pktdata;
	char *cp, *ncp;
	struct termios rtt, tt;
	struct timeval tmo;
	static int do_tioccons = 2;

	(void)tcgetattr(STDIN_FILENO, &tt);
	if (openpty(&master, &slave, NULL, &tt, win) == -1) {
		*errstr = "openpty() failed";
		return -1;
	}

	rtt = tt;

	/* ignore tty signals until we're done with subprocess setup */
	ttysig_ignore = 1;
	ioctl(master, TIOCPKT, &ttysig_ignore);

	/* Try to get console output into our pipe */
	if (do_tioccons) {
		if (ioctl(slave, TIOCCONS, &do_tioccons) == 0
		    && do_tioccons == 2) {
			/* test our output - we don't want it grabbed */
			write(1, " \b", 2);
			ioctl(master, FIONREAD, &do_tioccons);
			if (do_tioccons != 0) {
				do_tioccons = 0;
				ioctl(slave, TIOCCONS, &do_tioccons);
			} else
				do_tioccons = 1;
		}
	}

	if (logfp)
		fflush(logfp);
	if (script)
		fflush(script);

	child = fork();
	switch (child) {
	case -1:
		ttysig_ignore = 0;
		refresh();
		*errstr = "fork() failed";
		return -1;
	case 0:	/* child */
		(void)close(STDIN_FILENO);
		/* silently stop curses */
		(void)close(STDOUT_FILENO);
		(void)open("/dev/null", O_RDWR, 0);
		dup2(STDIN_FILENO, STDOUT_FILENO);
		endwin();
		(void)close(master);
		rtt = tt;
		rtt.c_lflag |= (ICANON|ECHO);
		(void)tcsetattr(slave, TCSANOW, &rtt);
		login_tty(slave);
		if (logfp) {
			fprintf(logfp, "executing: %s\n", scmd);
			fclose(logfp);
			logfp = NULL;
		}
		if (script) {
			fprintf(script, "%s\n", scmd);
			fclose(script);
			script = NULL;
		}
		if (strcmp(args[0], "cd") == 0 && strcmp(args[2], "&&") == 0) {
			target_chdir_or_die(args[1]);
			args += 3;
		}
		if (flags & RUN_XFER_DIR)
			target_chdir_or_die(xfer_dir);
		/*
		 * If target_prefix == "", the chroot will fail, but
		 * that's ok, since we don't need it then.
		 */
		if (flags & RUN_CHROOT && *target_prefix()
		    && chroot(target_prefix()) != 0)
			warn("chroot(%s) for %s", target_prefix(), *args);
		else {
			execvp(*args, args);
			warn("execvp %s", *args);
		}
		_exit(EXIT_FAILURE);
		// break; /* end of child */
	default:
		/*
		 * parent: we've set up the subprocess.
		 * forward tty signals to its process group.
		 */
		ttysig_forward = child;
		ttysig_ignore = 0;
		break;
	}

	/*
	 * Now loop transferring program output to screen, and keyboard
	 * input to the program.
	 */

	FD_ZERO(&active_fd_set);
	FD_SET(master, &active_fd_set);
	FD_SET(STDIN_FILENO, &active_fd_set);

	for (selectfailed = 0;;) {
		if (selectfailed) {
			const char mmsg[] =
			    "select(2) failed but no child died?";
			if (logfp)
				(void)fprintf(logfp, mmsg);
			errx(1, mmsg);
		}
		read_fd_set = active_fd_set;
		tmo.tv_sec = flags & RUN_SILENT ? 20 : 2;
		tmo.tv_usec = 0;
		i = select(FD_SETSIZE, &read_fd_set, NULL, NULL, &tmo);
		if (i == 0 && *actionwin == NULL && (flags & RUN_SILENT) == 0)
			*actionwin = show_cmd(scmd, win);
		if (i < 0) {
			if (errno != EINTR) {
				warn("select");
				if (logfp)
					(void)fprintf(logfp,
					    "select failure: %s\n",
					    strerror(errno));
				selectfailed = 1;
			}
		} else for (i = 0; i < FD_SETSIZE; ++i) {
			if (!FD_ISSET(i, &read_fd_set))
				continue;
			n = read(i, ibuf, sizeof ibuf - 1);
			if (n <= 0) {
				if (n < 0)
					warn("read");
				continue;
			}
			ibuf[n] = 0;
			cp = ibuf;
			if (i == STDIN_FILENO) {
				(void)write(master, ibuf, (size_t)n);
				if (!(rtt.c_lflag & ECHO))
					continue;
			} else {
				pktdata = ibuf[0];
				if (pktdata != 0) {
					if (pktdata & TIOCPKT_IOCTL)
						memcpy(&rtt, ibuf, sizeof(rtt));
					continue;
				}
				cp += 1;
			}
			if (*cp == 0 || flags & RUN_SILENT)
				continue;
			if (logfp) {
				fprintf(logfp, "%s", cp);
				fflush(logfp);
			}
			if (*actionwin == NULL)
				*actionwin = show_cmd(scmd, win);
			/* posix curses is braindead wrt \r\n so... */
			for (ncp = cp; (ncp = strstr(ncp, "\r\n")); ncp += 2) {
				ncp[0] = '\n';
				ncp[1] = '\r';
			}
			waddstr(*actionwin, cp);
			wrefresh(*actionwin);
		}
		pid = wait4(child, &status, WNOHANG, 0);
 		if (pid == child && (WIFEXITED(status) || WIFSIGNALED(status)))
			break;
	}
	close(master);
	close(slave);
	if (logfp)
		fflush(logfp);

	/* from here on out, we take tty signals ourselves */
	ttysig_forward = 0;

	reset_prog_mode();

	if (WIFEXITED(status)) {
		*errstr = msg_string(MSG_Command_failed);
		return WEXITSTATUS(status);
	}
	if (WIFSIGNALED(status)) {
		*errstr = msg_string(MSG_Command_ended_on_signal);
		return WTERMSIG(status);
	}
	return 0;
}