Exemplo n.º 1
0
static int
zpcre_get_substrings(char *arg, int *ovec, int ret, char *receptacle)
{
    char **captures, **matches;

	if(!pcre_get_substring_list(arg, ovec, ret, (const char ***)&captures)) {
	    
	    matches = zarrdup(&captures[1]); /* first one would be entire string */
	    if (receptacle == NULL)
		setaparam("match", matches);
	    else
		setaparam(receptacle, matches);
	    
	    pcre_free_substring_list((const char **)captures);
	}

	return 0;
}
Exemplo n.º 2
0
static int
comp_wrapper(Eprog prog, FuncWrap w, char *name)
{
    if (incompfunc != 1)
	return 1;
    else {
	char *orest, *opre, *osuf, *oipre, *oisuf, **owords, **oredirs;
	char *oqipre, *oqisuf, *oq, *oqi, *oqs, *oaq;
	zlong ocur;
	unsigned int runset = 0, kunset = 0, m, sm;
	Param *pp;

	m = CP_WORDS | CP_REDIRS | CP_CURRENT | CP_PREFIX | CP_SUFFIX | 
	    CP_IPREFIX | CP_ISUFFIX | CP_QIPREFIX | CP_QISUFFIX;
	for (pp = comprpms, sm = 1; m; pp++, m >>= 1, sm <<= 1) {
	    if ((m & 1) && ((*pp)->node.flags & PM_UNSET))
		runset |= sm;
	}
	if (compkpms[CPN_RESTORE]->node.flags & PM_UNSET)
	    kunset = CP_RESTORE;
	orest = comprestore;
	comprestore = ztrdup("auto");
	ocur = compcurrent;
	opre = ztrdup(compprefix);
	osuf = ztrdup(compsuffix);
	oipre = ztrdup(compiprefix);
	oisuf = ztrdup(compisuffix);
	oqipre = ztrdup(compqiprefix);
	oqisuf = ztrdup(compqisuffix);
	oq = ztrdup(compquote);
	oqi = ztrdup(compquoting);
	oqs = ztrdup(compqstack);
	oaq = ztrdup(autoq);
	owords = zarrdup(compwords);
	oredirs = zarrdup(compredirs);

	runshfunc(prog, w, name);

	if (comprestore && !strcmp(comprestore, "auto")) {
	    compcurrent = ocur;
	    zsfree(compprefix);
	    compprefix = opre;
	    zsfree(compsuffix);
	    compsuffix = osuf;
	    zsfree(compiprefix);
	    compiprefix = oipre;
	    zsfree(compisuffix);
	    compisuffix = oisuf;
	    zsfree(compqiprefix);
	    compqiprefix = oqipre;
	    zsfree(compqisuffix);
	    compqisuffix = oqisuf;
	    zsfree(compquote);
	    compquote = oq;
	    zsfree(compquoting);
	    compquoting = oqi;
	    zsfree(compqstack);
	    compqstack = oqs;
	    zsfree(autoq);
	    autoq = oaq;
	    freearray(compwords);
	    freearray(compredirs);
	    compwords = owords;
            compredirs = oredirs;
	    comp_setunset(CP_COMPSTATE |
			  (~runset & (CP_WORDS | CP_REDIRS |
                                      CP_CURRENT | CP_PREFIX |
                                      CP_SUFFIX | CP_IPREFIX | CP_ISUFFIX |
                                      CP_QIPREFIX | CP_QISUFFIX)),
			  (runset & CP_ALLREALS),
			  (~kunset & CP_RESTORE), (kunset & CP_ALLKEYS));
	} else {
	    comp_setunset(CP_COMPSTATE, 0, (~kunset & CP_RESTORE),
			  (kunset & CP_RESTORE));
	    zsfree(opre);
	    zsfree(osuf);
	    zsfree(oipre);
	    zsfree(oisuf);
	    zsfree(oqipre);
	    zsfree(oqisuf);
	    zsfree(oq);
	    zsfree(oqi);
	    zsfree(oqs);
	    zsfree(oaq);
	    freearray(owords);
	    freearray(oredirs);
	}
	zsfree(comprestore);
	comprestore = orest;

	return 0;
    }
}
Exemplo n.º 3
0
static int
raw_getbyte(long do_keytmout, char *cptr)
{
    int ret;
    struct ztmout tmout;
#if defined(HAS_TIO) && \
  (defined(sun) || (!defined(HAVE_POLL) && !defined(HAVE_SELECT)))
    struct ttyinfo ti;
#endif
#ifndef HAVE_POLL
# ifdef HAVE_SELECT
    fd_set foofd;
# endif
#endif

    calc_timeout(&tmout, do_keytmout);

    /*
     * Handle timeouts and watched fd's.  If a watched fd or a function
     * timeout triggers we restart any key timeout.  This is likely to
     * be harmless: the combination is extremely rare and a function
     * is likely to occupy the user for a little while anyway.  We used
     * to make timeouts take precedence, but we can't now that the
     * timeouts may be external, so we may have both a permanent watched
     * fd and a long-term timeout.
     */
    if ((nwatch || tmout.tp != ZTM_NONE)
#ifdef FIONREAD
	&& ! delayzsetterm
#endif
	) {
#if defined(HAVE_SELECT) || defined(HAVE_POLL)
	int i, errtry = 0, selret;
# ifdef HAVE_POLL
	int nfds;
	struct pollfd *fds;
# endif
# if defined(HAS_TIO) && defined(sun)
	/*
	 * Yes, I know this is complicated.  Yes, I know we
	 * already have three bits of code to poll the terminal
	 * down below.  No, I don't want to do this either.
	 * However, it turns out on certain OSes, specifically
	 * Solaris, that you can't poll typeahead for love nor
	 * money without actually trying to read it.  But
	 * if we are trying to select (and we need to if we
	 * are watching other fd's) we won't pick that up.
	 * So we just try and read it without blocking in
	 * the time-honoured (i.e. absurdly baroque) termios
	 * fashion.
	 */
	gettyinfo(&ti);
	ti.tio.c_cc[VMIN] = 0;
	settyinfo(&ti);
	ret = read(SHTTY, cptr, 1);
	ti.tio.c_cc[VMIN] = 1;
	settyinfo(&ti);
	if (ret > 0)
	    return 1;
# endif
# ifdef HAVE_POLL
	nfds = 1 + nwatch;
	/* First pollfd is SHTTY, following are the nwatch fds */
	fds = zalloc(sizeof(struct pollfd) * nfds);
	fds[0].fd = SHTTY;
	/*
	 * POLLIN, POLLIN, POLLIN,
	 * Keep those fd's POLLIN...
	 */
	fds[0].events = POLLIN;
	for (i = 0; i < nwatch; i++) {
	    fds[i+1].fd = watch_fds[i];
	    fds[i+1].events = POLLIN;
	}
# endif
	for (;;) {
# ifdef HAVE_POLL
	    int poll_timeout;

	    if (tmout.tp != ZTM_NONE)
		poll_timeout = tmout.exp100ths * 10;
	    else
		poll_timeout = -1;

	    selret = poll(fds, errtry ? 1 : nfds, poll_timeout);
# else
	    int fdmax = SHTTY;
	    struct timeval *tvptr;
	    struct timeval expire_tv;

	    FD_ZERO(&foofd);
	    FD_SET(SHTTY, &foofd);
	    if (!errtry) {
		for (i = 0; i < nwatch; i++) {
		    int fd = watch_fds[i];
		    FD_SET(fd, &foofd);
		    if (fd > fdmax)
			fdmax = fd;
		}
	    }

	    if (tmout.tp != ZTM_NONE) {
		expire_tv.tv_sec = tmout.exp100ths / 100;
		expire_tv.tv_usec = (tmout.exp100ths % 100) * 10000L;
		tvptr = &expire_tv;
	    }
	    else
		tvptr = NULL;

	    selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
			    NULL, NULL, tvptr);
# endif
	    /*
	     * Make sure a user interrupt gets passed on straight away.
	     */
	    if (selret < 0 && errflag)
		break;
	    /*
	     * Try to avoid errors on our special fd's from
	     * messing up reads from the terminal.  Try first
	     * with all fds, then try unsetting the special ones.
	     */
	    if (selret < 0 && !errtry) {
		errtry = 1;
		continue;
	    }
	    if (selret == 0) {
		/*
		 * Nothing ready and no error, so we timed out.
		 */
		switch (tmout.tp) {
		case ZTM_NONE:
		    /* keeps compiler happy if not debugging */
#ifdef DEBUG
		    dputs("BUG: timeout fired with no timeout set.");
#endif
		    /* treat as if a key timeout triggered */
		    /*FALLTHROUGH*/
		case ZTM_KEY:
		    /* Special value -2 signals nothing ready */
		    selret = -2;
		    break;

		case ZTM_FUNC:
		    while (firstnode(timedfns)) {
			Timedfn tfdat = (Timedfn)getdata(firstnode(timedfns));
			/*
			 * It's possible a previous function took
			 * a long time to run (though it can't
			 * call zle recursively), so recalculate
			 * the time on each iteration.
			 */
			time_t now = time(NULL);
			if (tfdat->when > now)
			    break;
			tfdat->func();
		    }
		    /* Function may have messed up the display */
		    if (resetneeded)
			zrefresh();
		    /* We need to recalculate the timeout */
		    /*FALLTHROUGH*/
		case ZTM_MAX:
		    /*
		     * Reached the limit of our range, but not the
		     * actual timeout; recalculate the timeout.
		     * We're cheating with the key timeout here:
		     * if one clashed with a function timeout we
		     * reconsider the key timeout from scratch.
		     * The effect of this is microscopic.
		     */
		    calc_timeout(&tmout, do_keytmout);
		    break;
		}
		/*
		 * If we handled the timeout successfully,
		 * carry on.
		 */
		if (selret == 0)
		    continue;
	    }
	    /* If error or unhandled timeout, give up. */
	    if (selret < 0)
		break;
	    /*
	     * If there's user input handle it straight away.
	     * This improves the user's ability to handle exceptional
	     * conditions like runaway output.
	     */
	    if (
# ifdef HAVE_POLL
		 (fds[0].revents & POLLIN)
# else
		 FD_ISSET(SHTTY, &foofd)
# endif
		 )
		break;
	    if (nwatch && !errtry) {
		/*
		 * Copy the details of the watch fds in case the
		 * user decides to delete one from inside the
		 * handler function.
		 */
		int lnwatch = nwatch;
		int *lwatch_fds = zalloc(lnwatch*sizeof(int));
		char **lwatch_funcs = zarrdup(watch_funcs);
		memcpy(lwatch_fds, watch_fds, lnwatch*sizeof(int));
		for (i = 0; i < lnwatch; i++) {
		    if (
# ifdef HAVE_POLL
			(fds[i+1].revents & POLLIN)
# else
			FD_ISSET(lwatch_fds[i], &foofd)
# endif
			) {
			/* Handle the fd. */
			LinkList funcargs = znewlinklist();
			zaddlinknode(funcargs, ztrdup(lwatch_funcs[i]));
			{
			    char buf[BDIGBUFSIZE];
			    convbase(buf, lwatch_fds[i], 10);
			    zaddlinknode(funcargs, ztrdup(buf));
			}
# ifdef HAVE_POLL
#  ifdef POLLERR
			if (fds[i+1].revents & POLLERR)
			    zaddlinknode(funcargs, ztrdup("err"));
#  endif
#  ifdef POLLHUP
			if (fds[i+1].revents & POLLHUP)
			    zaddlinknode(funcargs, ztrdup("hup"));
#  endif
#  ifdef POLLNVAL
			if (fds[i+1].revents & POLLNVAL)
			    zaddlinknode(funcargs, ztrdup("nval"));
#  endif
# endif


			callhookfunc(lwatch_funcs[i], funcargs, 0, NULL);
			if (errflag) {
			    /* No sensible way of handling errors here */
			    errflag = 0;
			    /*
			     * Paranoia: don't run the hooks again this
			     * time.
			     */
			    errtry = 1;
			}
			freelinklist(funcargs, freestr);
		    }
		}
		/* Function may have invalidated the display. */
		if (resetneeded)
		    zrefresh();
		zfree(lwatch_fds, lnwatch*sizeof(int));
		freearray(lwatch_funcs);
	    }
	}
# ifdef HAVE_POLL
	zfree(fds, sizeof(struct pollfd) * nfds);
# endif
	if (selret < 0)
	    return selret;
#else
# ifdef HAS_TIO
	ti = shttyinfo;
	ti.tio.c_lflag &= ~ICANON;
	ti.tio.c_cc[VMIN] = 0;
	ti.tio.c_cc[VTIME] = tmout.exp100ths / 10;
#  ifdef HAVE_TERMIOS_H
	tcsetattr(SHTTY, TCSANOW, &ti.tio);
#  else
	ioctl(SHTTY, TCSETA, &ti.tio);
#  endif
	ret = read(SHTTY, cptr, 1);
#  ifdef HAVE_TERMIOS_H
	tcsetattr(SHTTY, TCSANOW, &shttyinfo.tio);
#  else
	ioctl(SHTTY, TCSETA, &shttyinfo.tio);
#  endif
	return (ret <= 0) ? ret : *cptr;
# endif
#endif
    }

    ret = read(SHTTY, cptr, 1);

    return ret;
}
Exemplo n.º 4
0
Arquivo: pcre.c Projeto: Jaharmi/zsh
static int
zpcre_get_substrings(char *arg, int *ovec, int ret, char *matchvar,
		     char *substravar, int want_offset_pair, int matchedinarr,
		     int want_begin_end)
{
    char **captures, *match_all, **matches;
    char offset_all[50];
    int capture_start = 1;

    if (matchedinarr)
	capture_start = 0;
    if (matchvar == NULL)
	matchvar = "MATCH";
    if (substravar == NULL)
	substravar = "match";
    
    /* captures[0] will be entire matched string, [1] first substring */
    if (!pcre_get_substring_list(arg, ovec, ret, (const char ***)&captures)) {
	int nelem = arrlen(captures)-1;
	/* Set to the offsets of the complete match */
	if (want_offset_pair) {
	    sprintf(offset_all, "%d %d", ovec[0], ovec[1]);
	    setsparam("ZPCRE_OP", ztrdup(offset_all));
	}
	match_all = ztrdup(captures[0]);
	setsparam(matchvar, match_all);
	/*
	 * If we're setting match, mbegin, mend we only do
	 * so if there were parenthesised matches, for consistency
	 * (c.f. regex.c).
	 */
	if (!want_begin_end || nelem) {
	    matches = zarrdup(&captures[capture_start]);
	    setaparam(substravar, matches);
	}

	if (want_begin_end) {
	    char *ptr = arg;
	    zlong offs = 0;

	    /* Count the characters before the match */
	    MB_METACHARINIT();
	    while (ptr < arg + ovec[0]) {
		offs++;
		ptr += MB_METACHARLEN(ptr);
	    }
	    setiparam("MBEGIN", offs + !isset(KSHARRAYS));
	    /* Add on the characters in the match */
	    while (ptr < arg + ovec[1]) {
		offs++;
		ptr += MB_METACHARLEN(ptr);
	    }
	    setiparam("MEND", offs + !isset(KSHARRAYS) - 1);
	    if (nelem) {
		char **mbegin, **mend, **bptr, **eptr;
		int i, *ipair;

		bptr = mbegin = zalloc(sizeof(char*)*(nelem+1));
		eptr = mend = zalloc(sizeof(char*)*(nelem+1));

		for (ipair = ovec + 2, i = 0;
		     i < nelem;
		     ipair += 2, i++, bptr++, eptr++)
		{
		    char buf[DIGBUFSIZE];
		    ptr = arg;
		    offs = 0;
		    /* Find the start offset */
		    MB_METACHARINIT();
		    while (ptr < arg + ipair[0]) {
			offs++;
			ptr += MB_METACHARLEN(ptr);
		    }
		    convbase(buf, offs + !isset(KSHARRAYS), 10);
		    *bptr = ztrdup(buf);
		    /* Continue to the end offset */
		    while (ptr < arg + ipair[1]) {
			offs++;
			ptr += MB_METACHARLEN(ptr);
		    }
		    convbase(buf, offs + !isset(KSHARRAYS) - 1, 10);
		    *eptr = ztrdup(buf);
		}
		*bptr = *eptr = NULL;

		setaparam("mbegin", mbegin);
		setaparam("mend", mend);
	    }
	}

	pcre_free_substring_list((const char **)captures);
    }

    return 0;
}
Exemplo n.º 5
0
Arquivo: zpty.c Projeto: zsh-users/zsh
static int
newptycmd(char *nam, char *pname, char **args, int echo, int nblock)
{
    Ptycmd p;
    int master, slave, pid, oineval = ineval, ret;
    char *oscriptname = scriptname, syncch;
    Eprog prog;

    /* code borrowed from bin_eval() */
    ineval = !isset(EVALLINENO);
    if (!ineval)
	scriptname = "(zpty)";

    prog = parse_string(zjoin(args, ' ', 1), 0);
    if (!prog) {
	errflag &= ~ERRFLAG_ERROR;
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }

    if (get_pty(1, &master)) {
	zwarnnam(nam, "can't open pseudo terminal: %e", errno);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }
    if ((pid = fork()) == -1) {
	zwarnnam(nam, "can't create pty command %s: %e", pname, errno);
	close(master);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    } else if (!pid) {
	/* This code copied from the clone module, except for getting *
	 * the descriptor from get_pty() and duplicating it to 0/1/2. */

	deletehookfunc("exit", ptyhook);
	clearjobtab(0);
	ppid = getppid();
	mypid = getpid();
#ifdef HAVE_SETSID
	if (setsid() != mypid) {
	    zwarnnam(nam, "failed to create new session: %e", errno);
#endif
#ifdef TIOCNOTTY
	    if (ioctl(SHTTY, TIOCNOTTY, 0))
		zwarnnam(nam, "%e", errno);
	    setpgrp(0L, mypid);
#endif
#ifdef HAVE_SETSID
	}
#endif

	if (get_pty(0, &slave))
	    exit(1);
	SHTTY = slave;
	attachtty(mypid);
#ifdef TIOCGWINSZ
	/* Set the window size before associating with the terminal *
	 * so that we don't get hit with a SIGWINCH.  I'm paranoid. */
	if (interact) {
	    struct ttyinfo info;

	    if (ioctl(slave, TIOCGWINSZ, (char *) &info.winsize) == 0) {
		info.winsize.ws_row = zterm_lines;
		info.winsize.ws_col = zterm_columns;
		ioctl(slave, TIOCSWINSZ, (char *) &info.winsize);
	    }
	}
#endif /* TIOCGWINSZ */

	if (!echo) {
	    struct ttyinfo info;

	    if (!ptygettyinfo(slave, &info)) {
#ifdef HAVE_TERMIOS_H
		info.tio.c_lflag &= ~ECHO;
#else
#ifdef HAVE_TERMIO_H
		info.tio.c_lflag &= ~ECHO;
#else
		info.tio.lmodes &= ~ECHO; /**** dunno if this is right */
#endif
#endif
		ptysettyinfo(slave, &info);
	    }
	}

#ifdef TIOCSCTTY
	ioctl(slave, TIOCSCTTY, 0);
#endif

	close(0);
	close(1);
	close(2);

	dup2(slave, 0);
	dup2(slave, 1);
	dup2(slave, 2);

	closem(FDT_UNUSED, 0);
	close(slave);
	close(master);
	close(coprocin);
	close(coprocout);
	init_io(NULL);
	setsparam("TTY", ztrdup(ttystrname));

	opts[INTERACTIVE] = 0;

	syncch = 0;
	do {
	    ret = write(1, &syncch, 1);
	} while (ret != 1 && (
#ifdef EWOULDBLOCK
	    errno == EWOULDBLOCK ||
#else
#ifdef EAGAIN
	    errno == EAGAIN ||
#endif
#endif
	    errno == EINTR));

	execode(prog, 1, 0, "zpty");
	stopmsg = 2;
	mypid = 0; /* trick to ensure we _exit() */
	zexit(lastval, 0);
    }
    master = movefd(master);
    if (master == -1) {
	zerrnam(nam, "cannot duplicate fd %d: %e", master, errno);
	scriptname = oscriptname;
	ineval = oineval;
	return 1;
    }

    p = (Ptycmd) zalloc(sizeof(*p));

    p->name = ztrdup(pname);
    p->args = zarrdup(args);
    p->fd = master;
    p->pid = pid;
    p->echo = echo;
    p->nblock = nblock;
    p->fin = 0;
    p->read = -1;
    p->old = NULL;
    p->olen = 0;

    p->next = ptycmds;
    ptycmds = p;

    if (nblock)
	ptynonblock(master);

    scriptname = oscriptname;
    ineval = oineval;

    do {
	ret = read(master, &syncch, 1);
    } while (ret != 1 && (
#ifdef EWOULDBLOCK
	    errno == EWOULDBLOCK ||
#else
#ifdef EAGAIN
	    errno == EAGAIN ||
#endif
#endif
	    errno == EINTR));

    setiparam_no_convert("REPLY", (zlong)master);

    return 0;
}