if (!F_ISSET(gp, G_STDIN_TTY) || !isatty(STDOUT_FILENO)) {
if (!F_ISSET(clp, CL_STDIN_TTY) || !isatty(STDOUT_FILENO)) {
cl_vi_init(sp)	SCR *sp;{	CL_PRIVATE *clp;	GS *gp;	char *o_cols, *o_lines, *o_term, *ttype;	gp = sp->gp;	clp = CLP(sp);	/* If already initialized, just set the terminal modes. */	if (F_ISSET(clp, CL_SCR_VI_INIT))		goto fast;	/* Curses vi always reads from (and writes to) a terminal. */	if (!F_ISSET(gp, G_STDIN_TTY) || !isatty(STDOUT_FILENO)) {		msgq(sp, M_ERR,		    "016|Vi's standard input and output must be a terminal");		return (1);	}	/* We'll need a terminal type. */	if (opts_empty(sp, O_TERM, 0))		return (1);	ttype = O_STR(sp, O_TERM);	/*	 * XXX	 * Changing the row/column and terminal values is done by putting them	 * into the environment, which is then read by curses.  What this loses	 * in ugliness, it makes up for in stupidity.  We can't simply put the	 * values into the environment ourselves, because in the presence of a	 * kernel mechanism for returning the window size, entering values into	 * the environment will screw up future screen resizing events, e.g. if	 * the user enters a :shell command and then resizes their window.  So,	 * if they weren't already in the environment, we make sure to delete	 * them immediately after setting them.	 *	 * XXX	 * Putting the TERM variable into the environment is necessary, even	 * though we're using newterm() here.  We may be using initscr() as	 * the underlying function.	 */	o_term = getenv("TERM");	cl_putenv("TERM", ttype, 0);	o_lines = getenv("LINES");	cl_putenv("LINES", NULL, (u_long)O_VAL(sp, O_LINES));	o_cols = getenv("COLUMNS");	cl_putenv("COLUMNS", NULL, (u_long)O_VAL(sp, O_COLUMNS));	/*	 * We don't care about the SCREEN reference returned by newterm, we	 * never have more than one SCREEN at a time.	 *	 * XXX	 * The SunOS initscr() can't be called twice.  Don't even think about	 * using it.  It fails in subtle ways (e.g. select(2) on fileno(stdin)	 * stops working).  (The SVID notes that applications should only call	 * initscr() once.)	 *	 * XXX	 * The HP/UX newterm doesn't support the NULL first argument, so we	 * have to specify the terminal type.	 */	errno = 0;	if (newterm(ttype, stdout, stdin) == NULL) {		if (errno)			msgq(sp, M_SYSERR, "%s", ttype);		else			msgq(sp, M_ERR, "%s: unknown terminal type", ttype);		return (1);	}	if (o_term == NULL)		unsetenv("TERM");	if (o_lines == NULL)		unsetenv("LINES");	if (o_cols == NULL)		unsetenv("COLUMNS");	/*	 * XXX	 * Someone got let out alone without adult supervision -- the SunOS	 * newterm resets the signal handlers.  There's a race, but it's not	 * worth closing.	 */	(void)sig_init(sp->gp, sp);	/*	 * We use raw mode.  What we want is 8-bit clean, however, signals	 * and flow control should continue to work.  Admittedly, it sounds	 * like cbreak, but it isn't.  Using cbreak() can get you additional	 * things like IEXTEN, which turns on flags like DISCARD and LNEXT.	 *	 * !!!	 * If raw isn't turning off echo and newlines, something's wrong.	 * However, it shouldn't hurt.	 */	noecho();			/* No character echo. */	nonl();				/* No CR/NL translation. */	raw();				/* 8-bit clean. */	idlok(stdscr, 1);		/* Use hardware insert/delete line. */	/* Put the cursor keys into application mode. */	(void)keypad(stdscr, TRUE);	/*	 * XXX	 * The screen TI sequence just got sent.  See the comment in	 * cl_funcs.c:cl_attr().	 */	clp->ti_te = TI_SENT;	/*	 * XXX	 * Historic implementations of curses handled SIGTSTP signals	 * in one of three ways.  They either:	 *	 *	1: Set their own handler, regardless.	 *	2: Did not set a handler if a handler was already installed.	 *	3: Set their own handler, but then called any previously set	 *	   handler after completing their own cleanup.	 *	 * We don't try and figure out which behavior is in place, we force	 * it to SIG_DFL after initializing the curses interface, which means	 * that curses isn't going to take the signal.  Since curses isn't	 * reentrant (i.e., the whole curses SIGTSTP interface is a fantasy),	 * we're doing The Right Thing.	 */	(void)signal(SIGTSTP, SIG_DFL);	/*	 * If flow control was on, turn it back on.  Turn signals on.  ISIG	 * turns on VINTR, VQUIT, VDSUSP and VSUSP.   The main curses code	 * already installed a handler for VINTR.  We're going to disable the	 * other three.	 *	 * XXX	 * We want to use ^Y as a vi scrolling command.  If the user has the	 * DSUSP character set to ^Y (common practice) clean it up.  As it's	 * equally possible that the user has VDSUSP set to 'a', we disable	 * it regardless.  It doesn't make much sense to suspend vi at read,	 * so I don't think anyone will care.  Alternatively, we could look	 * it up in the table of legal command characters and turn it off if	 * it matches one.  VDSUSP wasn't in POSIX 1003.1-1990, so we test for	 * it.	 *	 * XXX	 * We don't check to see if the user had signals enabled originally.	 * If they didn't, it's unclear what we're supposed to do here, but	 * it's also pretty unlikely.	 */	if (tcgetattr(STDIN_FILENO, &clp->vi_enter)) {		msgq(sp, M_SYSERR, "tcgetattr");		goto err;	}	if (clp->orig.c_iflag & IXON)		clp->vi_enter.c_iflag |= IXON;	if (clp->orig.c_iflag & IXOFF)		clp->vi_enter.c_iflag |= IXOFF;	clp->vi_enter.c_lflag |= ISIG;#ifdef VDSUSP	clp->vi_enter.c_cc[VDSUSP] = _POSIX_VDISABLE;#endif	clp->vi_enter.c_cc[VQUIT] = _POSIX_VDISABLE;	clp->vi_enter.c_cc[VSUSP] = _POSIX_VDISABLE;	/*	 * XXX	 * OSF/1 doesn't turn off the <discard>, <literal-next> or <status>	 * characters when curses switches into raw mode.  It should be OK	 * to do it explicitly for everyone.	 */#ifdef VDISCARD	clp->vi_enter.c_cc[VDISCARD] = _POSIX_VDISABLE;#endif#ifdef VLNEXT	clp->vi_enter.c_cc[VLNEXT] = _POSIX_VDISABLE;#endif#ifdef VSTATUS	clp->vi_enter.c_cc[VSTATUS] = _POSIX_VDISABLE;#endif	/* Initialize terminal based information. */	if (cl_term_init(sp))		goto err;fast:	/* Set the terminal modes. */	if (tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &clp->vi_enter)) {		msgq(sp, M_SYSERR, "tcsetattr");err:		(void)cl_vi_end(sp->gp);		return (1);	}	return (0);}