Пример #1
0
void readcb(struct bufferevent *bev, void *ctx)
{
	char tmp[128];
	size_t n = bufferevent_read(bev, tmp, sizeof(tmp));
	printf("readcb, recved %d bytes: \n", int(n));
	if (n>0)
	{
		for (size_t i=0;i<n;i++)
		{
			printf("%02x ", tmp[i]);
		}
	}
	printf("\n\n");
}
Пример #2
0
void read_cb(struct bufferevent *bev, void *arg)
{
#define MAX_LINE    256
  char line[MAX_LINE+1];
  int n;
  evutil_socket_t fd = bufferevent_getfd(bev);

  while (n = bufferevent_read(bev, line, MAX_LINE), n > 0) {
    line[n] = '\0';
    printf("fd=%u, read line: %s\n", fd, line);

    bufferevent_write(bev, line, n);
  }
}
Пример #3
0
void socket_read_cb(bufferevent* bev, void* arg)
{
    char msg[4096];

    size_t len = bufferevent_read(bev, msg, sizeof(msg));

    msg[len] = '\0';
    printf("recv the client msg: %s", msg);


    char reply_msg[4096] = "I have recvieced the msg: ";

    strcat(reply_msg + strlen(reply_msg), msg);
    bufferevent_write(bev, reply_msg, strlen(reply_msg));
}
Пример #4
0
void read_cb(struct bufferevent*bev, void*arg)//循环读取套接字里的内容;
{
    #define MAX_LINE 256
    char line[MAX_LINE+1]={0};
    QR_HEAD *head;
    QA_HEAD qa_head;
    memset(&qa_head, 0, sizeof(QA_HEAD));
    qa_head.package_len = 232;
    qa_head.package_id = 11;
    HashNode **getinfo;//储存查询结果信息;
    int n;
    int i=0; 
    
    char *buf = malloc(sizeof(QA_HEAD)+4096);
    
    evutil_socket_t fd = bufferevent_getfd(bev);//获取套接字描述符;
    while(n = bufferevent_read(bev, line, MAX_LINE), n>0)//读取套接字中的内容;
    {
        head = (QR_HEAD*)line;
        
        printf("len %d\n", head->package_len);
        printf("id %d\n", head->package_id);
        printf("fd = %u, readline:%s", fd, (char*)(line+sizeof(QR_HEAD)));
        if(head->package_id == 9)//检测是不是reload包,通知重载hash表;
        {
            update_hash_table();//重载hash表内容;
            continue;
        }
        getinfo = hash_table_lookup(line+sizeof(QA_HEAD));//查询hash表;
        if(getinfo == NULL)//如果没有查询到响应的信息,设置包长度为包头长度;
        {
            qa_head.package_len = 8;
            memcpy(buf, &qa_head, sizeof(QA_HEAD));
        }
        else
        {
            i = 0;
            while(getinfo[i])//循环往包里添加查询到的数据;
            {
                memcpy(buf+sizeof(QA_HEAD)+i*sizeof(INFOR), getinfo[i]->infor, sizeof(INFOR));
                i++;
            }
            qa_head.package_len = sizeof(QA_HEAD)+i*sizeof(INFOR);
            memcpy(buf, &qa_head, sizeof(QA_HEAD));
        }
        bufferevent_write(bev, buf, sizeof(QA_HEAD)+4096);//发包;
    }
}
Пример #5
0
void read_cb(struct bufferevent *bev,void *arg)
{

	char line[256+1];
	int  n=0;
	while((n=bufferevent_read(bev,line,256)) > 0)
	{
      
	  line[n]='\0';
	  printf("read: %s\n",line);

    memset(line,'\0',257);
	}
	printf("read over\n");
	return ;
}
Пример #6
0
//从socket读
void TcpClient::read_cb(struct bufferevent *bev, void *arg)
{
    TcpClient *pClient = (TcpClient *)arg;
    const int MAX_LENGHT = 1024;
    char cbData[MAX_LENGHT];
    int n;
    //读数据:bufferevent_read
    //写数据:bufferevent_write
    while (n = bufferevent_read(bev, cbData, MAX_LENGHT))
    {
        if (n <= 0)
            break;
        //处理接收到的数据
        pClient->DealWithData(bev,cbData, n);
    }
}
Пример #7
0
void udp_readcb(struct bufferevent *bev, void *c) {
    UNUSED(c);
    char buf[3] = {0};
    struct evbuffer *input = bufferevent_get_input(bev);
    while (evbuffer_get_length(input) >= 3) {
        bufferevent_read(bev, buf, 3);
        if (!strncmp(buf, "ACK", 3)) {
            udp_last_ack = time_now();
            if (!connection_valid) {
                connection_valid = true;
                log_notice("Connected to %s", config_get_remote_hostname());
            }
        }
    }
    return;
}
Пример #8
0
void read_cb(struct bufferevent *bev, void *arg) {
#define MAX_LINE    2560
    char line[MAX_LINE + 1];
    char output[1000];
    int n;
    evutil_socket_t fd = bufferevent_getfd(bev);

    while (n = bufferevent_read(bev, line, MAX_LINE), n > 0) {
        line[n] = '\0';
        printf("fd=%u, read line: %s\n", fd, line);
        worker((int) fd, line, output);
        printf("out line: %s,len=%d\n", output,strlen(output));

        bufferevent_write(bev, output, strlen(output));
    }
    //close(fd);
}
Пример #9
0
static void
buff_input_cb (struct bufferevent *bev,
               void *ctx)
{
    printf("***in %s\n", __func__);

    int len = evbuffer_get_length(bufferevent_get_input(bev));
    printf("len=%d\n", len);

    char buff[1024];
    /* first read data, second make READ event pending */
    bufferevent_read(bev, buff, 1024);
    len = evbuffer_get_length(bufferevent_get_input(bev));
    printf("len=%d\n", len);

    return;
}
Пример #10
0
static void
conn_readcb(struct bufferevent *bev, void *user_data)
{
    struct evbuffer *input =bufferevent_get_input(bev);
    printf("input totalSize:%d\n",input->total_len);
    char dataBuf[14000] = {0};
    int buffSize = evbuffer_get_length(input);
    printf("buffSize:%d\n",buffSize);
    if (buffSize > 0)
    {
        int actualReadBytes = bufferevent_read(bev,dataBuf,buffSize);
        printf("actualReadBytes:%d\n",actualReadBytes);
        bufferevent_write(bev, dataBuf, actualReadBytes);
        struct evbuffer *output = bufferevent_get_output(bev);
        printf("in conn_readcb output totalSize:%d\n",(size_t)(output->total_len));
    }
}
Пример #11
0
void
pipe_read_cb(struct bufferevent *bev, void *arg)
{
	char query_str[1024] = {0};

	bufferevent_read(bev, query_str, sizeof(query_str));
	printf("tmp: %s\n", query_str);

	if (bufferevent_write(bufev_sock, query_str, strlen(query_str)) == -1) {
		jlog(L_ERROR, "bufferevent_write failed");
		return;
	}

	if (bufferevent_write(bufev_sock, "\n", strlen("\n")) == -1) {
		jlog(L_ERROR, "bufferevent_write failed");
		return;
	}
}
/* work to do */
static void server_job_function(struct job *job) {
    client_t *client = (client_t *)job->user_data;

    char data[4096];
    int nbytes;

    for(;;)
    {
        nbytes =  bufferevent_read(client->buf_ev, data, sizeof(data));
        if(nbytes <= 0)
        {
            break;
        }

        bufferevent_write(client->buf_ev, data, nbytes);
    }

}
Пример #13
0
	int Conn::recvMsg(struct bufferevent* pEvbuf, void* data, size_t size)
	{
		size_t n = bufferevent_read(pEvbuf, data, size);

		char c = '\0';
		for(unsigned int i = 0; i < n; i++)
		{
			if(memcmp((char*)data + i, &c, 1) != 0)
			{
				//如果存在有效数据
				return 0;
			}
		}

		//读到的数据为全0
		// LOG_DEBUG("[hint] recvMsg() read " << size << " character '0' from buffer, skip!");
		return -1;
	}
Пример #14
0
zend_string * ion_buffer_read_all(ion_buffer * buffer) {
    size_t incoming_length = evbuffer_get_length(bufferevent_get_input(buffer));
    zend_string * data;

    if(!incoming_length) {
        return ZSTR_EMPTY_ALLOC();
    }

    data = zend_string_alloc(incoming_length, 0);
    ZSTR_LEN(data) = bufferevent_read(buffer, ZSTR_VAL(data), incoming_length);
    if (ZSTR_LEN(data) > 0) {
        ZSTR_VAL(data)[ZSTR_LEN(data)] = '\0';
        return data;
    } else {
        zend_string_free(data);
        return NULL;
    }
}
Пример #15
0
void Channel::readCallback(struct bufferevent* bev, void* data)
{
	char msg[4096] = { 0 };
	fprintf(stdout, "readCallback..., threadID:%d\n", ::GetCurrentThreadId());
	struct evbuffer* input = bufferevent_get_input(bev);
	size_t len = evbuffer_get_length(input);
	//读取数据
	len =  bufferevent_read(bev, msg, 4096);
	echo_context* ptrData = (echo_context*)msg;
	std::cout << "server read the data: " << ptrData->echo_contents << std::endl;
	evbuffer_drain(input, len);//将读取到的数据移除掉
	fprintf(stdout, "drain, len:%d\n", len);

 	char* reply = "i has read you data";
	echo_context pp;
	memset(&pp, 0, sizeof(echo_context));
	memcpy(pp.echo_contents, "i has read you data", 80);
	bufferevent_write(bev, (char*)&pp, sizeof(echo_context));
}
Пример #16
0
static void readcb(struct bufferevent* bev, void* args) {
  char buf[BUF_LEN];
  size_t numRead;
  while ((numRead = bufferevent_read(bev, buf, BUF_LEN))) {
    char *p;
    for (p = buf; p < buf + numRead; ) {
      struct inotify_event *event = (struct inotify_event*) p;
      if (inotifycallback)
        inotifycallback(event);
      if (recursive && event->mask & IN_CREATE && event->mask & IN_ISDIR && event->len > 0) {
        char* folder = get_folder(event->wd);
        char fullpath[PATH_MAX];
        snprintf(fullpath, sizeof(fullpath), "%s/%s", folder, folder);
        watch_folder(strdup(fullpath), 0);
      }
      p += sizeof(struct inotify_event) + event->len;
    }
  };
}
Пример #17
0
        void CTcpHandler::TcpRead()
        {
            //内存copy三次,太浪费,后续改进
            int iLength = evbuffer_get_length(bufferevent_get_input(m_pBufevt));
            char *pData = new char[iLength + 1];
            bufferevent_read(m_pBufevt, pData, iLength);			
            pData[iLength] = '\0';
		    NsqLogPrintf(LOG_DEBUG, "TcpRead iLength = %d\n", iLength);

            //iNeedLength 证明包处理出错,已经析构掉了handler相关的一些
            int iNeedLength = OnRead(pData, iLength); 

            if (iNeedLength > 0)
            {
                bufferevent_setwatermark(m_pBufevt, EV_READ, iNeedLength, 0);
            }

            delete pData;
        }
Пример #18
0
/* Check that the server sends back the same byte that the client sent.
   If MAX_REQUESTS have been reached, exit. Otherwise, start another client. */
static void
client_read_cb(struct bufferevent *bev, void *ctx)
{
	unsigned char tmp;
	struct event_base *base = bufferevent_get_base(bev);

	bufferevent_read(bev, &tmp, 1);
	if (tmp != 'A') {
		puts("Incorrect data received!");
		exit(2);
	}
	bufferevent_free(bev);

	num_requests++;
	if (num_requests == MAX_REQUESTS) {
		event_base_loopbreak(base);
	} else {
		start_client(base);
	}
}
Пример #19
0
//void echo_buffered_on_read(struct bufferevent *bev, void *arg) {
void echo_buffered_on_read(OeSession client) {

    OeNetConn conn = OeSession_get_conn(client);
    struct bufferevent *bev = (struct bufferevent *)oenetconn_get_conn_obj(conn);
    char *peekdata = OeNetConn_peek(conn, 5, 5);
    int pos = OeNetConn_get_pos(conn, "cid:", 4);
    printf("peek: %s\n", peekdata);
    int SZ = 50;
    char input[SZ + 1];
    memset(&input, 0, sizeof(input));
    bufferevent_read(bev, input, SZ);
    printf("read: %s\n", input);

    bufferevent_write(bev, "foo", 4);

    if ( strcmp("bye", input) == 0 ) {
        OE_ILOG(NULL,"bye. quitting.\n");
        event_loopexit(0);
    }
}
Пример #20
0
void read_cb(struct bufferevent *bev, void *arg)
{
#define MAX_LINE    256
    char line[MAX_LINE+1];
    int n;
    evutil_socket_t fd = bufferevent_getfd(bev);
    net_para_t net;

    while (n = bufferevent_read(bev, line, MAX_LINE), n > 0) {
        line[n] = '\0';
        printf("fd=%u, read line: %s\n", fd, line);

        net.net = bev;
        net.print = net_print;
        parse_and_exec_cmd(line, ifs_cmd_list, &net);

        line[0] = '>';
        line[1] = 0;
        bufferevent_write(bev, line, 2);
    }
}
Пример #21
0
static void watcher_inotify(struct bufferevent *bev, void *vctx)
{
	struct watcher_ctx *ctx = vctx;
	struct inotify_event ev;

	/*
	 * Discard the event(s) and wait for resolv.conf to rematerialize.
	 * Note that upon deletion, the kernel will generate both
	 * IN_DELETE_SELF and IN_IGNORED events.
	 */
	while (1) {
		size_t bytes = bufferevent_read(bev, &ev, sizeof(ev));
		if (bytes == 0)
			break;
		else if (bytes != sizeof(ev))
			die("bad inotify event: %zu bytes\n", bytes);

		if (ev.wd == ctx->inotify_wd && ev.mask & IN_DELETE_SELF)
			watcher_check_resolv(-1, 0, vctx);
	}
}
Пример #22
0
static void
reader_eventcb(struct bufferevent *bev, short what, void *ctx)
{
	struct event_base *base = ctx;
	if (what & BEV_EVENT_ERROR) {
		perror("foobar");
		TT_FAIL(("got connector error %d", (int)what));
		return;
	}
	if (what & BEV_EVENT_CONNECTED) {
		bufferevent_enable(bev, EV_READ);
	}
	if (what & BEV_EVENT_EOF) {
		char buf[512];
		size_t n;
		n = bufferevent_read(bev, buf, sizeof(buf)-1);
		buf[n] = '\0';
		tt_str_op(buf, ==, TEST_STR);
		if (++n_strings_read == 2)
			event_base_loopexit(base, NULL);
	}
Пример #23
0
static void
socks_version(struct bufferevent *bev, void *ctx)
{
	int keep_alive = (int) ctx;
	u_char version;

	bufferevent_read(bev, &version, 1);

	LWIP_DEBUGF(SOCKS_DEBUG, ("%s: socks version %d\n", __func__, version));

	switch (version) {
	case 4:
		socks4_start(bev, keep_alive);
		break;
	case 5:
		socks5_start(bev, keep_alive);
		break;
	default:
		bufferevent_free(bev);
	}
}
Пример #24
0
static void cb_conn_read_async(struct bufferevent *bev, void *user_data)
{
    void*    buffer  = NULL;
    uint32_t buf_len = 0;
    addr_t   *addr   = (addr_t*)user_data;

    /* bufferevent_lock(bev); */

    struct evbuffer *buf_in = bufferevent_get_input(bev);

    /* read data frome buffer in */
    buf_len = evbuffer_get_length(buf_in);
    buffer = calloc(1, buf_len);
    bufferevent_read(bev, buffer, buf_len);

    /* bufferevent_unlock(bev); */

    /* put data to addr recv buffer, and translate to command format */
    addr_recv(addr, buffer, buf_len);
    free(buffer);
}
/**
 * Called by libevent when there is data to read.
 */
void
buffered_on_read(struct bufferevent *bev, void *arg)
{
    size_t readed = 0;
    char data[256] = {0};

    readed = bufferevent_read(bev, data, 256);
    printf("read data: %s\n", data);

	/* Write back the read buffer. It is important to note that
	 * bufferevent_write_buffer will drain the incoming data so it
	 * is effectively gone after we call it. */
    struct evbuffer *out_buffer = evbuffer_new();
    evbuffer_add(out_buffer, data, readed);

    char buffer[32] = "hello, world";
	//bufferevent_write(bev, buffer, 32);
    struct client *c = (struct client *)arg;
    //if (c->msg_count++ == 2)
    bufferevent_flush(bev, EV_WRITE, BEV_FINISHED);
        c->need_free = 1;
}
Пример #26
0
static void read_cb(struct bufferevent *bev, void *ctx) {
    state *s=(state *)ctx;
    int received, error=1;

    for(;;) {
        received=bufferevent_read(bev, s->buff.frag+s->ptr, s->len);
        if(received<=0) /* no data buffered */
            return;
        s->ptr+=received;
        s->len-=received;
        if(s->len) /* not enough data buffered */
            return;
        s->ptr=0;
        s->mode^=1;
        if(s->mode) { /* finished reading record header */
            s->len=rec_len(&s->buff.rec);
            if(s->len<1 || s->len>MAX_FRAG)
                break;
            s->rec_type=s->buff.rec.type;
        } else { /* finished reading record fragment */
            s->len=sizeof(record);
            if(s->rec_type==22 && s->buff.frag[0]==2) {
                /* handshake message type 2 (server_hello) */
                bufferevent_write(bev, &r2, rec_len(&r2.rec)+sizeof(record));
                bufferevent_write(bev, &r3, rec_len(&r3.rec)+sizeof(record));
                bufferevent_write(bev, &r4, rec_len(&r4.rec)+sizeof(record));
            }
            if(s->rec_type==21 && s->buff.frag[0]==2 && s->buff.frag[1]==20) {
                error=0; /* fatal alert 20 (bad_record_mac) */
                break;
            }
        }
    }
    bufferevent_free(bev);
    new_connection(ctx);
    statistics(error);
}
Пример #27
0
void cTCPLinkImpl::ReadCallback(bufferevent * a_BufferEvent, void * a_Self)
{
	ASSERT(a_Self != nullptr);
	cTCPLinkImpl * Self = static_cast<cTCPLinkImpl *>(a_Self);
	ASSERT(Self->m_BufferEvent == a_BufferEvent);
	ASSERT(Self->m_Callbacks != nullptr);

	// Read all the incoming data, in 1024-byte chunks:
	char data[1024];
	size_t length;
	auto tlsContext = Self->m_TlsContext;
	while ((length = bufferevent_read(a_BufferEvent, data, sizeof(data))) > 0)
	{
		if (tlsContext != nullptr)
		{
			ASSERT(tlsContext->IsLink(Self));
			tlsContext->StoreReceivedData(data, length);
		}
		else
		{
			Self->ReceivedCleartextData(data, length);
		}
	}
}
Пример #28
0
void MTCLink::RecvCallback(struct bufferevent *bev)
{
  int totalLength = 0;
  int n;
  char input[10000];
  memset(input,'\0',10000);
  while (1){
    bufferevent_lock(bev);
    n = bufferevent_read(bev, input+strlen(input), sizeof(input));
    bufferevent_unlock(bev);
    totalLength += n;
    if (n <= 0)
      break;
  }

  char *inputP = input;
  while (totalLength > 0){
    if (fTempBytes == 0){
      int numThisPacket = ((SBCPacket *) inputP)->numBytes;
      if (numThisPacket > totalLength){
        memcpy(fTempPacket,inputP,totalLength);
        fBytesLeft = numThisPacket-totalLength; 
        fTempBytes = totalLength;
        break;
      }else{
        memcpy(fTempPacket,inputP,numThisPacket);
        SBCPacket *packet = (SBCPacket *) fTempPacket;
        pthread_mutex_lock(&fRecvQueueLock);
        fRecvQueue.push(*packet);
        //lprintf("Got packet, size %d empty %d\n",fRecvQueue.size(),fRecvQueue.empty());
        pthread_cond_signal(&fRecvQueueCond);
        pthread_mutex_unlock(&fRecvQueueLock);
        memset(fTempPacket,0,sizeof(fTempPacket));
        totalLength -= numThisPacket;
        inputP += numThisPacket;
      }
    }else{
      if (fBytesLeft > totalLength){
        memcpy(fTempPacket+fTempBytes,inputP,totalLength);
        fBytesLeft -= totalLength; 
        fTempBytes += totalLength;
        break;
      }else{
        memcpy(fTempPacket+fTempBytes,inputP,fBytesLeft);
        SBCPacket *packet = (SBCPacket *) fTempPacket;
        pthread_mutex_lock(&fRecvQueueLock);
        fRecvQueue.push(*packet);
        //lprintf("Got packet, size %d empty %d\n",fRecvQueue.size(),fRecvQueue.empty());
        pthread_cond_signal(&fRecvQueueCond);
        pthread_mutex_unlock(&fRecvQueueLock);
        memset(fTempPacket,0,sizeof(fTempPacket));
        inputP += fBytesLeft;
        totalLength -= fBytesLeft;
        fBytesLeft = 0;
        fTempBytes = 0;
      }
    }
  }
//  if (fTempBytes)
//    lprintf("%d bytes left\n",fBytesLeft);
}
Пример #29
0
void irc_buffevent_read( struct bufferevent *bev, void *arg ) {
  BeatBoard::IRCConnection *irc_conn = (BeatBoard::IRCConnection*)arg;
  char buf[1024];
  stringstream str_stream;
  size_t read_size = 0;
  while ( 0 < (read_size = bufferevent_read( bev, buf, 1023 ) ) ){
    buf[read_size] = 0;
    str_stream << string(buf);
  }
  while(str_stream.getline(buf, 1024)){
    printf("readed: %s\n", buf);
    BeatBoard::IRCEvent *event = BeatBoard::parse_irc_message(buf);
    if(event != NULL){
      if(*(event->command) == string("PING")){
        irc_conn->PONG( *(event->params[0]) );
      }else if(*(event->command) == string("PRIVMSG")){
        string channel = *(event->params[0]);
        string message = *(event->params[1]);
        string prefix = *(event->prefix);

        irc_conn->received[channel].addMessage(prefix, message);
        
        irc_conn->notifyRead();
        irc_conn->loggingMessage(channel, prefix, message);
        
      }else if(*(event->command) == BeatBoard::IRCConnection::RPL_NAMREPLY){
        string users = *(event->params[3]);
        size_t pos;
        while( (pos = users.find(' ')) != string::npos){
          irc_conn->received[*(event->params[2])].addUser(users.substr(0, pos));
          users = users.substr(pos + 1, users.size() - 1);
        }
        irc_conn->received[*(event->params[2])].addUser(users);
      }else if(*(event->command) == BeatBoard::IRCConnection::RPL_ENDOFNAMES){
        irc_conn->received[*(event->params[1])].addUserEnd();
        irc_conn->notifyJoin();
      }else if(*(event->command) == string("JOIN")){
        string channel = *(event->params[0]);
        string message = *(event->command);
        string prefix = *(event->prefix);

        irc_conn->received[channel].addMessage(message, prefix);
        
        irc_conn->notifyRead();
        irc_conn->loggingMessage(channel, prefix, message);
        irc_conn->received[channel].addUserJoin(prefix);
        
      }else if(*(event->command) == string("PART")){
        string channel = *(event->params[0]);
        string message = *(event->command) + string(" ") + *(event->params[1]);
        string prefix = *(event->prefix);
        irc_conn->received[channel].addMessage(message, prefix);
        irc_conn->received[channel].delUser(prefix);
        
        irc_conn->notifyRead();
        irc_conn->loggingMessage(channel, prefix, message);
        
      }else if(*(event->command) == string("QUIT")){
        string message = *(event->command) + string(" ") + *(event->params[0]);
        string prefix = *(event->prefix);

        map<string,BeatBoard::IRCChannel>::iterator it =
          (irc_conn->received).begin();
        while(it != (irc_conn->received).end()){
          irc_conn->received[it->first].addMessage(message, prefix);
          irc_conn->received[it->first].delUser(prefix);
          irc_conn->loggingMessage(it->first, prefix, message);
          ++it;
        }

        irc_conn->notifyRead();
      }
      delete event;
    }else{

      //event not found
    }
  }
}
Пример #30
0
static void
tr_watchdir_win32_on_event (struct bufferevent * event,
                            void               * context)
{
  const tr_watchdir_t handle = context;
  size_t nread;
  size_t name_size = MAX_PATH * sizeof (WCHAR);
  char * buffer = tr_malloc (sizeof (FILE_NOTIFY_INFORMATION) + name_size);
  PFILE_NOTIFY_INFORMATION ev = (PFILE_NOTIFY_INFORMATION) buffer;
  const size_t header_size = offsetof (FILE_NOTIFY_INFORMATION, FileName);

  /* Read the size of the struct excluding name into buf. Guaranteed to have at
     least sizeof (*ev) available */
  while ((nread = bufferevent_read (event, ev, header_size)) != 0)
    {
      if (nread == (size_t) -1)
        {
          log_error ("Failed to read event: %s", tr_strerror (errno));
          break;
        }

      if (nread != header_size)
        {
          log_error ("Failed to read event: expected %zu, got %zu bytes.",
                     header_size, nread);
          break;
        }

      const size_t nleft = ev->NextEntryOffset - nread;

      assert (ev->FileNameLength % sizeof (WCHAR) == 0);
      assert (ev->FileNameLength > 0);
      assert (ev->FileNameLength <= nleft);

      if (nleft > name_size)
        {
          name_size = nleft;
          buffer = tr_realloc (buffer, sizeof (FILE_NOTIFY_INFORMATION) + name_size);
          ev = (PFILE_NOTIFY_INFORMATION) buffer;
        }

      /* Consume entire name into buffer */
      if ((nread = bufferevent_read (event, buffer + header_size, nleft)) == (size_t) -1)
        {
          log_error ("Failed to read name: %s", tr_strerror (errno));
          break;
        }

      if (nread != nleft)
        {
          log_error ("Failed to read name: expected %zu, got %zu bytes.", nleft, nread);
          break;
        }

      if (ev->Action == FILE_ACTION_ADDED ||
          ev->Action == FILE_ACTION_MODIFIED ||
          ev->Action == FILE_ACTION_RENAMED_NEW_NAME)
        {
          char * name = tr_win32_native_to_utf8 (ev->FileName,
                                                 ev->FileNameLength / sizeof (WCHAR));
          if (name != NULL)
            {
              tr_watchdir_process (handle, name);
              tr_free (name);
            }
        }
    }

  tr_free (buffer);
}