]> granicus.if.org Git - libevent/commitdiff
bufferevent: introduce bufferevent_replacefd() (like setfd() but also close fd)
authorAzat Khuzhin <azat@libevent.org>
Tue, 23 Mar 2021 06:00:24 +0000 (09:00 +0300)
committerAzat Khuzhin <azat@libevent.org>
Tue, 23 Mar 2021 06:06:58 +0000 (09:06 +0300)
bufferevent.c
include/event2/bufferevent.h

index 27f2a9ba0742434df0cd67cf08e15cefe344018e..53d3a99556eb9056fe3af38de8fdf60cc1a41325 100644 (file)
@@ -881,6 +881,34 @@ bufferevent_setfd(struct bufferevent *bev, evutil_socket_t fd)
        return res;
 }
 
+int
+bufferevent_replacefd(struct bufferevent *bev, evutil_socket_t fd)
+{
+       union bufferevent_ctrl_data d;
+       int err = -1;
+       evutil_socket_t old_fd = EVUTIL_INVALID_SOCKET;
+
+       BEV_LOCK(bev);
+       if (bev->be_ops->ctrl) {
+               err = bev->be_ops->ctrl(bev, BEV_CTRL_GET_FD, &d);
+               if (!err) {
+                       old_fd = d.fd;
+                       if (old_fd != EVUTIL_INVALID_SOCKET) {
+                               err = evutil_closesocket(old_fd);
+                       }
+               }
+               if (!err) {
+                       d.fd = fd;
+                       err = bev->be_ops->ctrl(bev, BEV_CTRL_SET_FD, &d);
+               }
+       }
+       if (err)
+               event_debug(("%s: cannot replace fd for %p from "EV_SOCK_FMT" to "EV_SOCK_FMT, __func__, bev, old_fd, fd));
+       BEV_UNLOCK(bev);
+
+       return err;
+}
+
 evutil_socket_t
 bufferevent_getfd(struct bufferevent *bev)
 {
index 58baf831087e9e3b9d5aaf9ebf69f89382f38da4..a50944f72e000f6fd911b34d3bf83922dc138f8d 100644 (file)
@@ -377,6 +377,18 @@ void bufferevent_getcb(struct bufferevent *bufev,
 EVENT2_EXPORT_SYMBOL
 int bufferevent_setfd(struct bufferevent *bufev, evutil_socket_t fd);
 
+/**
+  Replaces the file descriptor on which the bufferevent operates.
+  Not supported for all bufferevent types.
+
+  Unlike bufferevent_setfd() it will close previous file descriptor (if any).
+
+  @param bufev the bufferevent object for which to change the file descriptor
+  @param fd the file descriptor to operate on
+*/
+EVENT2_EXPORT_SYMBOL
+int bufferevent_replacefd(struct bufferevent *bufev, evutil_socket_t fd);
+
 /**
    Returns the file descriptor associated with a bufferevent, or -1 if
    no file descriptor is associated with the bufferevent.