Ejemplo n.º 1
0
/*
 * main --
 *	This is the main loop for the standalone curses editor.
 */
int
main(int argc, char *argv[])
{
	CL_PRIVATE *clp;
	GS *gp;
	size_t rows, cols;
	int rval;
	char *ttype;

	/* Create and initialize the global structure. */
	__global_list = gp = gs_init();

	/* Create and initialize the CL_PRIVATE structure. */
	clp = cl_init(gp);

	/*
	 * Initialize the terminal information.
	 *
	 * We have to know what terminal it is from the start, since we may
	 * have to use termcap/terminfo to find out how big the screen is.
	 */
	if ((ttype = getenv("TERM")) == NULL)
		ttype = "unknown";
	term_init(ttype);

	/* Add the terminal type to the global structure. */
	if ((OG_D_STR(gp, GO_TERM) =
	    OG_STR(gp, GO_TERM) = strdup(ttype)) == NULL)
		err(1, NULL);

	/* Figure out how big the screen is. */
	if (cl_ssize(NULL, 0, &rows, &cols, NULL))
		exit (1);

	/* Add the rows and columns to the global structure. */
	OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = rows;
	OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = cols;

	/* Ex wants stdout to be buffered. */
	(void)setvbuf(stdout, NULL, _IOFBF, 0);

	/* Start catching signals. */
	if (sig_init(gp, NULL))
		exit (1);

	/* Run ex/vi. */
	rval = editor(gp, argc, argv);

	/* Clean up signals. */
	sig_end(gp);

	/* Clean up the terminal. */
	(void)cl_quit(gp);

	/*
	 * XXX
	 * Reset the O_MESG option.
	 */
	if (clp->tgw != TGW_UNKNOWN)
		(void)cl_omesg(NULL, clp, clp->tgw == TGW_SET);

	/*
	 * XXX
	 * Reset the X11 xterm icon/window name.
	 */
	if (F_ISSET(clp, CL_RENAME)) {
		(void)printf(XTERM_RENAME, ttype);
		(void)fflush(stdout);
	}

	/* If a killer signal arrived, pretend we just got it. */
	if (clp->killersig) {
		(void)signal(clp->killersig, SIG_DFL);
		(void)kill(getpid(), clp->killersig);
		/* NOTREACHED */
	}

	/* Free the global and CL private areas. */
#if defined(DEBUG) || defined(PURIFY)
	free(clp);
	free(gp);
#endif

	exit (rval);
}
Ejemplo n.º 2
0
/*
 * cl_event --
 *	Return a single event.
 *
 * PUBLIC: int cl_event __P((SCR *, EVENT *, u_int32_t, int));
 */
int
cl_event(SCR *sp, EVENT *evp, u_int32_t flags, int ms)
{
    struct timeval t, *tp;
    CL_PRIVATE *clp;
    size_t lines, columns;
    int changed, nr = 0;
    CHAR_T *wp;
    size_t wlen;
    int rc;

    /*
     * Queue signal based events.  We never clear SIGHUP or SIGTERM events,
     * so that we just keep returning them until the editor dies.
     */
    clp = CLP(sp);
retest:
    if (LF_ISSET(EC_INTERRUPT) || F_ISSET(clp, CL_SIGINT)) {
        if (F_ISSET(clp, CL_SIGINT)) {
            F_CLR(clp, CL_SIGINT);
            evp->e_event = E_INTERRUPT;
        } else
            evp->e_event = E_TIMEOUT;
        return (0);
    }
    if (F_ISSET(clp, CL_SIGHUP | CL_SIGTERM | CL_SIGWINCH)) {
        if (F_ISSET(clp, CL_SIGHUP)) {
            evp->e_event = E_SIGHUP;
            return (0);
        }
        if (F_ISSET(clp, CL_SIGTERM)) {
            evp->e_event = E_SIGTERM;
            return (0);
        }
        if (F_ISSET(clp, CL_SIGWINCH)) {
            F_CLR(clp, CL_SIGWINCH);
            if (cl_ssize(sp, 1, &lines, &columns, &changed))
                return (1);
            if (changed) {
                (void)cl_resize(sp, lines, columns);
                evp->e_event = E_WRESIZE;
                return (0);
            }
            /* No real change, ignore the signal. */
        }
    }

    /* Set timer. */
    if (ms == 0)
        tp = NULL;
    else {
        t.tv_sec = ms / 1000;
        t.tv_usec = (ms % 1000) * 1000;
        tp = &t;
    }

    /* Read input characters. */
read:
    switch (cl_read(sp, LF_ISSET(EC_QUOTED | EC_RAW),
                    clp->ibuf + clp->skip, SIZE(clp->ibuf) - clp->skip, &nr, tp)) {
    case INP_OK:
        rc = INPUT2INT5(sp, clp->cw, clp->ibuf, nr + clp->skip,
                        wp, wlen);
        evp->e_csp = wp;
        evp->e_len = wlen;
        evp->e_event = E_STRING;
        if (rc < 0) {
            int n = -rc;
            memmove(clp->ibuf, clp->ibuf + nr + clp->skip - n, n);
            clp->skip = n;
            if (wlen == 0)
                goto read;
        } else if (rc == 0)
            clp->skip = 0;
        else
            msgq(sp, M_ERR, "323|Invalid input. Truncated.");
        break;
    case INP_EOF:
        evp->e_event = E_EOF;
        break;
    case INP_ERR:
        evp->e_event = E_ERR;
        break;
    case INP_INTR:
        goto retest;
    case INP_TIMEOUT:
        evp->e_event = E_TIMEOUT;
        break;
    default:
        abort();
    }
    return (0);
}
Ejemplo n.º 3
0
/*
 * cl_suspend --
 *	Suspend a screen.
 *
 * PUBLIC: int cl_suspend __P((SCR *, int *));
 */
int
cl_suspend(SCR *sp, int *allowedp)
{
	struct termios t;
	CL_PRIVATE *clp;
	WINDOW *win;
	size_t y, x;
	int changed;

	clp = CLP(sp);
	win = CLSP(sp) ? CLSP(sp) : stdscr;
	*allowedp = 1;

	/*
	 * The ex implementation of this function isn't needed by screens not
	 * supporting ex commands that require full terminal canonical mode
	 * (e.g. :suspend).
	 *
	 * The vi implementation of this function isn't needed by screens not
	 * supporting vi process suspension, i.e. any screen that isn't backed
	 * by a UNIX shell.
	 *
	 * Setting allowedp to 0 will cause the editor to reject the command.
	 */
	if (F_ISSET(sp, SC_EX)) { 
		/* Save the terminal settings, and restore the original ones. */
		if (F_ISSET(clp, CL_STDIN_TTY)) {
			(void)tcgetattr(STDIN_FILENO, &t);
			(void)tcsetattr(STDIN_FILENO,
			    TCSASOFT | TCSADRAIN, &clp->orig);
		}

		/* Stop the process group. */
		(void)kill(0, SIGTSTP);

		/* Time passes ... */

		/* Restore terminal settings. */
		if (F_ISSET(clp, CL_STDIN_TTY))
			(void)tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &t);
		return (0);
	}

	/*
	 * Move to the lower left-hand corner of the screen.
	 *
	 * XXX
	 * Not sure this is necessary in System V implementations, but it
	 * shouldn't hurt.
	 */
	getyx(win, y, x);
	(void)wmove(win, LINES - 1, 0);
	(void)wrefresh(win);

	/*
	 * Temporarily end the screen.  System V introduced a semantic where
	 * endwin() could be restarted.  We use it because restarting curses
	 * from scratch often fails in System V.  4BSD curses didn't support
	 * restarting after endwin(), so we have to do what clean up we can
	 * without calling it.
	 */
	/* Save the terminal settings. */
	(void)tcgetattr(STDIN_FILENO, &t);

	/* Restore the cursor keys to normal mode. */
	(void)keypad(stdscr, FALSE);

	/* Restore the window name. */
	(void)cl_rename(sp, NULL, 0);

#ifdef HAVE_BSD_CURSES
	(void)cl_attr(sp, SA_ALTERNATE, 0);
#else
	(void)endwin();
#endif
	/*
	 * XXX
	 * Restore the original terminal settings.  This is bad -- the
	 * reset can cause character loss from the tty queue.  However,
	 * we can't call endwin() in BSD curses implementations, and too
	 * many System V curses implementations don't get it right.
	 */
	(void)tcsetattr(STDIN_FILENO, TCSADRAIN | TCSASOFT, &clp->orig);

	/* Stop the process group. */
	(void)kill(0, SIGTSTP);

	/* Time passes ... */

	/*
	 * If we received a killer signal, we're done.  Leave everything
	 * unchanged.  In addition, the terminal has already been reset
	 * correctly, so leave it alone.
	 */
	if (clp->killersig) {
		F_CLR(clp, CL_SCR_EX_INIT | CL_SCR_VI_INIT);
		return (0);
	}

	/* Restore terminal settings. */
	wrefresh(win);			    /* Needed on SunOs/Solaris ? */
	if (F_ISSET(clp, CL_STDIN_TTY))
		(void)tcsetattr(STDIN_FILENO, TCSASOFT | TCSADRAIN, &t);

#ifdef HAVE_BSD_CURSES
	(void)cl_attr(sp, SA_ALTERNATE, 1);
#endif

	/* Set the window name. */
	(void)cl_rename(sp, sp->frp->name, 1);

	/* Put the cursor keys into application mode. */
	(void)keypad(stdscr, TRUE);

	/* Refresh and repaint the screen. */
	(void)wmove(win, y, x);
	(void)cl_refresh(sp, 1);

	/* If the screen changed size, set the SIGWINCH bit. */
	if (cl_ssize(sp, 1, NULL, NULL, &changed))
		return (1);
	if (changed)
		F_SET(CLP(sp), CL_SIGWINCH);

	return (0);
}
Ejemplo n.º 4
0
/*
 * main --
 *	This is the main loop for the standalone curses editor.
 */
int
main(int argc, char *argv[])
{
	static int reenter;
	CL_PRIVATE *clp;
	GS *gp;
	size_t rows, cols;
	int rval;
	char *ttype;
#ifdef RUNNING_IP
	char *ip_arg;
	char **p_av, **t_av;
#endif

	/* If loaded at 0 and jumping through a NULL pointer, stop. */
	if (reenter++)
		abort();

	/* Create and initialize the global structure. */
	__global_list = gp = gs_init(argv[0]);

	/*
	 * Strip out any arguments that vi isn't going to understand.  There's
	 * no way to portably call getopt twice, so arguments parsed here must
	 * be removed from the argument list.
	 */
#ifdef RUNNING_IP
	ip_arg = NULL;
	for (p_av = t_av = argv;;) {
		if (*t_av == NULL) {
			*p_av = NULL;
			break;
		}
		if (!strcmp(*t_av, "--")) {
			while ((*p_av++ = *t_av++) != NULL);
			break;
		}
		if (!memcmp(*t_av, "-I", sizeof("-I") - 1)) {
			if (t_av[0][2] != '\0') {
				ip_arg = t_av[0] + 2;
				++t_av;
				--argc;
				continue;
			}
			if (t_av[1] != NULL) {
				ip_arg = t_av[1];
				t_av += 2;
				argc -= 2;
				continue;
			}
		}
		*p_av++ = *t_av++;
	}

	/*
	 * If we're being called as an editor library, we're done here, we
	 * get loaded with the curses screen, we don't share much code.
	 */
	if (ip_arg != NULL)
		exit (ip_main(argc, argv, gp, ip_arg));
#endif
		
	/* Create and initialize the CL_PRIVATE structure. */
	clp = cl_init(gp);

	/*
	 * Initialize the terminal information.
	 *
	 * We have to know what terminal it is from the start, since we may
	 * have to use termcap/terminfo to find out how big the screen is.
	 */
	if ((ttype = getenv("TERM")) == NULL)
		ttype = "unknown";
	term_init(gp->progname, ttype);

	/* Add the terminal type to the global structure. */
	if ((OG_D_STR(gp, GO_TERM) =
	    OG_STR(gp, GO_TERM) = strdup(ttype)) == NULL)
		perr(gp->progname, NULL);

	/* Figure out how big the screen is. */
	if (cl_ssize(NULL, 0, &rows, &cols, NULL))
		exit (1);

	/* Add the rows and columns to the global structure. */
	OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = rows;
	OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = cols;

	/* Ex wants stdout to be buffered. */
	(void)setvbuf(stdout, NULL, _IOFBF, 0);

	/* Start catching signals. */
	if (sig_init(gp, NULL))
		exit (1);

	/* Run ex/vi. */
	rval = editor(gp, argc, argv);

	/* Clean up signals. */
	sig_end(gp);

	/* Clean up the terminal. */
	(void)cl_quit(gp);

	/*
	 * XXX
	 * Reset the O_MESG option.
	 */
	if (clp->tgw != TGW_UNKNOWN)
		(void)cl_omesg(NULL, clp, clp->tgw == TGW_SET);

	/*
	 * XXX
	 * Reset the X11 xterm icon/window name.
	 */
	if (F_ISSET(clp, CL_RENAME)) {
		(void)printf(XTERM_RENAME, ttype);
		(void)fflush(stdout);
	}

	/* If a killer signal arrived, pretend we just got it. */
	if (clp->killersig) {
		(void)signal(clp->killersig, SIG_DFL);
		(void)kill(getpid(), clp->killersig);
		/* NOTREACHED */
	}

	/* Free the global and CL private areas. */
#if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
	free(clp);
	free(gp);
#endif

	exit (rval);
}
Ejemplo n.º 5
0
/*
 * main --
 *	This is the main loop for the standalone curses editor.
 */
int
main(int argc, char **argv)
{
	static int reenter;
	CL_PRIVATE *clp;
	GS *gp;
	WIN *wp;
	size_t rows, cols;
	int rval;
	char **p_av, **t_av;
	const char *ttype;

	/* If loaded at 0 and jumping through a NULL pointer, stop. */
	if (reenter++)
		abort();

	/* Create and initialize the global structure. */
	__global_list = gp = gs_init(argv[0]);

	/*
	 * Strip out any arguments that vi isn't going to understand.  There's
	 * no way to portably call getopt twice, so arguments parsed here must
	 * be removed from the argument list.
	 */
	for (p_av = t_av = argv;;) {
		if (*t_av == NULL) {
			*p_av = NULL;
			break;
		}
		if (!strcmp(*t_av, "--")) {
			while ((*p_av++ = *t_av++) != NULL);
			break;
		}
		*p_av++ = *t_av++;
	}

	/* Create new window */
	wp = gs_new_win(gp);
		
	/* Create and initialize the CL_PRIVATE structure. */
	clp = cl_init(wp);

	/*
	 * Initialize the terminal information.
	 *
	 * We have to know what terminal it is from the start, since we may
	 * have to use termcap/terminfo to find out how big the screen is.
	 */
	if ((ttype = getenv("TERM")) == NULL) {
		if (isatty(STDIN_FILENO))
			fprintf(stderr, "%s: warning: TERM is not set\n",
			    gp->progname);
		ttype = "unknown";
	}
	term_init(gp->progname, ttype);

	/* Add the terminal type to the global structure. */
	if ((OG_D_STR(gp, GO_TERM) =
	    OG_STR(gp, GO_TERM) = strdup(ttype)) == NULL)
		perr(gp->progname, NULL);

	/* Figure out how big the screen is. */
	if (cl_ssize(NULL, 0, &rows, &cols, NULL))
		exit (1);

	/* Add the rows and columns to the global structure. */
	OG_VAL(gp, GO_LINES) = OG_D_VAL(gp, GO_LINES) = rows;
	OG_VAL(gp, GO_COLUMNS) = OG_D_VAL(gp, GO_COLUMNS) = cols;

	/* Ex wants stdout to be buffered. */
	(void)setvbuf(stdout, NULL, _IOFBF, 0);

	/* Start catching signals. */
	if (sig_init(gp, NULL))
		exit (1);

	/* Run ex/vi. */
	rval = editor(wp, argc, argv);

	/* Clean out the global structure. */
	gs_end(gp);

	/* Clean up signals. */
	sig_end(gp);

	/* Clean up the terminal. */
	(void)cl_quit(gp);

	/*
	 * XXX
	 * Reset the O_MESG option.
	 */
	if (clp->tgw != TGW_UNKNOWN)
		(void)cl_omesg(NULL, clp, clp->tgw == TGW_SET);

	/*
	 * XXX
	 * Reset the X11 xterm icon/window name.
	 */
	if (F_ISSET(clp, CL_RENAME))
		cl_setname(gp, clp->oname);

	/* If a killer signal arrived, pretend we just got it. */
	if (clp->killersig) {
		(void)signal(clp->killersig, SIG_DFL);
		(void)kill(getpid(), clp->killersig);
		/* NOTREACHED */
	}

	/* Free the global and CL private areas. */
#if defined(DEBUG) || defined(PURIFY) || defined(LIBRARY)
	cl_end(clp);
	free(gp);
#endif

	exit (rval);
}