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); } }
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); }
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); }
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; }
/* 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; }
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); } } }