コード例 #1
0
ファイル: ex_script.c プロジェクト: darksoul42/bitrig
/*
 * sscr_input --
 *	Read any waiting shell input.
 *
 * PUBLIC: int sscr_input(SCR *);
 */
int
sscr_input(SCR *sp)
{
	GS *gp;
	struct pollfd *pfd;
	int nfds, rval;

	gp = sp->gp;
	rval = 0;

	/* Allocate space for pfd. */
	nfds = 0;
	TAILQ_FOREACH(sp, &gp->dq, q)
		if (F_ISSET(sp, SC_SCRIPT))
			nfds++;
	if (nfds == 0)
		return (0);
	pfd = calloc(nfds, sizeof(struct pollfd));
	if (pfd == NULL) {
		msgq(sp, M_SYSERR, "malloc");
		return (1);
	}

	/* Setup events bitmasks. */
	nfds = 0;
	TAILQ_FOREACH(sp, &gp->dq, q)
		if (F_ISSET(sp, SC_SCRIPT)) {
			pfd[nfds].fd = sp->script->sh_master;
			pfd[nfds].events = POLLIN;
			nfds++;
		}

loop:
	/* Check for input. */
	switch (poll(pfd, nfds, 0)) {
	case -1:
		msgq(sp, M_SYSERR, "poll");
		rval = 1;
		/* FALLTHROUGH */
	case 0:
		goto done;
	default:
		break;
	}

	/* Read the input. */
	nfds = 0;
	TAILQ_FOREACH(sp, &gp->dq, q)
		if (F_ISSET(sp, SC_SCRIPT)) {
			if ((pfd[nfds].revents & POLLHUP) && sscr_end(sp))
				goto done;
			if ((pfd[nfds].revents & POLLIN) && sscr_insert(sp))
				goto done;
			nfds++;
		}
	goto loop;
done:
	free(pfd);
	return (rval);
}
コード例 #2
0
/*
 * sscr_getprompt --
 *	Eat lines printed by the shell until a line with no trailing
 *	carriage return comes; set the prompt from that line.
 */
static int
sscr_getprompt(SCR *sp)
{
	struct timeval tv;
	fd_set fdset;
	int master;

	/* Wait up to a second for characters to read. */
	tv.tv_sec = 5;
	tv.tv_usec = 0;
	master = sp->script->sh_master;
	FD_ZERO(&fdset);
	FD_SET(master, &fdset);
	switch (select(master + 1, &fdset, NULL, NULL, &tv)) {
	case -1:		/* Error or interrupt. */
		msgq(sp, M_SYSERR, "select");
		break;
	case  0:		/* Timeout */
		msgq(sp, M_ERR, "Error: timed out");
		break;
	case  1:		/* Characters to read. */
		return (sscr_insert(sp) || sp->script == NULL);
	}

	sscr_end(sp);
	return (1);
}
コード例 #3
0
ファイル: ex_init.c プロジェクト: fishman/nvi
/*
 * ex_screen_end --
 *	End a vi screen.
 *
 * PUBLIC: int ex_screen_end __P((SCR *));
 */
int
ex_screen_end(SCR *sp)
{
	EX_PRIVATE *exp;
	int rval;

	if ((exp = EXP(sp)) == NULL)
		return (0);

	rval = 0;

	/* Close down script connections. */
	if (F_ISSET(sp, SC_SCRIPT) && sscr_end(sp))
		rval = 1;

	if (argv_free(sp))
		rval = 1;

	if (exp->ibp != NULL)
		free(exp->ibp);

	if (exp->lastbcomm != NULL)
		free(exp->lastbcomm);

	if (ex_tag_free(sp))
		rval = 1;

	/* Free private memory. */
	free(exp);
	sp->ex_private = NULL;

	return (rval);
}
コード例 #4
0
ファイル: ex_script.c プロジェクト: darksoul42/bitrig
/*
 * sscr_check_input -
 *	Check for input from command input or scripting windows.
 *
 * PUBLIC: int sscr_check_input(SCR *sp);
 */
int
sscr_check_input(SCR *sp)
{
	GS *gp;
	SCR *tsp;
	struct pollfd *pfd;
	int nfds, rval;

	gp = sp->gp;
	rval = 0;

	/* Allocate space for pfd. */   
	nfds = 1;
	TAILQ_FOREACH(tsp, &gp->dq, q)
		if (F_ISSET(sp, SC_SCRIPT))
			nfds++;
	pfd = calloc(nfds, sizeof(struct pollfd));
	if (pfd == NULL) {
		msgq(sp, M_SYSERR, "malloc");
		return (1);
	}

	/* Setup events bitmasks. */
	pfd[0].fd = STDIN_FILENO;
	pfd[0].events = POLLIN;
	nfds = 1;
	TAILQ_FOREACH(tsp, &gp->dq, q)
		if (F_ISSET(sp, SC_SCRIPT)) {
			pfd[nfds].fd = sp->script->sh_master;
			pfd[nfds].events = POLLIN;
			nfds++;
		}

loop:
	/* Check for input. */
	switch (poll(pfd, nfds, INFTIM)) {
	case -1:
		msgq(sp, M_SYSERR, "poll");
		rval = 1;
		/* FALLTHROUGH */
	case 0:
		goto done;
	default:
		break;
	}

	/* Only insert from the scripting windows if no command input */
	if (!(pfd[0].revents & POLLIN)) {
		nfds = 1;
		TAILQ_FOREACH(tsp, &gp->dq, q)
			if (F_ISSET(sp, SC_SCRIPT)) {
				if ((pfd[nfds].revents & POLLHUP) && sscr_end(sp))
					goto done;
				if ((pfd[nfds].revents & POLLIN) && sscr_insert(sp))
					goto done;
				nfds++;
			}
		goto loop;
	}
コード例 #5
0
ファイル: ex_script.c プロジェクト: darksoul42/bitrig
/*
 * sscr_setprompt --
 *
 * Set the prompt to the last line we got from the shell.
 *
 */
static int
sscr_setprompt(SCR *sp, char *buf, size_t len)
{
	SCRIPT *sc;

	sc = sp->script;
	if (sc->sh_prompt)
		free(sc->sh_prompt);
	MALLOC(sp, sc->sh_prompt, len + 1);
	if (sc->sh_prompt == NULL) {
		sscr_end(sp);
		return (1);
	}
	memmove(sc->sh_prompt, buf, len);
	sc->sh_prompt_len = len;
	sc->sh_prompt[len] = '\0';
	return (0);
}
コード例 #6
0
ファイル: ex_script.c プロジェクト: Hooman3/minix
/*
 * sscr_setprompt --
 *
 * Set the prompt to the last line we got from the shell.
 *
 */
static int
sscr_setprompt(SCR *sp, CHAR_T *buf, size_t len)
{
	SCRIPT *sc;
	const char *np;
	size_t nlen;

	sc = sp->script;
	if (sc->sh_prompt)
		free(sc->sh_prompt);
	MALLOC(sp, sc->sh_prompt, char *, len + 1);
	if (sc->sh_prompt == NULL) {
		sscr_end(sp);
		return (1);
	}
	INT2CHAR(sp, buf, len, np, nlen);
	memmove(sc->sh_prompt, np, nlen);
	sc->sh_prompt_len = len;
	sc->sh_prompt[len] = '\0';
	return (0);
}
コード例 #7
0
ファイル: ex_script.c プロジェクト: darksoul42/bitrig
/*
 * sscr_insert --
 *	Take a line from the shell and insert it into the file.
 */
static int
sscr_insert(SCR *sp)
{
	CHAR_T *endp, *p, *t;
	SCRIPT *sc;
	struct pollfd pfd[1];
	recno_t lno;
	size_t blen, len, tlen;
	u_int value;
	int nr, rval;
	char *bp;

	/* Find out where the end of the file is. */
	if (db_last(sp, &lno))
		return (1);

#define	MINREAD	1024
	GET_SPACE_RET(sp, bp, blen, MINREAD);
	endp = bp;

	/* Read the characters. */
	rval = 1;
	sc = sp->script;
more:	switch (nr = read(sc->sh_master, endp, MINREAD)) {
	case  0:			/* EOF; shell just exited. */
		sscr_end(sp);
		rval = 0;
		goto ret;
	case -1:			/* Error or interrupt. */
		msgq(sp, M_SYSERR, "shell");
		goto ret;
	default:
		endp += nr;
		break;
	}

	/* Append the lines into the file. */
	for (p = t = bp; p < endp; ++p) {
		value = KEY_VAL(sp, *p);
		if (value == K_CR || value == K_NL) {
			len = p - t;
			if (db_append(sp, 1, lno++, t, len))
				goto ret;
			t = p + 1;
		}
	}
	if (p > t) {
		len = p - t;
		/*
		 * If the last thing from the shell isn't another prompt, wait
		 * up to 1/10 of a second for more stuff to show up, so that
		 * we don't break the output into two separate lines.  Don't
		 * want to hang indefinitely because some program is hanging,
		 * confused the shell, or whatever.
		 */
		if (!sscr_matchprompt(sp, t, len, &tlen) || tlen != 0) {
			pfd[0].fd = sc->sh_master;
			pfd[0].events = POLLIN;
			if (poll(pfd, 1, 100) > 0) {
				memmove(bp, t, len);
				endp = bp + len;
				goto more;
			}
		}
		if (sscr_setprompt(sp, t, len))
			return (1);
		if (db_append(sp, 1, lno++, t, len))
			goto ret;
	}

	/* The cursor moves to EOF. */
	sp->lno = lno;
	sp->cno = len ? len - 1 : 0;
	rval = vs_refresh(sp, 1);

ret:	FREE_SPACE(sp, bp, blen);
	return (rval);
}
コード例 #8
0
ファイル: ex_script.c プロジェクト: darksoul42/bitrig
/*
 * sscr_getprompt --
 *	Eat lines printed by the shell until a line with no trailing
 *	carriage return comes; set the prompt from that line.
 */
static int
sscr_getprompt(SCR *sp)
{
	CHAR_T *endp, *p, *t, buf[1024];
	SCRIPT *sc;
	struct pollfd pfd[1];
	recno_t lline;
	size_t llen, len;
	u_int value;
	int nr;

	endp = buf;
	len = sizeof(buf);

	/* Wait up to a second for characters to read. */
	sc = sp->script;
	pfd[0].fd = sc->sh_master;
	pfd[0].events = POLLIN;
	switch (poll(pfd, 1, 5 * 1000)) {
	case -1:		/* Error or interrupt. */
		msgq(sp, M_SYSERR, "poll");
		goto prompterr;
	case  0:		/* Timeout */
		msgq(sp, M_ERR, "Error: timed out");
		goto prompterr;
	default:		/* Characters to read. */
		break;
	}

	/* Read the characters. */
more:	len = sizeof(buf) - (endp - buf);
	switch (nr = read(sc->sh_master, endp, len)) {
	case  0:			/* EOF. */
		msgq(sp, M_ERR, "Error: shell: EOF");
		goto prompterr;
	case -1:			/* Error or interrupt. */
		msgq(sp, M_SYSERR, "shell");
		goto prompterr;
	default:
		endp += nr;
		break;
	}

	/* If any complete lines, push them into the file. */
	for (p = t = buf; p < endp; ++p) {
		value = KEY_VAL(sp, *p);
		if (value == K_CR || value == K_NL) {
			if (db_last(sp, &lline) ||
			    db_append(sp, 0, lline, t, p - t))
				goto prompterr;
			t = p + 1;
		}
	}
	if (p > buf) {
		memmove(buf, t, endp - t);
		endp = buf + (endp - t);
	}
	if (endp == buf)
		goto more;

	/* Wait up 1/10 of a second to make sure that we got it all. */
	switch (poll(pfd, 1, 100)) {
	case -1:		/* Error or interrupt. */
		msgq(sp, M_SYSERR, "poll");
		goto prompterr;
	case  0:		/* Timeout */
		break;
	default:		/* Characters to read. */
		goto more;
	}

	/* Timed out, so theoretically we have a prompt. */
	llen = endp - buf;
	endp = buf;

	/* Append the line into the file. */
	if (db_last(sp, &lline) || db_append(sp, 0, lline, buf, llen)) {
prompterr:	sscr_end(sp);
		return (1);
	}

	return (sscr_setprompt(sp, buf, llen));
}
コード例 #9
0
/*
 * sscr_insert --
 *	Take a line from the shell and insert it into the file.
 */
static int
sscr_insert(SCR *sp)
{
	struct timeval tv;
	char *endp, *p, *t;
	SCRIPT *sc;
	fd_set rdfd;
	db_recno_t lno;
	size_t len;
	ssize_t nr;
	char bp[1024];
	const CHAR_T *ip;
	size_t ilen = 0;

	/* Find out where the end of the file is. */
	if (db_last(sp, &lno))
		return (1);

	endp = bp;

	/* Read the characters. */
	sc = sp->script;
more:	switch (nr = read(sc->sh_master, endp, bp + sizeof(bp) - endp)) {
	case  0:			/* EOF; shell just exited. */
		sscr_end(sp);
		return (0);
	case -1:			/* Error or interrupt. */
		msgq(sp, M_SYSERR, "shell");
		return (1);
	default:
		endp += nr;
		break;
	}

	/* Append the lines into the file. */
	for (p = t = bp; p < endp; ++p) {
		if (*p == '\r' || *p == '\n') {
			len = p - t;
			if (CHAR2INT(sp, t, len, ip, ilen) ||
			    db_append(sp, 1, lno++, ip, ilen))
				return (1);
			t = p + 1;
		}
	}
	/*
	 * If the last thing from the shell isn't another prompt, wait up to
	 * 1/10 of a second for more stuff to show up, so that we don't break
	 * the output into two separate lines.  Don't want to hang indefinitely
	 * because some program is hanging, confused the shell, or whatever.
	 * Note that sc->sh_prompt can be NULL here.
	 */
	len = p - t;
	if (sc->sh_prompt == NULL || len != sc->sh_prompt_len ||
	    memcmp(t, sc->sh_prompt, len) != 0) {
		tv.tv_sec = 0;
		tv.tv_usec = 100000;
		FD_ZERO(&rdfd);
		FD_SET(sc->sh_master, &rdfd);
		if (select(sc->sh_master + 1, &rdfd, NULL, NULL, &tv) == 1) {
			if (len == sizeof(bp)) {
				if (CHAR2INT(sp, t, len, ip, ilen) ||
				    db_append(sp, 1, lno++, ip, ilen))
					return (1);
				endp = bp;
			} else {
				memmove(bp, t, len);
				endp = bp + len;
			}
			goto more;
		}
		if (sscr_setprompt(sp, t, len))
			return (1);
	}

	/* Append the remains into the file, and the cursor moves to EOF. */
	if (len > 0) {
		if (CHAR2INT(sp, t, len, ip, ilen) ||
		    db_append(sp, 1, lno++, ip, ilen))
			return (1);
		sp->cno = ilen - 1;
	} else
		sp->cno = 0;
	sp->lno = lno;
	return (vs_refresh(sp, 1));
}
コード例 #10
0
ファイル: ex_script.c プロジェクト: Hooman3/minix
/*
 * sscr_getprompt --
 *	Eat lines printed by the shell until a line with no trailing
 *	carriage return comes; set the prompt from that line.
 */
static int
sscr_getprompt(SCR *sp)
{
	struct timeval tv;
	CHAR_T *endp, *p, *t, buf[1024];
	SCRIPT *sc;
	fd_set fdset;
	db_recno_t lline;
	size_t llen, len;
	e_key_t value;
	int nr;

	FD_ZERO(&fdset);
	endp = buf;
	len = sizeof(buf);

	/* Wait up to a second for characters to read. */
	tv.tv_sec = 5;
	tv.tv_usec = 0;
	sc = sp->script;
	FD_SET(sc->sh_master, &fdset);
	switch (select(sc->sh_master + 1, &fdset, NULL, NULL, &tv)) {
	case -1:		/* Error or interrupt. */
		msgq(sp, M_SYSERR, "select");
		goto prompterr;
	case  0:		/* Timeout */
		msgq(sp, M_ERR, "Error: timed out");
		goto prompterr;
	case  1:		/* Characters to read. */
		break;
	}

	/* Read the characters. */
more:	len = sizeof(buf) - (endp - buf);
	switch (nr = read(sc->sh_master, endp, len)) {
	case  0:			/* EOF. */
		msgq(sp, M_ERR, "Error: shell: EOF");
		goto prompterr;
	case -1:			/* Error or interrupt. */
		msgq(sp, M_SYSERR, "shell");
		goto prompterr;
	default:
		endp += nr;
		break;
	}

	/* If any complete lines, push them into the file. */
	for (p = t = buf; p < endp; ++p) {
		value = KEY_VAL(sp, *p);
		if (value == K_CR || value == K_NL) {
			if (db_last(sp, &lline) ||
			    db_append(sp, 0, lline, t, p - t))
				goto prompterr;
			t = p + 1;
		}
	}
	if (p > buf) {
		MEMMOVE(buf, t, endp - t);
		endp = buf + (endp - t);
	}
	if (endp == buf)
		goto more;

	/* Wait up 1/10 of a second to make sure that we got it all. */
	tv.tv_sec = 0;
	tv.tv_usec = 100000;
	switch (select(sc->sh_master + 1, &fdset, NULL, NULL, &tv)) {
	case -1:		/* Error or interrupt. */
		msgq(sp, M_SYSERR, "select");
		goto prompterr;
	case  0:		/* Timeout */
		break;
	case  1:		/* Characters to read. */
		goto more;
	}

	/* Timed out, so theoretically we have a prompt. */
	llen = endp - buf;
	endp = buf;

	/* Append the line into the file. */
	if (db_last(sp, &lline) || db_append(sp, 0, lline, buf, llen)) {
prompterr:	sscr_end(sp);
		return (1);
	}

	return (sscr_setprompt(sp, buf, llen));
}