From b0921370916880e4b2d9ea80571b28741b2368b2 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 19 Oct 2012 00:34:04 -0700 Subject: [PATCH] Add select handler, partial refactor. --- libguac/include/socket.h | 25 ++++++++++++++++++++++++ libguac/src/socket.c | 42 +++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/libguac/include/socket.h b/libguac/include/socket.h index f558f9a8..42e5c902 100644 --- a/libguac/include/socket.h +++ b/libguac/include/socket.h @@ -47,6 +47,12 @@ * @file socket.h */ +typedef struct guac_socket_fd_data { + + int fd; + +} guac_socket_fd_data; + typedef struct guac_socket guac_socket; /** @@ -75,6 +81,19 @@ typedef ssize_t guac_socket_read_handler(guac_socket* socket, typedef ssize_t guac_socket_write_handler(guac_socket* socket, void* buf, size_t count); +/** + * Generic handler for socket select operations, similar to the POSIX select() + * function. When guac_socket_select() is called on a guac_socket, its + * guac_socket_select_handler will be invoked, if defined. + * + * @param socket The guac_socket being selected. + * @param usec_timeout The maximum number of microseconds to wait for data, or + * -1 to potentially wait forever. + * @return Positive on success, zero if the timeout elapsed and no data is + * available, negative on error. + */ +typedef int guac_socket_select_handler(guac_socket* socket, int usec_timeout); + /** * Generic handler for the closing of a socket, modeled after the standard * POSIX close() function. When set within a guac_socket, a handler of this type @@ -108,6 +127,12 @@ struct guac_socket { */ guac_socket_write_handler* write_handler; + /** + * Handler which will be called whenever guac_socket_select is invoked + * on this socket. + */ + guac_socket_select_handler* select_handler; + /** * Handler which will be called when the socket is free'd (closed). */ diff --git a/libguac/src/socket.c b/libguac/src/socket.c index cf1aa3e2..138ba8b5 100644 --- a/libguac/src/socket.c +++ b/libguac/src/socket.c @@ -57,13 +57,14 @@ #include "error.h" char __guac_socket_BASE64_CHARACTERS[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/' }; -guac_socket* guac_socket_open(int fd) { +guac_socket* guac_socket_alloc() { guac_socket* socket = malloc(sizeof(guac_socket)); @@ -76,7 +77,7 @@ guac_socket* guac_socket_open(int fd) { socket->__ready = 0; socket->__written = 0; - socket->fd = fd; + socket->data = NULL; /* Allocate instruction buffer */ socket->__instructionbuf_size = 1024; @@ -95,11 +96,33 @@ guac_socket* guac_socket_open(int fd) { socket->__instructionbuf_parse_start = 0; socket->__instructionbuf_elementc = 0; + /* No handlers yet */ + socket->read_handler = NULL; + socket->write_handler = NULL; + socket->select_handler = NULL; + socket->free_handler = NULL; + return socket; } -void guac_socket_close(guac_socket* socket) { +guac_socket* guac_socket_open(int fd) { + + /* Allocate socket and associated data */ + guac_socket* socket = guac_socket_alloc(); + guac_socket_fd_data* data = malloc(sizeof(guac_socket_fd_data)); + + /* Store file descriptor as socket data */ + data->fd = fd; + socket->data = data; + + /* FIXME: Set read/write/free handlers */ + + return socket; + +} + +void guac_socket_free(guac_socket* socket) { guac_socket_flush(socket); free(socket->__instructionbuf); free(socket); @@ -108,14 +131,15 @@ void guac_socket_close(guac_socket* socket) { /* Write bytes, limit rate */ ssize_t __guac_socket_write(guac_socket* socket, const char* buf, int count) { + guac_socket_fd_data* data = (guac_socket_fd_data*) socket->data; int retval; #ifdef __MINGW32__ /* MINGW32 WINSOCK only works with send() */ - retval = send(socket->fd, buf, count, 0); + retval = send(data->fd, buf, count, 0); #else /* Use write() for all other platforms */ - retval = write(socket->fd, buf, count); + retval = write(data->fd, buf, count); #endif /* Record errors in guac_error */