#301 bufferevent_write returns 0 in case of bad fd

For_2.0
open
nobody
5
2013-03-02
2013-03-02
Ruslan Osmanov
No

$ cat test1.c
#include <event2/event.h>
#include <event2/bufferevent.h>
#include <sys/socket.h>
#include <string.h>

static void fatal_error_cb(int err) {
printf("fatal_error_cb\n");
}
static void log_cb(int severity, const char *msg)
{
printf("%s\n", msg);

}
int main (int argc, char const* argv[]) {
struct event_base *base;
struct bufferevent *bev;

event_set_fatal_callback(fatal_error_cb);
event_set_log_callback(log_cb);
event_enable_debug_mode();

base = event_base_new();

bev = bufferevent_socket_new(base, 109, BEV_OPT_CLOSE_ON_FREE);

/* what gonna return bufferevent_write()? */
int res = bufferevent_write(bev, "xyz", 3);
printf("bufferevent_write(): %d\n", res);

event_base_dispatch(base);

return 0;
}

$ gcc -levent_core -levent_extra test1.c -o test1

$ ./test1
Epoll ADD(4) on fd 109 failed. Old events were 0; read change was 0 (none); write change was 1 (add): Bad file descriptor
bufferevent_write(): 0

Should return -1 here.

Discussion

  • Nick Mathewson
    Nick Mathewson
    2013-03-04

    bufferevent_write adds data to be written; libevent won't know whether the data could be written successfully until later when it actually tries to write it.

    The logical place to get an error here would be via the bufferevent's errorcb callback, I guess.

    It won't know whether the fd is good until it tries to do an event_add() on the appropriate fd --- but due to limitations of some backends, there isn't a great channel in the event_add() interface to find out whether the fd actually failed. In kqueue, for example, you can't learn that an fd is bad until dispatch time.

    Does anybody have an idea for an implementable interface here?