1 module libssh.poll; 2 3 import libssh.c_bindings.libssh; 4 import libssh.c_bindings.poll; 5 import libssh.errors; 6 import libssh.utils; 7 import libssh.session; 8 9 enum PollEvents : short { 10 In = POLLIN, 11 Pro = POLLPRI, 12 Out = POLLOUT, 13 } 14 15 class SSHEvent : Disposable { 16 alias EventCallback = bool delegate(socket_t fd, PollEvents revents); 17 18 void addFd(socket_t fd, PollEvents events, EventCallback cb) { 19 this._eventCallbacks[fd] = cb; 20 scope(failure) this._eventCallbacks.remove(fd); 21 22 auto rc = ssh_event_add_fd(this._event, fd, events, &nativeEventCallback, 23 cast(void*) &this._eventCallbacks[fd]); 24 checkForRCError(rc, rc); 25 } 26 27 void removeFd(socket_t fd) { 28 scope(exit) this._eventCallbacks.remove(fd); 29 auto rc = ssh_event_remove_fd(this._event, fd); 30 checkForRCError(rc, rc); 31 } 32 33 void addSession(SSHSession session) { 34 auto rc = ssh_event_add_session(this._event, session._session); 35 checkForRCError(rc, rc); 36 } 37 38 void removeSession(SSHSession session) { 39 auto rc = ssh_event_remove_session(this._event, session._session); 40 checkForRCError(rc, rc); 41 } 42 43 void doPoll(int timeout) { 44 auto rc = ssh_event_dopoll(this._event, timeout); 45 checkForRCError(rc, rc); 46 } 47 48 this() { 49 auto event = ssh_event_new(); 50 if (event is null) { 51 throw new SSHException("Error while creating new event"); 52 } 53 this(event); 54 } 55 56 ~this() { 57 this._dispose(true); 58 } 59 60 override void dispose() { 61 this._dispose(false); 62 } 63 64 private { 65 void _dispose(bool fromDtor) { 66 if (this._event !is null) { 67 ssh_event_free(this._event); 68 this._event = null; 69 } 70 } 71 72 this(ssh_event event) { 73 this._event = event; 74 } 75 76 ssh_event _event; 77 EventCallback[socket_t] _eventCallbacks; 78 } 79 } 80 81 private { 82 extern(C) int nativeEventCallback(socket_t fd, int revents, void *userdata) { 83 auto cb = cast(SSHEvent.EventCallback*) userdata; 84 85 try { 86 return (*cb)(fd, cast(PollEvents) revents) ? SSH_OK : SSH_ERROR; 87 } catch (Exception) { 88 return SSH_ERROR; 89 } 90 } 91 }