示例#1
0
/*
 * ex_exec_proc --
 *	Run a separate process.
 *
 * PUBLIC: int ex_exec_proc __P((SCR *, EXCMD *, const char *, const char *, int));
 */
int
ex_exec_proc(SCR *sp, EXCMD *cmdp, const char *cmd, const char *msg, int need_newline)
{
    GS *gp;
    const char *name;
    pid_t pid;

    gp = sp->gp;

    /* We'll need a shell. */
    if (opts_empty(sp, O_SHELL, 0))
        return (1);

    /* Enter ex mode. */
    if (F_ISSET(sp, SC_VI)) {
        if (gp->scr_screen(sp, SC_EX)) {
            ex_wemsg(sp, cmdp->cmd->name, EXM_NOCANON);
            return (1);
        }
        (void)gp->scr_attr(sp, SA_ALTERNATE, 0);
        F_SET(sp, SC_SCR_EX | SC_SCR_EXWROTE);
    }

    /* Put out additional newline, message. */
    if (need_newline)
        (void)ex_puts(sp, "\n");
    if (msg != NULL) {
        (void)ex_puts(sp, msg);
        (void)ex_puts(sp, "\n");
    }
    (void)ex_fflush(sp);

    switch (pid = vfork()) {
    case -1:			/* Error. */
        msgq(sp, M_SYSERR, "vfork");
        return (1);
    case 0:				/* Utility. */
        if (gp->scr_child)
            gp->scr_child(sp);
        if ((name = strrchr(O_STR(sp, O_SHELL), '/')) == NULL)
            name = O_STR(sp, O_SHELL);
        else
            ++name;
        execl(O_STR(sp, O_SHELL), name, "-c", cmd, (char *)NULL);
        msgq_str(sp, M_SYSERR, O_STR(sp, O_SHELL), "execl: %s");
        _exit(127);
    /* NOTREACHED */
    default:			/* Parent. */
        return (proc_wait(sp, (long)pid, cmd, 0, 0));
    }
    /* NOTREACHED */
}