Пример #1
0
void setbacktick(int num, int lifespan, int tick, char **cmdv)
{
	struct backtick **btp, *bt;
	char **v;

	for (btp = &backticks; (bt = *btp) != 0; btp = &bt->next)
		if (bt->num == num)
			break;
	if (!bt && !cmdv)
		return;
	if (bt) {
		for (v = bt->cmdv; *v; v++)
			free(*v);
		free(bt->cmdv);
		if (bt->buf)
			free(bt->buf);
		if (bt->ev.fd >= 0)
			close(bt->ev.fd);
		evdeq(&bt->ev);
	}
	if (bt && !cmdv) {
		*btp = bt->next;
		free(bt);
		return;
	}
	if (!bt) {
		bt = malloc(sizeof *bt);
		if (!bt) {
			Msg(0, "%s", strnomem);
			return;
		}
		memset(bt, 0, sizeof(*bt));
		bt->next = 0;
		*btp = bt;
	}
	bt->num = num;
	bt->tick = tick;
	bt->lifespan = lifespan;
	bt->bestbefore = 0;
	bt->result[0] = 0;
	bt->buf = 0;
	bt->bufi = 0;
	bt->cmdv = cmdv;
	bt->ev.fd = -1;
	if (bt->tick == 0 && bt->lifespan == 0) {
		bt->buf = malloc(MAXSTR);
		if (bt->buf == 0) {
			Msg(0, "%s", strnomem);
			setbacktick(num, 0, 0, (char **)0);
			return;
		}
		bt->ev.type = EV_READ;
		bt->ev.fd = readpipe(bt->cmdv);
		bt->ev.handler = backtick_fn;
		bt->ev.data = (char *)bt;
		if (bt->ev.fd >= 0)
			evenq(&bt->ev);
	}
}
Пример #2
0
Файл: mark.c Проект: meh/screen
void FreePaster(struct paster *pa)
{
	if (pa->pa_pastebuf)
		free(pa->pa_pastebuf);
	pa->pa_pastebuf = 0;
	pa->pa_pasteptr = 0;
	pa->pa_pastelen = 0;
	pa->pa_pastelayer = 0;
	evdeq(&pa->pa_slowev);
}
Пример #3
0
void FreeCanvas(struct canvas *cv)
{
	struct viewport *vp, *nvp;
	struct canvas **cvp;
	struct win *p;

	if (cv->c_slprev)
		cv->c_slprev->c_slnext = cv->c_slnext;
	if (cv->c_slnext)
		cv->c_slnext->c_slprev = cv->c_slprev;
	if (cv->c_slback && cv->c_slback->c_slperp == cv)
		cv->c_slback->c_slperp = cv->c_slnext ? cv->c_slnext : cv->c_slprev;
	if (cv->c_slperp) {
		while (cv->c_slperp)
			FreeCanvas(cv->c_slperp);
		LayerCleanupMemory(&cv->c_blank);
		free(cv);
		return;
	}

	if (display) {
		if (D_forecv == cv)
			D_forecv = 0;
		/* remove from canvas chain as SetCanvasWindow might call
		 * some layer function */
		for (cvp = &D_cvlist; *cvp; cvp = &(*cvp)->c_next)
			if (*cvp == cv) {
				*cvp = cv->c_next;
				break;
			}
	}
	p = cv->c_layer ? Layer2Window(cv->c_layer) : 0;
	SetCanvasWindow(cv, 0);
	if (p)
		WindowChanged(p, 'u');
	if (flayer == cv->c_layer)
		flayer = 0;
	for (vp = cv->c_vplist; vp; vp = nvp) {
		vp->v_canvas = 0;
		nvp = vp->v_next;
		vp->v_next = 0;
		free(vp);
	}
	evdeq(&cv->c_captev);
	LayerCleanupMemory(&cv->c_blank);
	free(cv);
}
Пример #4
0
static void backtick_fn(Event *ev, void *data)
{
	struct backtick *bt;
	int i, j, k, l;

	bt = (struct backtick *)data;
	i = bt->bufi;
	l = read(ev->fd, bt->buf + i, MAXSTR - i);
	if (l <= 0) {
		evdeq(ev);
		close(ev->fd);
		ev->fd = -1;
		return;
	}
	i += l;
	for (j = 0; j < l; j++)
		if (bt->buf[i - j - 1] == '\n')
			break;
	if (j < l) {
		for (k = i - j - 2; k >= 0; k--)
			if (bt->buf[k] == '\n')
				break;
		k++;
		memmove(bt->result, bt->buf + k, i - j - k);
		bt->result[i - j - k - 1] = 0;
		backtick_filter(bt);
		WindowChanged(0, '`');
	}
	if (j == l && i == MAXSTR) {
		j = MAXSTR / 2;
		l = j + 1;
	}
	if (j < l) {
		if (j)
			memmove(bt->buf, bt->buf + i - j, j);
		i = j;
	}
	bt->bufi = i;
}
Пример #5
0
/* TODO: const char *str for safety and reassurance */
char *MakeWinMsgEv(WinMsgBuf *winmsg, char *str, Window *win,
                   int chesc, int padlen, Event *ev, int rec)
{
	static int tick;
	char *s = str;
	struct timeval now;
	int qmnumrend = 0;
	int numpad = 0;
	int lastpad = 0;
	WinMsgBufContext *wmbc;
	WinMsgEsc esc;
	WinMsgCond *cond = alloca(sizeof(WinMsgCond));

	/* TODO: temporary to work into existing code */
	if (winmsg == NULL) {
		if (g_winmsg == NULL) {
			if ((g_winmsg = wmb_create()) == NULL)
				Panic(0, "%s", strnomem);
		}
		winmsg = g_winmsg;
	}

	if (cond == NULL)
		Panic(0, "%s", strnomem);

	if (rec > WINMSG_RECLIMIT)
		return winmsg->buf;

	/* set to sane state (clear garbage) */
	wmc_deinit(cond);

	/* TODO: we can get rid of this once winmsg is properly handled by caller */
	if (winmsg->numrend > 0)
		winmsg->numrend = 0;

	wmb_reset(winmsg);
	wmbc = wmbc_create(winmsg);

	if (wmbc == NULL)
		Panic(0, "%s", strnomem);

	tick = 0;
	gettimeofday(&now, NULL);
	for (s = str; *s; s++) {
		if (*s != chesc) {
			if ((chesc == '%') && (*s == '^')) {
				s++;
				if (*s != '^' && *s >= 64)
					wmbc_putchar(wmbc, *s & 0x1f);
				continue;
			}
			wmbc_putchar(wmbc, *s);
			continue;
		}

		if (*++s == chesc)	/* double escape ? */
			continue;

		/* initialize escape */
		if ((esc.flags.plus = (*s == '+')) != 0)
			s++;
		if ((esc.flags.minus = (*s == '-')) != 0)
			s++;
		if ((esc.flags.zero = (*s == '0')) != 0)
			s++;
		esc.num = 0;
		while (*s >= '0' && *s <= '9')
			esc.num = esc.num * 10 + (*s++ - '0');
		if ((esc.flags.lng = (*s == 'L')) != 0)
			s++;

		switch (*s) {
		case WINESC_COND:
			WinMsgDoEscEx(Cond, &qmnumrend);
			break;
		case WINESC_COND_ELSE:
			WinMsgDoEscEx(CondElse, &qmnumrend);
			break;
		case WINESC_HSTATUS:
			WinMsgDoEscEx(Hstatus, win, &tick, rec);
			break;
		case WINESC_BACKTICK:
			WinMsgDoEscEx(Backtick, esc.num, win, &tick, &now, rec);
			break;
		case WINESC_CMD:
		case WINESC_CMD_ARGS:
			WinMsgDoEscEx(WinArgv, win);
			break;
		case WINESC_WIN_NAMES:
		case WINESC_WIN_NAMES_NOCUR:
			WinMsgDoEscEx(WinNames, (*s == WINESC_WIN_NAMES_NOCUR), win);
			break;
		case WINESC_WFLAGS:
			WinMsgDoEscEx(Wflags, win);
			break;
		case WINESC_WIN_TITLE:
			WinMsgDoEscEx(WinTitle, win);
			break;
		case WINESC_REND_START:
			WinMsgDoEsc(Rend);
			break;
		case WINESC_HOST:
			WinMsgDoEsc(HostName);
			break;
		case WINESC_SESS_NAME:
			WinMsgDoEsc(SessName);
			break;
		case WINESC_PID:
			WinMsgDoEsc(Pid);
			break;
		case WINESC_FOCUS:
			WinMsgDoEscEx(Focus, win, ev);
			break;
		case WINESC_COPY_MODE:
			WinMsgDoEscEx(CopyMode, ev);
			break;
		case WINESC_ESC_SEEN:
			WinMsgDoEsc(EscSeen);
			break;
		case WINESC_TRUNC_POS:
			WinMsgDoEscEx(TruncPos,
				((esc.num > 100) ? 100 : esc.num),
				esc.flags.lng);
			break;
		case WINESC_PAD:
		case WINESC_TRUNC:
			WinMsgDoEscEx(PadOrTrunc, &numpad, &lastpad, padlen);
			break;
		case WINESC_WIN_SIZE:
			WinMsgDoEscEx(WinSize, win);
			break;
		case WINESC_WIN_NUM:
			WinMsgDoEscEx(WinNum, win);
			break;
		case WINESC_WIN_LOGNAME:
			WinMsgDoEscEx(WinLogName, win);
			break;
		}
	}
	if (wmc_is_active(cond) && !wmc_is_set(cond))
		wmbc->p = wmc_end(cond, wmbc->p, NULL) + 1;
	wmbc_putchar(wmbc, '\0' );
	wmbc->p--; /* TODO: temporary to work with old code */
	if (numpad) {
		if (padlen > MAXSTR - 1)
			padlen = MAXSTR - 1;
		pad_expand(winmsg, winmsg->buf, wmbc->p, numpad, padlen);
	}
	if (ev) {
		evdeq(ev);	/* just in case */
		ev->timeout.tv_sec = 0;
		ev->timeout.tv_usec = 0;
	}
	if (ev && tick) {
		now.tv_usec = 100000;
		if (tick == 1)
			now.tv_sec++;
		else
			now.tv_sec += tick - (now.tv_sec % tick);
		ev->timeout = now;
	}

	wmbc_free(wmbc);
	return winmsg->buf;
}
Пример #6
0
void
sched()
{
  struct event *ev;
  fd_set r, w, *set;
  struct event *timeoutev = 0;
  struct timeval timeout;
  int nsel;

  for (;;)
    {
      if (calctimeout)
	timeoutev = calctimo();
      if (timeoutev)
	{
	  gettimeofday(&timeout, NULL);
	  /* tp - timeout */
	  timeout.tv_sec = timeoutev->timeout.tv_sec - timeout.tv_sec;
	  timeout.tv_usec = timeoutev->timeout.tv_usec - timeout.tv_usec;
	  if (timeout.tv_usec < 0)
	    {
	      timeout.tv_usec += 1000000;
	      timeout.tv_sec--;
	    }
	  if (timeout.tv_sec < 0)
	    {
	      timeout.tv_usec = 0;
	      timeout.tv_sec = 0;
	    }
	}
#ifdef DEBUG
      debug("waiting for events");
      if (timeoutev)
        debug2(" timeout %d secs %d usecs", timeout.tv_sec, timeout.tv_usec);
      debug(":\n");
      for (ev = evs; ev; ev = ev->next)
        debug3(" - fd %d type %d pri %d\n", ev->fd, ev->type, ev->pri);
      if (tevs)
        debug("timed events:\n");
      for (ev = tevs; ev; ev = ev->next)
        debug3(" - pri %d sec %d usec %d\n", ev->pri, ev->timeout.tv_sec, ev->timeout.tv_usec);
#endif

      FD_ZERO(&r);
      FD_ZERO(&w);
      for (ev = evs; ev; ev = ev->next)
        {
	  if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0))
	    {
	      debug2(" - cond ev fd %d type %d failed\n", ev->fd, ev->type);
	      continue;
	    }
	  if (ev->type == EV_READ)
	    FD_SET(ev->fd, &r);
	  else if (ev->type == EV_WRITE)
	    FD_SET(ev->fd, &w);
        }

#ifdef DEBUG
      debug("readfds:");
      for (nsel = 0; nsel < FD_SETSIZE; nsel++)
	if (FD_ISSET(nsel, &r))
	  debug1(" %d", nsel);
      debug("\n");
      debug("writefds:");
      for (nsel = 0; nsel < FD_SETSIZE; nsel++)
	if (FD_ISSET(nsel, &w))
	  debug1(" %d", nsel);
      debug("\n");
#endif

      nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, timeoutev ? &timeout : (struct timeval *) 0);
      if (nsel < 0)
	{
	  if (errno != EINTR)
	    {
#if defined(sgi) && defined(SVR4)
	      if (errno == EIO && sgihack())
		continue;
#endif
#if defined(__osf__) || defined(M_UNIX)
	      /* OSF/1 3.x, SCO bug: EBADF */
	      /* OSF/1 4.x bug: EIO */
	      if ((errno == EIO || errno == EBADF) && sgihack())
		continue;
#endif
	      Panic(errno, "select");
	    }
	  nsel = 0;
	}
      else if (nsel == 0)	/* timeout */
	{
	  debug("TIMEOUT!\n");
	  ASSERT(timeoutev);
	  evdeq(timeoutev);
	  timeoutev->handler(timeoutev, timeoutev->data);
	}
#ifdef SELECT_BROKEN
      /*
       * Sequents select emulation counts a descriptor which is
       * readable and writeable only as one hit. Waaaaa.
       */
      if (nsel)
        nsel = 2 * FD_SETSIZE;
#endif

      for (ev = evs; ev; ev = nextev)
        {
          nextev = ev->next;
	  if (ev->type != EV_ALWAYS)
	    {
	      set = ev->type == EV_READ ? &r : &w;
	      if (nsel == 0 || !FD_ISSET(ev->fd, set))
		continue;
	      nsel--;
	    }
	  if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0))
	    continue;
	  debug2(" + hit ev fd %d type %d!\n", ev->fd, ev->type);
	  ev->handler(ev, ev->data);
        }
    }
}