GUACAMOLE-325: Use select() if poll() is unavailable.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/commit/9dcddd19 Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/tree/9dcddd19 Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/diff/9dcddd19 Branch: refs/heads/master Commit: 9dcddd1947c83d9154f96d15ce2aa1c6c15570c8 Parents: 50d2dd5 Author: Michael Jumper <[email protected]> Authored: Mon Jun 12 13:58:05 2017 -0700 Committer: Michael Jumper <[email protected]> Committed: Wed Jul 5 20:55:02 2017 -0700 ---------------------------------------------------------------------- src/libguac/Makefile.am | 6 ++-- src/libguac/socket-fd.c | 27 +++++----------- src/libguac/socket-ssl.c | 20 ++---------- src/libguac/wait-fd.c | 72 +++++++++++++++++++++++++++++++++++++++++++ src/libguac/wait-fd.h | 41 ++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9dcddd19/src/libguac/Makefile.am ---------------------------------------------------------------------- diff --git a/src/libguac/Makefile.am b/src/libguac/Makefile.am index a1f47ed..35e8e6e 100644 --- a/src/libguac/Makefile.am +++ b/src/libguac/Makefile.am @@ -68,7 +68,8 @@ noinst_HEADERS = \ encode-png.h \ palette.h \ user-handlers.h \ - raw_encoder.h + raw_encoder.h \ + wait-fd.h libguac_la_SOURCES = \ audio.c \ @@ -92,7 +93,8 @@ libguac_la_SOURCES = \ unicode.c \ user.c \ user-handlers.c \ - user-handshake.c + user-handshake.c \ + wait-fd.c # Compile WebP support if available if ENABLE_WEBP http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9dcddd19/src/libguac/socket-fd.c ---------------------------------------------------------------------- diff --git a/src/libguac/socket-fd.c b/src/libguac/socket-fd.c index 0ed5748..f806b87 100644 --- a/src/libguac/socket-fd.c +++ b/src/libguac/socket-fd.c @@ -21,8 +21,8 @@ #include "error.h" #include "socket.h" +#include "wait-fd.h" -#include <poll.h> #include <pthread.h> #include <stddef.h> #include <stdio.h> @@ -31,6 +31,10 @@ #include <sys/time.h> #include <unistd.h> +#ifdef __MINGW32__ +#include <winsock2.h> +#endif + /** * Data associated with an open socket which writes to a file descriptor. */ @@ -330,24 +334,9 @@ static ssize_t guac_socket_fd_write_handler(guac_socket* socket, static int guac_socket_fd_select_handler(guac_socket* socket, int usec_timeout) { + /* Wait for data on socket */ guac_socket_fd_data* data = (guac_socket_fd_data*) socket->data; - - int retval; - - /* Initialize with single underlying file descriptor */ - struct pollfd fds[1] = {{ - .fd = data->fd, - .events = POLLIN, - .revents = 0, - }}; - - /* No timeout if usec_timeout is negative */ - if (usec_timeout < 0) - retval = poll(fds, 1, -1); - - /* Handle timeout if specified, rounding up to poll()'s granularity */ - else - retval = poll(fds, 1, (usec_timeout + 999) / 1000); + int retval = guac_wait_for_fd(data->fd, usec_timeout); /* Properly set guac_error */ if (retval < 0) { @@ -355,7 +344,7 @@ static int guac_socket_fd_select_handler(guac_socket* socket, guac_error_message = "Error while waiting for data on socket"; } - if (retval == 0) { + else if (retval == 0) { guac_error = GUAC_STATUS_TIMEOUT; guac_error_message = "Timeout while waiting for data on socket"; } http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9dcddd19/src/libguac/socket-ssl.c ---------------------------------------------------------------------- diff --git a/src/libguac/socket-ssl.c b/src/libguac/socket-ssl.c index f8f3f87..1a631fe 100644 --- a/src/libguac/socket-ssl.c +++ b/src/libguac/socket-ssl.c @@ -22,8 +22,8 @@ #include "error.h" #include "socket-ssl.h" #include "socket.h" +#include "wait-fd.h" -#include <poll.h> #include <stdlib.h> #include <openssl/ssl.h> @@ -69,23 +69,7 @@ static ssize_t __guac_socket_ssl_write_handler(guac_socket* socket, static int __guac_socket_ssl_select_handler(guac_socket* socket, int usec_timeout) { guac_socket_ssl_data* data = (guac_socket_ssl_data*) socket->data; - - int retval; - - /* Initialize with single underlying file descriptor */ - struct pollfd fds[1] = {{ - .fd = data->fd, - .events = POLLIN, - .revents = 0, - }}; - - /* No timeout if usec_timeout is negative */ - if (usec_timeout < 0) - retval = poll(fds, 1, -1); - - /* Handle timeout if specified, rounding up to poll()'s granularity */ - else - retval = poll(fds, 1, (usec_timeout + 999) / 1000); + int retval = guac_wait_for_fd(data->fd, usec_timeout); /* Properly set guac_error */ if (retval < 0) { http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9dcddd19/src/libguac/wait-fd.c ---------------------------------------------------------------------- diff --git a/src/libguac/wait-fd.c b/src/libguac/wait-fd.c new file mode 100644 index 0000000..0523e62 --- /dev/null +++ b/src/libguac/wait-fd.c @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "config.h" + +#ifdef __MINGW32__ +# include <winsock2.h> +#else +# ifdef HAVE_POLL +# include <poll.h> +# else +# include <sys/select.h> +# endif +#endif + +#ifdef HAVE_POLL +int guac_wait_for_fd(int fd, int usec_timeout) { + + /* Initialize with single underlying file descriptor */ + struct pollfd fds[1] = {{ + .fd = fd, + .events = POLLIN, + .revents = 0 + }}; + + /* No timeout if usec_timeout is negative */ + if (usec_timeout < 0) + return poll(fds, 1, -1); + + /* Handle timeout if specified, rounding up to poll()'s granularity */ + return poll(fds, 1, (usec_timeout + 999) / 1000); + +} +#else +int guac_wait_for_fd(int fd, int usec_timeout) { + + fd_set fds; + + /* Initialize fd_set with single underlying file descriptor */ + FD_ZERO(&fds); + FD_SET(fd, &fds); + + /* No timeout if usec_timeout is negative */ + if (usec_timeout < 0) + return select(fd + 1, &fds, NULL, NULL, NULL); + + /* Handle timeout if specified */ + struct timeval timeout = { + .tv_sec = usec_timeout / 1000000, + .tv_usec = usec_timeout % 1000000 + }; + + return select(fd + 1, &fds, NULL, NULL, &timeout); + +} +#endif http://git-wip-us.apache.org/repos/asf/incubator-guacamole-server/blob/9dcddd19/src/libguac/wait-fd.h ---------------------------------------------------------------------- diff --git a/src/libguac/wait-fd.h b/src/libguac/wait-fd.h new file mode 100644 index 0000000..b5e2e5f --- /dev/null +++ b/src/libguac/wait-fd.h @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef GUAC_WAIT_FD_H +#define GUAC_WAIT_FD_H + +/** + * Waits for data to be available for reading on a given file descriptor, + * similar to the POSIX select() and poll() functions. + * + * @param fd + * The file descriptor to wait for. + * + * @param usec_timeout + * The maximum number of microseconds to wait for data, or -1 to + * potentially wait forever. + * + * @return + * Positive if data is available for reading, zero if the timeout elapsed + * and no data is available, negative if an error occurs, in which case + * errno will also be set. + */ +int guac_wait_for_fd(int fd, int usec_timeout); + +#endif
