From da3bef21191315d5cd3fe15aa1ac5372a93c5af2 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 6 Jan 2014 15:53:22 -0800 Subject: [PATCH] Add common utility sources. --- Makefile.am | 1 + configure.ac | 1 + src/common/Makefile.am | 36 ++++++++++++ src/common/io.c | 71 +++++++++++++++++++++++ src/common/io.h | 53 +++++++++++++++++ src/common/list.c | 82 +++++++++++++++++++++++++++ src/common/list.h | 125 +++++++++++++++++++++++++++++++++++++++++ 7 files changed, 369 insertions(+) create mode 100644 src/common/Makefile.am create mode 100644 src/common/io.c create mode 100644 src/common/io.h create mode 100644 src/common/list.c create mode 100644 src/common/list.h diff --git a/Makefile.am b/Makefile.am index 5136a121..b7f274b3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,6 +32,7 @@ DIST_SUBDIRS = \ tests SUBDIRS = \ + src/common \ src/libguac \ src/guacd \ tests diff --git a/configure.ac b/configure.ac index 41f3f3b1..450a38b2 100644 --- a/configure.ac +++ b/configure.ac @@ -596,6 +596,7 @@ AM_CONDITIONAL([ENABLE_SSH_AGENT], AC_CONFIG_FILES([Makefile tests/Makefile + src/common/Makefile src/libguac/Makefile src/guacd/Makefile src/protocols/rdp/Makefile diff --git a/src/common/Makefile.am b/src/common/Makefile.am new file mode 100644 index 00000000..5a6cefd4 --- /dev/null +++ b/src/common/Makefile.am @@ -0,0 +1,36 @@ +# +# Copyright (C) 2013 Glyptodon LLC +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +AUTOMAKE_OPTIONS = foreign +ACLOCAL_AMFLAGS = -I m4 +AM_CFLAGS = -Werror -Wall -pedantic + +noinst_LTLIBRARIES = libguac_common.la + +noinst_HEADERS = \ + io.h \ + list.h + +libguac_common_la_SOURCES = \ + io.c \ + list.c + diff --git a/src/common/io.c b/src/common/io.c new file mode 100644 index 00000000..3efeee7a --- /dev/null +++ b/src/common/io.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2013 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "config.h" +#include "io.h" + +#include + +int guac_common_write(int fd, void* buffer, int length) { + + unsigned char* bytes = (unsigned char*) buffer; + + while (length > 0) { + + /* Attempt write */ + int bytes_written = write(fd, bytes, length); + if (bytes_written < 0) + return bytes_written; + + /* Update buffer */ + length -= bytes_written; + bytes += bytes_written; + + } + + /* Success */ + return length; + +} + +int guac_common_read(int fd, void* buffer, int length) { + + unsigned char* bytes = (unsigned char*) buffer; + + while (length > 0) { + + /* Attempt read */ + int bytes_read = read(fd, bytes, length); + if (bytes_read < 0) + return bytes_read; + + /* Update buffer */ + length -= bytes_read; + bytes += bytes_read; + + } + + /* Success */ + return length; + +} + diff --git a/src/common/io.h b/src/common/io.h new file mode 100644 index 00000000..fc8269e8 --- /dev/null +++ b/src/common/io.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __GUAC_COMMON_IO_H +#define __GUAC_COMMON_IO_H + +#include "config.h" + +/** + * Writes absolutely all bytes from within the given buffer, returning an error + * only if the required writes fail. + * + * @param fd The file descriptor to write to. + * @param buffer The buffer containing the data to write. + * @param length The number of bytes to write. + * @return The number of bytes written, or a value less than zero if an error + * occurs. + */ +int guac_common_write(int fd, void* buffer, int length); + +/** + * Reads enough bytes to fill the given buffer, returning an error only if the + * required reads fail. + * + * @param fd The file descriptor to read from. + * @param buffer The buffer to read data into. + * @param length The number of bytes to read. + * @return The number of bytes read, or a value less than zero if an error + * occurs. + */ +int guac_common_read(int fd, void* buffer, int length); + +#endif + diff --git a/src/common/list.c b/src/common/list.c new file mode 100644 index 00000000..7060f5e7 --- /dev/null +++ b/src/common/list.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2013 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "config.h" +#include "list.h" + +#include +#include + +guac_common_list* guac_common_list_alloc() { + + guac_common_list* list = malloc(sizeof(guac_common_list)); + + pthread_mutex_init(&list->_lock, NULL); + list->head = NULL; + + return list; + +} + +void guac_common_list_free(guac_common_list* list) { + free(list); +} + +guac_common_list_element* guac_common_list_add(guac_common_list* list, + void* data) { + + /* Allocate element, initialize as new head */ + guac_common_list_element* element = + malloc(sizeof(guac_common_list_element)); + element->data = data; + element->next = list->head; + element->_ptr = &(list->head); + + /* If head already existed, point it at this element */ + if (list->head != NULL) + list->head->_ptr = &(element->next); + + /* Set as new head */ + list->head = element; + return element; + +} + +void guac_common_list_remove(guac_common_list* list, + guac_common_list_element* element) { + + /* Point previous (or head) to next */ + *(element->_ptr) = element->next; + element->next->_ptr = element->_ptr; + + free(element); + +} + +void guac_common_list_lock(guac_common_list* list) { + pthread_mutex_lock(&list->_lock); +} + +void guac_common_list_unlock(guac_common_list* list) { + pthread_mutex_unlock(&list->_lock); +} + diff --git a/src/common/list.h b/src/common/list.h new file mode 100644 index 00000000..5075a8b8 --- /dev/null +++ b/src/common/list.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2013 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __GUAC_LIST_H +#define __GUAC_LIST_H + +#include "config.h" + +#include + +/** + * Generic linked list element. + */ +typedef struct guac_common_list_element guac_common_list_element; + +struct guac_common_list_element { + + /** + * The next element in the list, or NULL if none. + */ + guac_common_list_element* next; + + /** + * Generic data. + */ + void* data; + + /** + * The pointer which points to this element, whether another element's + * next pointer, or the entire list's head pointer. + */ + guac_common_list_element** _ptr; + +}; + +/** + * Generic linked list. + */ +typedef struct guac_common_list { + + /** + * The first element in the list. + */ + guac_common_list_element* head; + + /** + * Mutex which is locked when exclusive access to the list is required. + * Possession of the lock is not enforced outside the + * guac_common_list_lock() function. + */ + pthread_mutex_t _lock; + +} guac_common_list; + +/** + * Creates a new list. + * + * @return A newly-allocated list. + */ +guac_common_list* guac_common_list_alloc(); + +/** + * Frees the given list. + * + * @param list The list to free. + */ +void guac_common_list_free(guac_common_list* list); + +/** + * Adds the given data to the list as a new element, returning the created + * element. + * + * @param list The list to add an element to. + * @param data The data to associate with the newly-created element. + * @param The newly-created element. + */ +guac_common_list_element* guac_common_list_add(guac_common_list* list, + void* data); + +/** + * Removes the given element from the list. + * + * @param list The list to remove the element from. + * @param element The element to remove. + */ +void guac_common_list_remove(guac_common_list* list, + guac_common_list_element* element); + +/** + * Acquires exclusive access to the list. No list functions implicitly lock or + * unlock the list, so any list access which must be threadsafe must use + * guac_common_list_lock() and guac_common_list_unlock() manually. + * + * @param list The list to acquire exclusive access to. + */ +void guac_common_list_lock(guac_common_list* list); + +/** + * Releases exclusive access to the list. + * + * @param list The list to release from exclusive access. + */ +void guac_common_list_unlock(guac_common_list* list); + +#endif +