Exemplo n.º 1
0
/*
 * Free storage associated with a screen structure.
 * NOTE endwin() does not do this.
 */
void
delscreen(SCREEN *sp)
{
	if (sp != NULL) {
		if (sp->_slk._w != NULL)
			(void) delwin(sp->_slk._w);

		(void) delwin(sp->_newscr);
		(void) delwin(sp->_curscr);
		(void) del_curterm(sp->_term);

		__m_decode_free((t_decode **) &sp->_decode);

		if (sp->_hash != NULL)
			free(sp->_hash);

		if (sp->_unget._stack != NULL)
			free(sp->_unget._stack);

		if (sp->_in != NULL)
			free(sp->_in);

		free(sp);
	}
}
Exemplo n.º 2
0
/* ARGSUSED */
int
tgetent(__unused char *bp, const char *name)
{
	int errret;
	static TERMINAL *last = NULL;

	_DIAGASSERT(name != NULL);

	/* Free the old term */
	if (cur_term != NULL) {
		if (last != NULL && cur_term != last)
			del_curterm(last);
		last = cur_term;
	}
	errret = -1;
	if (setupterm(name, STDOUT_FILENO, &errret) != 0)
		return errret;

	if (last == NULL)
		last = cur_term;

	if (pad_char != NULL)
		PC = pad_char[0];
	UP = __UNCONST(cursor_up);
	BC = __UNCONST(cursor_left);
	return 1;
}
Exemplo n.º 3
0
_nc_tgetent_leaks(void)
{
    for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
	FreeIfNeeded(FIX_SGR0);
	if (LAST_TRM != 0)
	    del_curterm(LAST_TRM);
    }
}
Exemplo n.º 4
0
static void
cleanup(MYDATA * data)
{
    set_curterm(data->term);
    del_curterm(data->term);
#if !NO_LEAKS
    free(data->sp);		/* cannot use delscreen in tinfo */
#endif
    free(data);
}
Exemplo n.º 5
0
/**
   Free memory used by various subsystems.
*/
static void destroy()
{
	env_universal_destroy();
	input_common_destroy();
	wutil_destroy();
	if( del_curterm( cur_term ) == ERR )
	{
		debug( 0, _(L"Error while closing terminfo") );		
	}
	
	fclose( out_file );
}
Exemplo n.º 6
0
_nc_leaks_tinfo(void)
{
#if NO_LEAKS
    char *s;
#endif

    T((T_CALLED("_nc_free_tinfo()")));
#if NO_LEAKS
    _nc_globals.leak_checking = TRUE;
    _nc_free_tparm();
    _nc_tgetent_leaks();

    if (TerminalOf(CURRENT_SCREEN) != 0) {
	del_curterm(TerminalOf(CURRENT_SCREEN));
    }
    _nc_forget_prescr();

    _nc_comp_captab_leaks();
    _nc_free_entries(_nc_head);
    _nc_get_type(0);
    _nc_first_name(0);
    _nc_db_iterator_leaks();
    _nc_keyname_leaks();
#if BROKEN_LINKER || USE_REENTRANT
    _nc_names_leaks();
    _nc_codes_leaks();
    FreeIfNeeded(_nc_prescreen.real_acs_map);
#endif
    _nc_comp_error_leaks();

    if ((s = _nc_home_terminfo()) != 0)
	free(s);

#ifdef TRACE
    T((T_RETURN("")));
    trace(0);
    _nc_trace_buf(-1, (size_t) 0);
#endif

#endif /* NO_LEAKS */
    returnVoid;
}
Exemplo n.º 7
0
void input_destroy()
{
	if( !is_init )
		return;
	

	is_init=0;
	
	al_foreach( &mappings, &free );		
	al_destroy( &mappings );

	input_common_destroy();
	
	if( del_curterm( cur_term ) == ERR )
	{
		debug( 0, _(L"Error while closing terminfo") );
	}

	input_terminfo_destroy();
	
}
Exemplo n.º 8
0
static void
term_init(int fd, const char *sa[5])
{
	TERMINAL *ti;
	int error;
	const char *bold, *sgr0, *smso, *rmso, *smul, *rmul;

	if (ti_setupterm(&ti, NULL, fd, &error) == -1) {
		bold = sgr0 = NULL;
		smso = rmso = smul = rmul = "";
		ti = NULL;
	} else {
		bold = ti_getstr(ti, "bold");
		sgr0 = ti_getstr(ti, "sgr0");
		if (bold == NULL || sgr0 == NULL) {
			smso = ti_getstr(ti, "smso");

			if (smso == NULL ||
			    (rmso = ti_getstr(ti, "rmso")) == NULL)
				smso = rmso = "";
			bold = sgr0 = NULL;
		} else
			smso = rmso = "";

		smul = ti_getstr(ti, "smul");
		if (smul == NULL || (rmul = ti_getstr(ti, "rmul")) == NULL)
			smul = rmul = "";
	}

	sa[0] = term_fix_seq(ti, bold ? bold : smso);
	sa[1] = term_fix_seq(ti, sgr0 ? sgr0 : rmso);
	sa[2] = estrdup("...");
	sa[3] = term_fix_seq(ti, smul);
	sa[4] = term_fix_seq(ti, rmul);

	if (ti)
		del_curterm(ti);
}
Exemplo n.º 9
0
static void
finish(const char *psz_msg, int rc)
{
  if (b_interactive) {
    attron(A_STANDOUT);
    mvprintw(LINE_ACTION, 0, (char *) "%s, exiting...\n", psz_msg);
    attroff(A_STANDOUT);
    clrtoeol();
    refresh();
  }
  tty_restore();
  if (cur_term) del_curterm(cur_term);
  cur_window = NULL;

#ifdef HAVE_CDDB
  if (p_conn) cddb_destroy(p_conn);
  cddb_disc_destroy(p_cddb_disc);
  libcddb_shutdown();
#endif /*HAVE_CDDB*/
  cdio_destroy (p_cdio_global);
  free (psz_device_global);
  exit (rc);
}
Exemplo n.º 10
0
int intern initbios( void )
{
    PossibleDisplay             *curr;

    if( UIConFile == NULL ) {
        char *tty;

        tty = getenv( "TTY" );
        if( tty == NULL ) {
            tty = "/dev/tty";
        }
        UIConFile = fopen( tty, "w+" );
        if( UIConFile == NULL ) return( FALSE );
        UIConHandle = fileno( UIConFile );
        fcntl( UIConHandle, F_SETFD, 1 );
    }

    setupterm( GetTermType(), UIConHandle, (int *)0);
    /* will report an error message and exit if any
       problem with a terminfo */

    // Check to make sure terminal is suitable
    if( cursor_address == NULL || hard_copy ) {
        del_curterm( cur_term );
        return( FALSE );
    }

    curr = DisplayList;

    for( ;; ) {
        if( curr->check == NULL ) return( FALSE );
        if( curr->check() ) break;
        ++curr;
    }
    UIVirt = curr->virt;
    return( _uibiosinit() );
}
Exemplo n.º 11
0
tgetent(char *bufp, const char *name)
{
    int errcode;
    int n;
    bool found_cache = FALSE;

    START_TRACE();
    T((T_CALLED("tgetent()")));

    _nc_setupterm((NCURSES_CONST char *) name, STDOUT_FILENO, &errcode, TRUE);

    /*
     * In general we cannot tell if the fixed sgr0 is still used by the
     * caller, but if tgetent() is called with the same buffer, that is
     * good enough, since the previous data would be invalidated by the
     * current call.
     *
     * bufp may be a null pointer, e.g., GNU termcap.  That allocates data,
     * which is good until the next tgetent() call.  The conventional termcap
     * is inconvenient because of the fixed buffer size, but because it uses
     * caller-supplied buffers, can have multiple terminal descriptions in
     * use at a given time.
     */
    for (n = 0; n < TGETENT_MAX; ++n) {
	bool same_result = (MyCache[n].last_used && MyCache[n].last_bufp == bufp);
	if (same_result) {
	    CacheInx = n;
	    if (FIX_SGR0 != 0) {
		FreeAndNull(FIX_SGR0);
	    }
	    /*
	     * Also free the terminfo data that we loaded (much bigger leak).
	     */
	    if (LAST_TRM != 0 && LAST_TRM != cur_term) {
		TERMINAL *trm = LAST_TRM;
		del_curterm(LAST_TRM);
		for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx)
		    if (LAST_TRM == trm)
			LAST_TRM = 0;
		CacheInx = n;
	    }
	    found_cache = TRUE;
	    break;
	}
    }
    if (!found_cache) {
	int best = 0;

	for (CacheInx = 0; CacheInx < TGETENT_MAX; ++CacheInx) {
	    if (LAST_SEQ < MyCache[best].sequence) {
		best = CacheInx;
	    }
	}
	CacheInx = best;
    }
    LAST_TRM = cur_term;
    LAST_SEQ = ++CacheSeq;

    PC = 0;
    UP = 0;
    BC = 0;
    FIX_SGR0 = 0;		/* don't free it - application may still use */

    if (errcode == 1) {

	if (cursor_left)
	    if ((backspaces_with_bs = (char) !strcmp(cursor_left, "\b")) == 0)
		backspace_if_not_bs = cursor_left;

	/* we're required to export these */
	if (pad_char != NULL)
	    PC = pad_char[0];
	if (cursor_up != NULL)
	    UP = cursor_up;
	if (backspace_if_not_bs != NULL)
	    BC = backspace_if_not_bs;

	if ((FIX_SGR0 = _nc_trim_sgr0(&(cur_term->type))) != 0) {
	    if (!strcmp(FIX_SGR0, exit_attribute_mode)) {
		if (FIX_SGR0 != exit_attribute_mode) {
		    free(FIX_SGR0);
		}
		FIX_SGR0 = 0;
	    }
	}
	LAST_BUF = bufp;
	LAST_USE = TRUE;

	SetNoPadding(SP);
	(void) baudrate();	/* sets ospeed as a side-effect */

/* LINT_PREPRO
#if 0*/
#include <capdefaults.c>
/* LINT_PREPRO
#endif*/

    }
    returnCode(errcode);
}
Exemplo n.º 12
0
static void
rt_free(void *ptr)
{
  if(ptr != NULL)
    del_curterm(ptr);
}
Exemplo n.º 13
0
/*
 * cl_ex_init --
 *	Initialize the ex screen.
 */
static int
cl_ex_init(SCR *sp)
{
	CL_PRIVATE *clp;
	int error;
	const char *ttype;

	clp = CLP(sp);

	/* If already initialized, just set the terminal modes. */
	if (F_ISSET(clp, CL_SCR_EX_INIT))
		goto fast;

	/* If not reading from a file, we're done. */
	if (!F_ISSET(clp, CL_STDIN_TTY))
		return (0);

	if (F_ISSET(clp, CL_CHANGE_TERM)) {
		if (F_ISSET(clp, CL_SETUPTERM) && del_curterm(cur_term))
			return (1);
		F_CLR(clp, CL_SETUPTERM | CL_CHANGE_TERM);
	}

	if (!F_ISSET(clp, CL_SETUPTERM)) {
		/* We'll need a terminal type. */
		if (opts_empty(sp, O_TERM, 0))
			return (1);
		ttype = O_STR(sp, O_TERM);
		(void)setupterm(ttype, STDOUT_FILENO, &error);
		if (error == 0 || error == -1)
			return (1);
	}

	/* Get the ex termcap/terminfo strings. */
	(void)cl_getcap(sp, "cup", &clp->cup);
	(void)cl_getcap(sp, "smso", &clp->smso);
	(void)cl_getcap(sp, "rmso", &clp->rmso);
	(void)cl_getcap(sp, "el", &clp->el);
	(void)cl_getcap(sp, "cuu1", &clp->cuu1);

	/* Enter_standout_mode and exit_standout_mode are paired. */
	if (clp->smso == NULL || clp->rmso == NULL) {
		if (clp->smso != NULL) {
			free(clp->smso);
			clp->smso = NULL;
		}
		if (clp->rmso != NULL) {
			free(clp->rmso);
			clp->rmso = NULL;
		}
	}

	/*
	 * Turn on canonical mode, with normal input and output processing.
	 * Start with the original terminal settings as the user probably
	 * had them (including any local extensions) set correctly for the
	 * current terminal.
	 *
	 * !!!
	 * We can't get everything that we need portably; for example, ONLCR,
	 * mapping <newline> to <carriage-return> on output isn't required
	 * by POSIX 1003.1b-1993.  If this turns out to be a problem, then
	 * we'll either have to play some games on the mapping, or we'll have
	 * to make all ex printf's output \r\n instead of \n.
	 */
	clp->ex_enter = clp->orig;
	clp->ex_enter.c_lflag  |= ECHO | ECHOE | ECHOK | ICANON | IEXTEN | ISIG;
#ifdef ECHOCTL
	clp->ex_enter.c_lflag |= ECHOCTL;
#endif
#ifdef ECHOKE
	clp->ex_enter.c_lflag |= ECHOKE;
#endif
	clp->ex_enter.c_iflag |= ICRNL;
	clp->ex_enter.c_oflag |= OPOST;
#ifdef ONLCR
	clp->ex_enter.c_oflag |= ONLCR;
#endif

fast:	if (tcsetattr(STDIN_FILENO, TCSADRAIN | TCSASOFT, &clp->ex_enter)) {
		if (errno == EINTR)
			goto fast;
		msgq(sp, M_SYSERR, "tcsetattr");
		return (1);
	}
	return (0);
}
Exemplo n.º 14
0
void intern finibios( void )
{
    _uibiosfini();
    del_curterm( cur_term );
}
Exemplo n.º 15
0
int main( int argc, char **argv )
{
	char *bgcolor=0;
	char *fgcolor=0;
	bool bold=false;
	bool underline=false;

	while( 1 )
	{
		static struct option
			long_options[] =
			{
				{
					"background", required_argument, 0, 'b' 
				}
				,
				{
					"help", no_argument, 0, 'h' 
				}
				,
				{
					"bold", no_argument, 0, 'o' 
				}
				,
				{
					"underline", no_argument, 0, 'u' 
				}
				,
				{
					"version", no_argument, 0, 'v' 
				}
				,
				{
					"print-colors", no_argument, 0, 'c' 
				}
				,
				{ 
					0, 0, 0, 0 
				}
			}
		;		
		
		int opt_index = 0;
		
		int opt = getopt_long( argc,
							   argv, 
							   GETOPT_STRING, 
							   long_options, 
							   &opt_index );

		if( opt == -1 )
			break;
			
		switch( opt )
		{
			case 0:
				break;
				
			case 'b':				
				bgcolor = optarg;
				break;
			case 'h':
				print_help( argv[0], 1 );
				exit(0);				
								
			case 'o':
				bold=true;
				break;
				
			case 'u':
				underline=true;
				break;
				
			case 'v':
				check_locale_init();
				fprintf( stderr, _("%s, version %s\n"), SET_COLOR, PACKAGE_VERSION );
				exit( 0 );								

			case 'c':
				print_colors();
				exit(0);
				
			case '?':
				return 1;
				
		}
		
	}		
	
	switch( argc-optind)
	{
		case 0:
//			printf( "no fg\n" );
			break;
			
		case 1:
			fgcolor=argv[optind];
//			printf( "fg %s\n", fgcolor );
			break;
			
		default:
			check_locale_init();
			printf( _("%s: Too many arguments\n"), SET_COLOR );
			return 1;
	}
    
    /* Infer term256 support */
    char *fish_term256 = getenv("fish_term256");
    if (fish_term256) {
        support_term256 = from_string<bool>(fish_term256);
    } else {
        const char *term = getenv("TERM");
        support_term256 = term && strstr(term, "256color");
    }

	if( !fgcolor && !bgcolor && !bold && !underline )
	{
		check_locale_init();
		fprintf( stderr, _("%s: Expected an argument\n"), SET_COLOR );
		print_help( argv[0], 2 );		
		return 1;
	}
    
    rgb_color_t fg = rgb_color_t(fgcolor ? fgcolor : "");
	if( fgcolor && fg.is_none())
	{
		check_locale_init();
		fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, fgcolor );
		return 1;		
	}

    rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : "");
	if( bgcolor && bg.is_none())
	{
		check_locale_init();
		fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, bgcolor );
		return 1;		
	}

	setupterm( 0, STDOUT_FILENO, 0);

	if( bold )
	{
		if( enter_bold_mode )
			putp( enter_bold_mode );
	}

	if( underline )
	{
		if( enter_underline_mode )
			putp( enter_underline_mode );
	}

	if( bgcolor )
	{
		if( bg.is_normal() )
		{
            write_background_color(0);
			putp( tparm(exit_attribute_mode) );		
		}	
	}

	if( fgcolor )
	{
		if( fg.is_normal() )
		{
            write_foreground_color(0);
			putp( tparm(exit_attribute_mode) );		
		}	
		else
		{
            write_foreground_color(index_for_color(fg));
		}
	}
	
	if( bgcolor )
	{
		if( ! bg.is_normal() )
		{
            write_background_color(index_for_color(bg));
		}
	}

	if( del_curterm( cur_term ) == ERR )
	{
		fprintf( stderr, "%s", _("Error while closing terminfo") );
	}

}
Exemplo n.º 16
0
delscreen(SCREEN *sp)
{
    SCREEN **scan = &_nc_screen_chain;
    int i;

    T((T_CALLED("delscreen(%p)"), sp));

    while (*scan) {
	if (*scan == sp) {
	    *scan = sp->_next_screen;
	    break;
	}
	scan = &(*scan)->_next_screen;
    }

    (void) _nc_freewin(sp->_curscr);
    (void) _nc_freewin(sp->_newscr);
    (void) _nc_freewin(sp->_stdscr);

    if (sp->_slk != 0) {
	if (sp->_slk->ent != 0) {
	    for (i = 0; i < sp->_slk->labcnt; ++i) {
		FreeIfNeeded(sp->_slk->ent[i].ent_text);
		FreeIfNeeded(sp->_slk->ent[i].form_text);
	    }
	    free(sp->_slk->ent);
	}
	free(sp->_slk);
	sp->_slk = 0;
    }

    _nc_free_keytry(sp->_keytry);
    sp->_keytry = 0;

    _nc_free_keytry(sp->_key_ok);
    sp->_key_ok = 0;

    FreeIfNeeded(sp->_current_attr);

    FreeIfNeeded(sp->_color_table);
    FreeIfNeeded(sp->_color_pairs);

    FreeIfNeeded(sp->oldhash);
    FreeIfNeeded(sp->newhash);
    FreeIfNeeded(sp->hashtab);

    del_curterm(sp->_term);

    /*
     * If the associated output stream has been closed, we can discard the
     * set-buffer.  Limit the error check to EBADF, since fflush may fail
     * for other reasons than trying to operate upon a closed stream.
     */
    if (sp->_ofp != 0
	&& sp->_setbuf != 0
	&& fflush(sp->_ofp) != 0
	&& errno == EBADF) {
	free(sp->_setbuf);
    }

    free(sp);

    /*
     * If this was the current screen, reset everything that the
     * application might try to use (except cur_term, which may have
     * multiple references in different screens).
     */
    if (sp == SP) {
	curscr = 0;
	newscr = 0;
	stdscr = 0;
	COLORS = 0;
	COLOR_PAIRS = 0;
	_nc_set_screen(0);
    }
    returnVoid;
}
Exemplo n.º 17
0
_nc_freeall(void)
{
    WINDOWLIST *p, *q;
    char *s;

    T((T_CALLED("_nc_freeall()")));
#if NO_LEAKS
    _nc_free_tparm();
    if (_nc_oldnums != 0) {
	FreeAndNull(_nc_oldnums);
    }
#endif
    if (SP != 0) {
	while (_nc_windows != 0) {
	    /* Delete only windows that're not a parent */
	    for (p = _nc_windows; p != 0; p = p->next) {
		bool found = FALSE;

		for (q = _nc_windows; q != 0; q = q->next) {
		    if ((p != q)
			&& (q->win._flags & _SUBWIN)
			&& (&(p->win) == q->win._parent)) {
			found = TRUE;
			break;
		    }
		}

		if (!found) {
		    delwin(&(p->win));
		    break;
		}
	    }
	}
	delscreen(SP);
    }

    del_curterm(cur_term);
    _nc_free_entries(_nc_head);
    _nc_get_type(0);
    _nc_first_name(0);
#if USE_WIDEC_SUPPORT
    FreeIfNeeded(_nc_wacs);
#endif
#if NO_LEAKS
    _nc_alloc_entry_leaks();
    _nc_captoinfo_leaks();
    _nc_comp_scan_leaks();
#endif

    if ((s = _nc_home_terminfo()) != 0)
	free(s);

    (void) _nc_printf_string(0, 0);
#ifdef TRACE
    (void) _nc_trace_buf(-1, 0);
#endif

#if HAVE_LIBDBMALLOC
    malloc_dump(malloc_errfd);
#elif HAVE_LIBDMALLOC
#elif HAVE_LIBMPATROL
    __mp_summary();
#elif HAVE_PURIFY
    purify_all_inuse();
#endif
    returnVoid;
}
Exemplo n.º 18
0
/*
 * cl_vi_init --
 *	Initialize the curses vi screen.
 */
static int
cl_vi_init(SCR *sp)
{
	CL_PRIVATE *clp;
	char *o_cols, *o_lines, *o_term;
	const char *ttype;

	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(clp, CL_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(sp, "TERM", ttype, 0);
	o_lines = getenv("LINES");
	cl_putenv(sp, "LINES", NULL, (u_long)O_VAL(sp, O_LINES));
	o_cols = getenv("COLUMNS");
	cl_putenv(sp, "COLUMNS", NULL, (u_long)O_VAL(sp, O_COLUMNS));

	/* Delete cur_term if exists. */
	if (F_ISSET(clp, CL_SETUPTERM)) {
		if (del_curterm(cur_term))
			return (1);
		F_CLR(clp, CL_SETUPTERM);
	}

	/*
	 * 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 ((clp->screen = newterm(__UNCONST(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)
		cl_unsetenv(sp, "TERM");
	if (o_lines == NULL)
		cl_unsetenv(sp, "LINES");
	if (o_cols == NULL)
		cl_unsetenv(sp, "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);
}