示例#1
0
void
control_close(int fd, struct control_sock *cs)
{
	struct ctl_conn	*c;

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("control_close: fd %d: not found", fd);
		return;
	}

	msgbuf_clear(&c->iev.ibuf.w);
	TAILQ_REMOVE(&ctl_conns, c, entry);

	event_del(&c->iev.ev);
	close(c->iev.ibuf.fd);

	/* Some file descriptors are available again. */
	if (evtimer_pending(&cs->cs_evt, NULL)) {
		evtimer_del(&cs->cs_evt);
		event_add(&cs->cs_ev, NULL);
	}
	npppd_ctl_destroy(c->ctx);

	free(c);
}
示例#2
0
void
control_close(struct ctl_conn *c, const char *msg, struct imsg *imsg)
{
	struct control_sock *cs = c->cs;

	if (imsg) {
		log_debug("%s: fd %d: %s, imsg %d datalen %zu", __func__,
		    c->iev.ibuf.fd, msg, imsg->hdr.type, IMSG_DATA_SIZE(imsg));
		imsg_free(imsg);
	} else
		log_debug("%s: fd %d: %s", __func__, c->iev.ibuf.fd, msg);

	msgbuf_clear(&c->iev.ibuf.w);
	TAILQ_REMOVE(&ctl_conns, c, entry);

	event_del(&c->iev.ev);
	close(c->iev.ibuf.fd);

	/* Some file descriptors are available again. */
	if (evtimer_pending(&cs->cs_evt, NULL)) {
		evtimer_del(&cs->cs_evt);
		event_add(&cs->cs_ev, NULL);
	}

	free(c);
}
示例#3
0
    void event_callback(int _socket, short _kind, void* _connection_ptr)
    {
        const auto connection = static_cast<curl_handler::connection_context*>(_connection_ptr);
        const auto handler = connection->curl_handler_;

        const auto tv = curl_handler::make_timeval(connection->timeout_);
        event_del(connection->timeout_event_);
        event_add(connection->timeout_event_, &tv);

        int action = 0;
        if (_kind & EV_READ)
            action |= CURL_CSELECT_IN;
        if (_kind & EV_WRITE)
            action |= CURL_CSELECT_OUT;

        const auto error = curl_multi_socket_action(handler->multi_handle_, _socket, action, &handler->running_);
        assert(!error);
        (void*) error; // supress warning

        check_multi_info(handler);

        if (handler->running_ <= 0)
        {
            if (evtimer_pending(handler->timer_event_, NULL))
                evtimer_del(handler->timer_event_);
        }
    }
示例#4
0
文件: web.c 项目: fangang190/canary
static void
stop_timer( tr_web* g )
{
    if( evtimer_pending( &g->timer_event, NULL ) )
    {
        dbgmsg( "deleting the pending global timer" );
        evtimer_del( &g->timer_event );
    }
}
示例#5
0
static void udp_retry_later(struct event_base *base) {
    static struct event *retry_timer = NULL;
    struct timeval delay_tv = {SERVER_RECONNECT_INTERVAL_SEC, 0};
    if (!retry_timer) {
        retry_timer = evtimer_new(base, udp_init, base);
    }
    if (!evtimer_pending(retry_timer, &delay_tv)) {
        evtimer_add(retry_timer, &delay_tv);
    }
}
示例#6
0
void
if_del(struct iface *iface)
{
	log_debug("if_del: interface %s", iface->name);

	if (evtimer_pending(&iface->hello_timer, NULL))
		evtimer_del(&iface->hello_timer);

	free(iface);
}
示例#7
0
static void
cert_reschedule_query_after_success(ProxyContext * const proxy_context)
{
    if (evtimer_pending(proxy_context->cert_updater.cert_timer, NULL)) {
        return;
    }
    cert_reschedule_query(proxy_context, (time_t)
                          CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_MIN_DELAY
                          + (time_t) randombytes_uniform
                          (CERT_QUERY_RETRY_DELAY_AFTER_SUCCESS_JITTER));
}
示例#8
0
void
ct_set_keepalive_timeout(struct ct_event_state *ev_st, int delay)
{
	struct timeval tv;

	if (evtimer_pending(ev_st->keepalive_ev, NULL))
		evtimer_del(ev_st->keepalive_ev);
	bzero(&tv, sizeof(tv));
	tv.tv_sec = delay;
	evtimer_add(ev_st->keepalive_ev, &tv);
}
示例#9
0
文件: names.c 项目: mosconi/openbsd
void
check_window_name(struct window *w)
{
	struct timeval	 tv, next;
	char		*name;
	int		 left;

	if (w->active == NULL)
		return;

	if (!options_get_number(w->options, "automatic-rename"))
		return;

	if (~w->active->flags & PANE_CHANGED) {
		log_debug("@%u active pane not changed", w->id);
		return;
	}
	log_debug("@%u active pane changed", w->id);

	gettimeofday(&tv, NULL);
	left = name_time_expired(w, &tv);
	if (left != 0) {
		if (!event_initialized(&w->name_event))
			evtimer_set(&w->name_event, name_time_callback, w);
		if (!evtimer_pending(&w->name_event, NULL)) {
			log_debug("@%u name timer queued (%d left)", w->id,
			    left);
			timerclear(&next);
			next.tv_usec = left;
			event_add(&w->name_event, &next);
		} else {
			log_debug("@%u name timer already queued (%d left)",
			    w->id, left);
		}
		return;
	}
	memcpy(&w->name_time, &tv, sizeof w->name_time);
	if (event_initialized(&w->name_event))
		evtimer_del(&w->name_event);

	w->active->flags &= ~PANE_CHANGED;

	name = format_window_name(w);
	if (strcmp(name, w->name) != 0) {
		log_debug("@%u new name %s (was %s)", w->id, name, w->name);
		window_set_name(w, name);
		server_status_window(w);
	} else
		log_debug("@%u name not changed (still %s)", w->id, w->name);

	free(name);
}
示例#10
0
static void
cert_reschedule_query(ProxyContext * const proxy_context,
                      const time_t query_retry_delay)
{
    CertUpdater *cert_updater = &proxy_context->cert_updater;

    if (evtimer_pending(cert_updater->cert_timer, NULL)) {
        return;
    }
    const struct timeval tv = { .tv_sec = query_retry_delay, .tv_usec = 0 };
    evtimer_add(cert_updater->cert_timer, &tv);
}

static void
cert_reschedule_query_after_failure(ProxyContext * const proxy_context)
{
    CertUpdater *cert_updater = &proxy_context->cert_updater;
    time_t       query_retry_delay;

    if (evtimer_pending(cert_updater->cert_timer, NULL)) {
        return;
    }
    query_retry_delay = (time_t)
        (CERT_QUERY_RETRY_MIN_DELAY +
            (time_t) cert_updater->query_retry_step *
            (CERT_QUERY_RETRY_MAX_DELAY - CERT_QUERY_RETRY_MIN_DELAY) /
            CERT_QUERY_RETRY_STEPS);
    if (cert_updater->query_retry_step < CERT_QUERY_RETRY_STEPS) {
        cert_updater->query_retry_step++;
    }
    cert_reschedule_query(proxy_context, query_retry_delay);
    DNSCRYPT_PROXY_CERTS_UPDATE_RETRY();
    if (proxy_context->test_only != 0 &&
        cert_updater->query_retry_step > CERT_QUERY_TEST_RETRY_STEPS) {
        exit(DNSCRYPT_EXIT_CERT_TIMEOUT);
    }
}
示例#11
0
static void
http_engine_check_activity(int fd, short kind, void *userp)
{
    int i, error = 0;

    if (!g_http_engine->workers_running) {
        if (evtimer_pending(g_http_engine->activity_timer_event, NULL)) {
            evtimer_del(g_http_engine->activity_timer_event);
        }
        return;
    }

    for (i = 0; i < g_http_engine->total_workers; i++) {
        if (g_http_engine->workers[i].worker) {
            error |= pthread_tryjoin_np(g_http_engine->workers[i].worker, NULL);
        }
    }

    if (!error) {
        /* Workers are done */

        pthread_mutex_lock(&g_http_engine->lock);
        g_http_engine->workers_running = 0;
        pthread_mutex_unlock(&g_http_engine->lock);

        if (evtimer_pending(g_http_engine->activity_timer_event, NULL)) {
            evtimer_del(g_http_engine->activity_timer_event);
        }

        zlog_info(log_get_cat_http(), "Http workers terminated normally");
        http_process_test_completed();
        return;
    }

    http_engine_activity_timer_update();
}
示例#12
0
// called by libevent when we get a socket event
static void _curl_event_cb(int fd, short events, void *arg)
{
    _bosh_conn_ctx conn_ctx = arg;

    PUSH_CONN_NDC;
    JW_LOG_TRACE_FUNCTION_NO_ARGS;

    assert(conn_ctx);
    // map libevent constants to curl constants
    int action = (events & EV_READ  ? CURL_CSELECT_IN  : 0) |
                 (events & EV_WRITE ? CURL_CSELECT_OUT : 0);

    jw_err    err;
    CURLMcode rc = curl_multi_socket_action(
            conn_ctx->multi, fd, action, &conn_ctx->num_active);
    if (!_check_curl_mcode(rc, &err))
    {
        goto _curl_event_cb_fail_label;
    }

    if (!_check_multi_info(conn_ctx, &err))
    {
        goto _curl_event_cb_fail_label;
    }

    if (0 >= conn_ctx->num_active
     && 0 != evtimer_pending(conn_ctx->timeout_ev, NULL))
    {
        jw_log(JW_LOG_DEBUG, "no more pending transfers; killing curl timeout");
        if (0 != evtimer_del(conn_ctx->timeout_ev))
        {
            jw_log(JW_LOG_WARN, "failed to remove curl event timer");
            JABBERWERX_ERROR(&err, JW_ERR_INVALID_STATE);
            goto _curl_event_cb_fail_label;
        }
    }

    goto _curl_event_cb_done_label;

_curl_event_cb_fail_label:
    conn_ctx->error_cb(err.code, conn_ctx->cb_arg);
_curl_event_cb_done_label:
    POP_CONN_NDC;
}
示例#13
0
/* Called by libevent when we get action on a multi socket */
static void event_cb(int fd, short kind, void *userp)
{
  GlobalInfo *g = (GlobalInfo*) userp;
  CURLMcode rc;

  int action =
    (kind & EV_READ ? CURL_CSELECT_IN : 0) |
    (kind & EV_WRITE ? CURL_CSELECT_OUT : 0);

  rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
  mcode_or_die("event_cb: curl_multi_socket_action", rc);

  check_multi_info(g);
  if ( g->still_running <= 0 ) {
    fprintf(MSG_OUT, "last transfer done, kill timeout\n");
    if (evtimer_pending(g->timer_event, NULL)) {
      evtimer_del(g->timer_event);
    }
  }
}
示例#14
0
static evhtp_res
pause_cb(evhtp_request_t * request, evhtp_header_t * header, void * arg) {
    struct pauser * pause = (struct pauser *)arg;
    int             s     = rand() % 1000000;

    printf("pause_cb(%p) pause == %p, timer_ev = %p\n",
           request->conn, pause, pause->timer_ev);
    printf("pause_cb(%p) k=%s, v=%s timer_ev = %p\n", request->conn,
           header->key, header->val, pause->timer_ev);
    printf("pause_cb(%p) setting to %ld usec sleep timer_ev = %p\n",
           request->conn, (long int)s, pause->timer_ev);

    pause->tv->tv_sec  = 0;
    pause->tv->tv_usec = s;

    if (evtimer_pending(pause->timer_ev, NULL)) {
        evtimer_del(pause->timer_ev);
    }

    evtimer_add(pause->timer_ev, pause->tv);

    return EVHTP_RES_PAUSE;
}
示例#15
0
struct ctl_iface *
if_to_ctl(struct iface *iface)
{
	static struct ctl_iface	 ictl;
	struct timeval		 tv, now, res;

	memcpy(ictl.name, iface->name, sizeof(ictl.name));
	memcpy(&ictl.addr, &iface->addr, sizeof(ictl.addr));
	memcpy(&ictl.mask, &iface->mask, sizeof(ictl.mask));
	ictl.rtr_id.s_addr = ldpe_router_id();
	ictl.ifindex = iface->ifindex;
	ictl.state = iface->state;
	ictl.mtu = iface->mtu;
	ictl.baudrate = iface->baudrate;
	ictl.holdtime = iface->holdtime;
	ictl.hello_interval = iface->hello_interval;
	ictl.flags = iface->flags;
	ictl.type = iface->type;
	ictl.linkstate = iface->linkstate;
	ictl.mediatype = iface->media_type;
	ictl.priority = iface->priority;
	ictl.passive = iface->passive;

	gettimeofday(&now, NULL);
	if (evtimer_pending(&iface->hello_timer, &tv)) {
		timersub(&tv, &now, &res);
		ictl.hello_timer = res.tv_sec;
	} else
		ictl.hello_timer = -1;

	if (iface->state != IF_STA_DOWN) {
		ictl.uptime = now.tv_sec - iface->uptime;
	} else
		ictl.uptime = 0;

	return (&ictl);
}
示例#16
0
void
control_close(int fd)
{
	struct ctl_conn	*c;

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warnx("%s: fd %d: not found", __func__, fd);
		return;
	}

	msgbuf_clear(&c->iev.ibuf.w);
	TAILQ_REMOVE(&ctl_conns, c, entry);

	event_del(&c->iev.ev);
	close(c->iev.ibuf.fd);

	/* Some file descriptors are available again. */
	if (evtimer_pending(&control_state.evt, NULL)) {
		evtimer_del(&control_state.evt);
		event_add(&control_state.ev, NULL);
	}

	free(c);
}
示例#17
0
/*
 * Process at least one key in the buffer and invoke tty->key_callback. Return
 * 0 if there are no further keys, or 1 if there could be more in the buffer.
 */
int
tty_keys_next(struct tty *tty)
{
	struct tty_key	*tk;
	struct timeval	 tv;
	const char	*buf;
	size_t		 len, size;
	cc_t		 bspace;
	int		 key, delay;

	buf = EVBUFFER_DATA(tty->event->input);
	len = EVBUFFER_LENGTH(tty->event->input);
	if (len == 0)
		return (0);
	log_debug("keys are %zu (%.*s)", len, (int) len, buf);

	/* If a normal key, return it. */
	if (*buf != '\033') {
		key = (u_char) *buf;
		evbuffer_drain(tty->event->input, 1);

		/*
		 * Check for backspace key using termios VERASE - the terminfo
		 * kbs entry is extremely unreliable, so cannot be safely
		 * used. termios should have a better idea.
		 */
		bspace = tty->tio.c_cc[VERASE];
		if (bspace != _POSIX_VDISABLE && key == bspace)
			key = KEYC_BSPACE;
		goto handle_key;
	}

	/* Is this device attributes response? */
	switch (tty_keys_device(tty, buf, len, &size)) {
	case 0:		/* yes */
		evbuffer_drain(tty->event->input, size);
		key = KEYC_NONE;
		goto handle_key;
	case -1:	/* no, or not valid */
		break;
	case 1:		/* partial */
		goto partial_key;
	}

	/* Is this a mouse key press? */
	switch (tty_keys_mouse(tty, buf, len, &size)) {
	case 0:		/* yes */
		evbuffer_drain(tty->event->input, size);
		key = KEYC_MOUSE;
		goto handle_key;
	case -1:	/* no, or not valid */
		break;
	case 1:		/* partial */
		goto partial_key;
	}

	/* Try to parse a key with an xterm-style modifier. */
	switch (xterm_keys_find(buf, len, &size, &key)) {
	case 0:		/* found */
		evbuffer_drain(tty->event->input, size);
		goto handle_key;
	case -1:	/* not found */
		break;
	case 1:
		goto partial_key;
	}

	/* Look for matching key string and return if found. */
	tk = tty_keys_find(tty, buf + 1, len - 1, &size);
	if (tk != NULL) {
		key = tk->key;
		goto found_key;
	}

	/* Skip the escape. */
	buf++;
	len--;

	/* Is there a normal key following? */
	if (len != 0 && *buf != '\033') {
		key = *buf | KEYC_ESCAPE;
		evbuffer_drain(tty->event->input, 2);
		goto handle_key;
	}

	/* Or a key string? */
	if (len > 1) {
		tk = tty_keys_find(tty, buf + 1, len - 1, &size);
		if (tk != NULL) {
			key = tk->key | KEYC_ESCAPE;
			size++;	/* include escape */
			goto found_key;
		}
	}

	/* Escape and then nothing useful - fall through. */

partial_key:
	/*
	 * Escape but no key string. If have already seen an escape and the
	 * timer has expired, give up waiting and send the escape.
	 */
	if ((tty->flags & TTY_ESCAPE) &&
	    !evtimer_pending(&tty->key_timer, NULL)) {
		evbuffer_drain(tty->event->input, 1);
		key = '\033';
		goto handle_key;
	}

	/* Fall through to start the timer. */

start_timer:
	/* If already waiting for timer, do nothing. */
	if (evtimer_pending(&tty->key_timer, NULL))
		return (0);

	/* Start the timer and wait for expiry or more data. */
	delay = options_get_number(&global_options, "escape-time");
	tv.tv_sec = delay / 1000;
	tv.tv_usec = (delay % 1000) * 1000L;

	if (event_initialized(&tty->key_timer))
		evtimer_del(&tty->key_timer);
	evtimer_set(&tty->key_timer, tty_keys_callback, tty);
	evtimer_add(&tty->key_timer, &tv);

	tty->flags |= TTY_ESCAPE;
	return (0);

found_key:
	if (tk->next != NULL) {
		/* Partial key. Start the timer if not already expired. */
		if (!(tty->flags & TTY_ESCAPE))
			goto start_timer;

		/* Otherwise, if no key, send the escape alone. */
		if (tk->key == KEYC_NONE)
			goto partial_key;

		/* Or fall through to send the partial key found. */
	}
	evbuffer_drain(tty->event->input, size + 1);

	goto handle_key;

handle_key:
	if (event_initialized(&tty->key_timer))
		evtimer_del(&tty->key_timer);

	if (key != KEYC_NONE)
		server_client_handle_key(tty->client, key);

	tty->flags &= ~TTY_ESCAPE;
	return (1);
}
示例#18
0
文件: tty-keys.c 项目: dragon788/tmux
/*
 * Process at least one key in the buffer and invoke tty->key_callback. Return
 * 0 if there are no further keys, or 1 if there could be more in the buffer.
 */
key_code
tty_keys_next(struct tty *tty)
{
	struct tty_key		*tk;
	struct timeval		 tv;
	const char		*buf;
	size_t			 len, size;
	cc_t			 bspace;
	int			 delay, expired = 0;
	key_code		 key;
	struct utf8_data	 ud;
	enum utf8_state		 more;
	u_int			 i;

	/* Get key buffer. */
	buf = EVBUFFER_DATA(tty->event->input);
	len = EVBUFFER_LENGTH(tty->event->input);
	if (len == 0)
		return (0);
	log_debug("keys are %zu (%.*s)", len, (int) len, buf);

	/* Is this a mouse key press? */
	switch (tty_keys_mouse(tty, buf, len, &size)) {
	case 0:		/* yes */
		key = KEYC_MOUSE;
		goto complete_key;
	case -1:	/* no, or not valid */
		break;
	case -2:	/* yes, but we don't care. */
		key = KEYC_MOUSE;
		goto discard_key;
	case 1:		/* partial */
		goto partial_key;
	}

	/* Look for matching key string and return if found. */
	tk = tty_keys_find(tty, buf, len, &size);
	if (tk != NULL) {
		if (tk->next != NULL)
			goto partial_key;
		key = tk->key;
		goto complete_key;
	}

	/* Try to parse a key with an xterm-style modifier. */
	switch (xterm_keys_find(buf, len, &size, &key)) {
	case 0:		/* found */
		goto complete_key;
	case -1:	/* not found */
		break;
	case 1:
		goto partial_key;
	}

first_key:
	/* Is this a meta key? */
	if (len >= 2 && buf[0] == '\033') {
		if (buf[1] != '\033') {
			key = buf[1] | KEYC_ESCAPE;
			size = 2;
			goto complete_key;
		}

		tk = tty_keys_find(tty, buf + 1, len - 1, &size);
		if (tk != NULL && (!expired || tk->next == NULL)) {
			size++;	/* include escape */
			if (tk->next != NULL)
				goto partial_key;
			key = tk->key;
			if (key != KEYC_NONE)
				key |= KEYC_ESCAPE;
			goto complete_key;
		}
	}

	/* Is this valid UTF-8? */
	if ((more = utf8_open(&ud, (u_char)*buf) == UTF8_MORE)) {
		size = ud.size;
		if (len < size) {
			if (expired)
				goto discard_key;
			goto partial_key;
		}
		for (i = 1; i < size; i++)
			more = utf8_append(&ud, (u_char)buf[i]);
		if (more != UTF8_DONE)
			goto discard_key;
		key = utf8_combine(&ud);
		log_debug("UTF-8 key %.*s %#llx", (int)size, buf, key);
		goto complete_key;
	}

	/* No key found, take first. */
	key = (u_char)*buf;
	size = 1;

	/*
	 * Check for backspace key using termios VERASE - the terminfo
	 * kbs entry is extremely unreliable, so cannot be safely
	 * used. termios should have a better idea.
	 */
	bspace = tty->tio.c_cc[VERASE];
	if (bspace != _POSIX_VDISABLE && key == bspace)
		key = KEYC_BSPACE;

	goto complete_key;

partial_key:
	log_debug("partial key %.*s", (int) len, buf);

	/* If timer is going, check for expiration. */
	if (tty->flags & TTY_TIMER) {
		if (evtimer_initialized(&tty->key_timer) &&
		    !evtimer_pending(&tty->key_timer, NULL)) {
			expired = 1;
			goto first_key;
		}
		return (0);
	}

	/* Get the time period. */
	delay = options_get_number(global_options, "escape-time");
	tv.tv_sec = delay / 1000;
	tv.tv_usec = (delay % 1000) * 1000L;

	/* Start the timer. */
	if (event_initialized(&tty->key_timer))
		evtimer_del(&tty->key_timer);
	evtimer_set(&tty->key_timer, tty_keys_callback, tty);
	evtimer_add(&tty->key_timer, &tv);

	tty->flags |= TTY_TIMER;
	return (0);

complete_key:
	log_debug("complete key %.*s %#llx", (int)size, buf, key);

	/* Remove data from buffer. */
	evbuffer_drain(tty->event->input, size);

	/* Remove key timer. */
	if (event_initialized(&tty->key_timer))
		evtimer_del(&tty->key_timer);
	tty->flags &= ~TTY_TIMER;

	/* Check for focus events. */
	if (key == KEYC_FOCUS_OUT) {
		tty->client->flags &= ~CLIENT_FOCUSED;
		return (1);
	} else if (key == KEYC_FOCUS_IN) {
		tty->client->flags |= CLIENT_FOCUSED;
		return (1);
	}

	/* Fire the key. */
	if (key != KEYC_NONE)
		server_client_handle_key(tty->client, key);

	return (1);

discard_key:
	log_debug("discard key %.*s %#llx", (int)size, buf, key);

	/* Remove data from buffer. */
	evbuffer_drain(tty->event->input, size);

	return (1);
}
示例#19
0
文件: tty-keys.c 项目: akracun/tmux
/*
 * Process at least one key in the buffer and invoke tty->key_callback. Return
 * 0 if there are no further keys, or 1 if there could be more in the buffer.
 */
int
tty_keys_next(struct tty *tty)
{
	struct tty_key	*tk;
	struct timeval	 tv;
	const char	*buf;
	size_t		 len, size;
	cc_t		 bspace;
	int		 key, delay;

	/* Get key buffer. */
	buf = EVBUFFER_DATA(tty->event->input);
	len = EVBUFFER_LENGTH(tty->event->input);
	if (len == 0)
		return (0);
	log_debug("keys are %zu (%.*s)", len, (int) len, buf);

	/* Is this device attributes response? */
	switch (tty_keys_device(tty, buf, len, &size)) {
	case 0:		/* yes */
		key = KEYC_NONE;
		goto complete_key;
	case -1:	/* no, or not valid */
		break;
	case 1:		/* partial */
		goto partial_key;
	}

	/* Is this a mouse key press? */
	switch (tty_keys_mouse(tty, buf, len, &size)) {
	case 0:		/* yes */
		key = KEYC_MOUSE;
		goto complete_key;
	case -1:	/* no, or not valid */
		break;
	case 1:		/* partial */
		goto partial_key;
	}

	/* Try to parse a key with an xterm-style modifier. */
	switch (xterm_keys_find(buf, len, &size, &key)) {
	case 0:		/* found */
		goto complete_key;
	case -1:	/* not found */
		break;
	case 1:
		goto partial_key;
	}

	/* Look for matching key string and return if found. */
	tk = tty_keys_find(tty, buf, len, &size);
	if (tk != NULL) {
		if (tk->next != NULL)
			goto partial_key;
		key = tk->key;
		goto complete_key;
	}

	/* Is this a meta key? */
	if (len >= 2 && buf[0] == '\033') {
		if (buf[1] != '\033') {
			key = buf[1] | KEYC_ESCAPE;
			size = 2;
			goto complete_key;
		}

		tk = tty_keys_find(tty, buf + 1, len - 1, &size);
		if (tk != NULL) {
			size++;	/* include escape */
			if (tk->next != NULL)
				goto partial_key;
			key = tk->key;
			if (key != KEYC_NONE)
				key |= KEYC_ESCAPE;
			goto complete_key;
		}
	}

first_key:
	/* No key found, take first. */
	key = (u_char) *buf;
	size = 1;

	/*
	 * Check for backspace key using termios VERASE - the terminfo
	 * kbs entry is extremely unreliable, so cannot be safely
	 * used. termios should have a better idea.
	 */
	bspace = tty->tio.c_cc[VERASE];
	if (bspace != _POSIX_VDISABLE && key == bspace)
		key = KEYC_BSPACE;

	goto complete_key;

partial_key:
	log_debug("partial key %.*s", (int) len, buf);

	/* If timer is going, check for expiration. */
	if (tty->flags & TTY_TIMER) {
		if (evtimer_initialized(&tty->key_timer) &&
		    !evtimer_pending(&tty->key_timer, NULL))
			goto first_key;
		return (0);
	}

	/* Get the time period. */
	delay = options_get_number(&global_options, "escape-time");
	tv.tv_sec = delay / 1000;
	tv.tv_usec = (delay % 1000) * 1000L;

	/* Start the timer. */
	if (event_initialized(&tty->key_timer))
		evtimer_del(&tty->key_timer);
	evtimer_set(&tty->key_timer, tty_keys_callback, tty);
	evtimer_add(&tty->key_timer, &tv);

	tty->flags |= TTY_TIMER;
	return (0);

complete_key:
	log_debug("complete key %.*s %#x", (int) size, buf, key);

	/* Remove data from buffer. */
	evbuffer_drain(tty->event->input, size);

	/* Remove key timer. */
	if (event_initialized(&tty->key_timer))
		evtimer_del(&tty->key_timer);
	tty->flags &= ~TTY_TIMER;

	/* Fire the key. */
	if (key != KEYC_NONE)
		server_client_handle_key(tty->client, key);

	return (1);
}
示例#20
0
/** \brief return true if the external timer is current started, false otherwise
 */
bool	timeout_t::external_is_started()					const throw()
{
	// use evtimer_pending()
	return evtimer_pending(const_cast<struct event *>(external_ctx), NULL);	
}
示例#21
0
文件: tty-keys.c 项目: 447327642/tmux
/*
 * Process at least one key in the buffer and invoke tty->key_callback. Return
 * 0 if there are no further keys, or 1 if there could be more in the buffer.
 */
key_code
tty_keys_next(struct tty *tty)
{
	struct timeval	 tv;
	const char	*buf;
	size_t		 len, size;
	cc_t		 bspace;
	int		 delay, expired = 0, n;
	key_code	 key;

	/* Get key buffer. */
	buf = EVBUFFER_DATA(tty->event->input);
	len = EVBUFFER_LENGTH(tty->event->input);

	if (len == 0)
		return (0);
	log_debug("keys are %zu (%.*s)", len, (int)len, buf);

	/* Is this a mouse key press? */
	switch (tty_keys_mouse(tty, buf, len, &size)) {
	case 0:		/* yes */
		key = KEYC_MOUSE;
		goto complete_key;
	case -1:	/* no, or not valid */
		break;
	case -2:	/* yes, but we don't care. */
		key = KEYC_MOUSE;
		goto discard_key;
	case 1:		/* partial */
		goto partial_key;
	}

first_key:
	/* Handle keys starting with escape. */
	if (*buf == '\033') {
		/* Look for a key without the escape. */
		n = tty_keys_next1(tty, buf + 1, len - 1, &key, &size, expired);
		if (n == 0) {	/* found */
			key |= KEYC_ESCAPE;
			size++;
			goto complete_key;
		}
		if (n == 1)	/* partial */
			goto partial_key;
	}

	/* Try to lookup key. */
	n = tty_keys_next1(tty, buf, len, &key, &size, expired);
	if (n == 0)	/* found */
		goto complete_key;
	if (n == 1)
		goto partial_key;

	/* Is this an an xterm(1) key? */
	n = xterm_keys_find(buf, len, &size, &key);
	if (n == 0)
		goto complete_key;
	if (n == 1 && !expired)
		goto partial_key;

	/*
	 * At this point, we know the key is not partial (with or without
	 * escape). So pass it through even if the timer has not expired.
	 */
	if (*buf == '\033' && len >= 2) {
		key = (u_char)buf[1] | KEYC_ESCAPE;
		size = 2;
	} else {
		key = (u_char)buf[0];
		size = 1;
	}
	goto complete_key;

partial_key:
	log_debug("partial key %.*s", (int)len, buf);

	/* If timer is going, check for expiration. */
	if (tty->flags & TTY_TIMER) {
		if (evtimer_initialized(&tty->key_timer) &&
		    !evtimer_pending(&tty->key_timer, NULL)) {
			expired = 1;
			goto first_key;
		}
		return (0);
	}

	/* Get the time period. */
	delay = options_get_number(global_options, "escape-time");
	tv.tv_sec = delay / 1000;
	tv.tv_usec = (delay % 1000) * 1000L;

	/* Start the timer. */
	if (event_initialized(&tty->key_timer))
		evtimer_del(&tty->key_timer);
	evtimer_set(&tty->key_timer, tty_keys_callback, tty);
	evtimer_add(&tty->key_timer, &tv);

	tty->flags |= TTY_TIMER;
	return (0);

complete_key:
	log_debug("complete key %.*s %#llx", (int)size, buf, key);

	/*
	 * Check for backspace key using termios VERASE - the terminfo
	 * kbs entry is extremely unreliable, so cannot be safely
	 * used. termios should have a better idea.
	 */
	bspace = tty->tio.c_cc[VERASE];
	if (bspace != _POSIX_VDISABLE && (key & KEYC_MASK_KEY) == bspace)
		key = (key & KEYC_MASK_MOD) | KEYC_BSPACE;

	/* Remove data from buffer. */
	evbuffer_drain(tty->event->input, size);

	/* Remove key timer. */
	if (event_initialized(&tty->key_timer))
		evtimer_del(&tty->key_timer);
	tty->flags &= ~TTY_TIMER;

	/* Check for focus events. */
	if (key == KEYC_FOCUS_OUT) {
		tty->client->flags &= ~CLIENT_FOCUSED;
		return (1);
	} else if (key == KEYC_FOCUS_IN) {
		tty->client->flags |= CLIENT_FOCUSED;
		return (1);
	}

	/* Fire the key. */
	if (key != KEYC_UNKNOWN)
		server_client_handle_key(tty->client, key);

	return (1);

discard_key:
	log_debug("discard key %.*s %#llx", (int)size, buf, key);

	/* Remove data from buffer. */
	evbuffer_drain(tty->event->input, size);

	return (1);
}
示例#22
0
/* Called by libevent when we get action on a multi socket */
void event_cb(int fd, short kind, void *userp)
{
	struct http_m_global *g;
	CURLMcode rc;
	CURL *easy = (CURL*) userp;
	struct http_m_cell *cell;

	cell = http_m_cell_lookup(easy);
	if (cell == NULL) {
		LM_INFO("Cell for handler %p not found in table\n", easy);
		return;
	}

	g = cell->global;
	int action =
		(kind & EV_READ ? CURL_CSELECT_IN : 0) |
		(kind & EV_WRITE ? CURL_CSELECT_OUT : 0);

	LM_DBG("activity %d on socket %d: action %d\n", kind, fd, action);
	if (kind == EV_TIMEOUT) {
		LM_DBG("handle %p timeout on socket %d (cell=%p, param=%p)\n", cell->easy, fd, cell, cell->param);
		update_stat(timeouts, 1);
		const char *error = "TIMEOUT";

		strncpy(cell->error, error, strlen(error)+1);

		reply_error(cell);

		easy = cell->easy;
		/* we are going to remove the cell and the handle here:
		   pass NULL as sockptr */
		curl_multi_assign(g->multi, cell->sockfd, NULL);

		LM_DBG("cleaning up cell %p\n", cell);
		if (cell->evset && cell->ev) {
			LM_DBG("freeing event %p\n", cell->ev);
			event_del(cell->ev);
			event_free(cell->ev);
			cell->ev=NULL;
			cell->evset=0;
		}
		unlink_http_m_cell(cell);
		free_http_m_cell(cell);

		LM_DBG("removing handle %p\n", easy);
		curl_multi_remove_handle(g->multi, easy);
		curl_easy_cleanup(easy);
		rc = curl_multi_socket_action(g->multi,
                                  CURL_SOCKET_TIMEOUT, 0, &g->still_running);

	} else {
		LM_DBG("performing action %d on socket %d\n", action, fd);
		rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
		LM_DBG("action %d on socket %d performed\n", action, fd);

		if (rc == CURLM_CALL_MULTI_PERFORM) {
			LM_DBG("received CURLM_CALL_MULTI_PERFORM, performing action again\n");
			rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
		}
		if (check_mcode(rc, cell->error) < 0) {
			LM_ERR("error: %s\n", cell->error);
			reply_error(cell);
			curl_multi_remove_handle(g->multi, easy);
			curl_easy_cleanup(easy);
		}
	}

	check_multi_info(g);
	if ( g->still_running <= 0 ) {
		LM_DBG("last transfer done, kill timeout\n");
		if (evtimer_pending(g->timer_event, NULL)) {
			evtimer_del(g->timer_event);
		}
	}
}
示例#23
0
文件: rde.c 项目: appleorange1/bitrig
int
rde_check_route(struct rip_route *e)
{
	struct timeval	 tv, now;
	struct rt_node	*rn;
	struct iface	*iface;
	u_int8_t	 metric;

	if ((e->nexthop.s_addr & htonl(IN_CLASSA_NET)) ==
	    htonl(INADDR_LOOPBACK & IN_CLASSA_NET) ||
	    e->nexthop.s_addr == INADDR_ANY)
		return (-1);

	if ((iface = if_find_index(e->ifindex)) == NULL)
		return (-1);

	metric = MIN(INFINITY, e->metric + iface->cost);

	if ((rn = rt_find(e->address.s_addr, e->mask.s_addr)) == NULL) {
		if (metric >= INFINITY)
			return (0);
		rn = rt_new_rr(e, metric);
		rt_insert(rn);
		rde_send_change_kroute(rn);
		route_start_timeout(rn);
		triggered_update(rn);
	} else {
		/*
		 * XXX don't we have to track all incoming routes?
		 * what happens if the kernel route is removed later.
		 */
		if (rn->flags & F_KERNEL)
			return (0);

		if (metric < rn->metric) {
			rn->metric = metric;
			rn->nexthop.s_addr = e->nexthop.s_addr;
			rn->ifindex = e->ifindex;
			rde_send_change_kroute(rn);
			triggered_update(rn);
		} else if (e->nexthop.s_addr == rn->nexthop.s_addr &&
		    metric > rn->metric) {
				rn->metric = metric;
				rde_send_change_kroute(rn);
				triggered_update(rn);
				if (rn->metric == INFINITY)
					route_start_garbage(rn);
		} else if (e->nexthop.s_addr != rn->nexthop.s_addr &&
		    metric == rn->metric) {
			/* If the new metric is the same as the old one,
			 * examine the timeout for the existing route.  If it
			 * is at least halfway to the expiration point, switch
			 * to the new route.
			 */
			timerclear(&tv);
			gettimeofday(&now, NULL);
			evtimer_pending(&rn->timeout_timer, &tv);
			if (tv.tv_sec - now.tv_sec < ROUTE_TIMEOUT / 2) {
				rn->nexthop.s_addr = e->nexthop.s_addr;
				rn->ifindex = e->ifindex;
				rde_send_change_kroute(rn);
			}
		}

		if (e->nexthop.s_addr == rn->nexthop.s_addr &&
		    rn->metric < INFINITY)
			route_reset_timers(rn);
	}

	return (0);
}