/* libnul * Copyright (C) 2002, 2008 Søren Sandmann (sandmann@daimi.au.dk) * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __LIBNUL_H #define __LIBNUL_H #include #include #include /* These macros come from glib */ /* Provide convenience macros for handling structure * fields through their offsets. */ #if defined(__GNUC__) && __GNUC__ >= 4 # define NUL_STRUCT_OFFSET(struct_type, member) \ ((gssize) __builtin_offsetof (struct_type, member)) #else # define NUL_STRUCT_OFFSET(struct_type, member) \ ((gssize) ((guint8*) &((struct_type*) 0)->member)) #endif #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) #define NUL_GNUC_WARN_UNUSED_RESULT \ __attribute__((warn_unused_result)) #else #define G_GNUC_WARN_UNUSED_RESULT #endif /* __GNUC__ */ #define NUL_COMPILE_TIME_ASSERT(condition,text) \ typedef char nul_error_##text[(condition)? 1 : -1] #define NUL_UR G_GNUC_WARN_UNUSED_RESULT typedef void * nul_ptr_t; typedef void * const nul_const_ptr_t; typedef int nul_bool_t; /* * Generic array implementation */ nul_ptr_t nul_garray_new (int element_size) NUL_UR; nul_ptr_t nul_garray_new_prefix (int element_size, int prefix_size) NUL_UR; nul_ptr_t nul_garray_append (nul_ptr_t array, nul_ptr_t element) NUL_UR; nul_ptr_t nul_garray_remove (nul_ptr_t array, nul_ptr_t element) NUL_UR; nul_ptr_t nul_garray_remove_fast (nul_ptr_t array, nul_ptr_t element) NUL_UR; nul_ptr_t nul_garray_set_size (nul_ptr_t array, gsize n_elements) NUL_UR; gsize nul_garray_len (nul_ptr_t array); /* In number of elements */ void nul_garray_free (nul_ptr_t array); #define nul_array_new(type) _nul_array_new_impl(type) #define nul_array_append(array,value) _nul_array_append_impl(array,value) #define nul_array_remove(array,value) _nul_array_remove_impl(array,value) #define nul_array_remove_fast(array,value) _nul_array_remove_fast_impl(array,value) #define nul_array_len(array) nul_garray_len(array) #define nul_array_free(array) nul_garray_free(array) #define nul_array_set_size(array,size) nul_garray_set_size(array,size); #define nul_prefix_array_new(type,member) \ _nul_prefix_array_new_impl(type,member) #define nul_prefix_array_append(array,member,value) \ _nul_prefix_array_append_impl(array,member,value) #define nul_prefix_array_remove(array,member,value) \ _nul_prefix_array_remove_impl(array,member,value) #define nul_prefix_array_remove_fast(array,member,value) \ _nul_prefix_array_remove_impl(array,member,value) #define nul_prefix_array_len(array,member) \ _nul_prefix_array_len_impl(array,member) #define nul_prefix_array_free(array,member) \ _nul_prefix_array_free_impl(array,member) #define nul_prefix_array_set_size(array,member,size) \ _nul_prefix_array_set_size_impl(array,member,size) /* * Strings */ typedef char nul_string_t; nul_string_t *nul_string_new (void) NUL_UR; void nul_string_free (nul_string_t *str); gsize nul_string_len (const nul_string_t *str); nul_bool_t nul_string_empty (const nul_string_t *str); nul_string_t *nul_string_append_undefined (nul_string_t *string, gsize n_bytes, nul_string_t **tail) NUL_UR; nul_string_t *nul_string_append (nul_string_t *string, const char *bytes, gssize n_bytes) NUL_UR; nul_string_t *nul_string_append_printf (nul_string_t *string, const char *fmt, ...) NUL_UR; nul_string_t *nul_string_append_vprintf (nul_string_t *string, const char *fmt, va_list args) NUL_UR; nul_string_t *nul_string_delete_head (nul_string_t *str, gsize n_bytes) NUL_UR; nul_string_t *nul_string_delete_tail (nul_string_t *str, gsize n_bytes) NUL_UR; /* * Buffers */ typedef struct nul_buffer_t nul_buffer_t; nul_buffer_t * nul_buffer_new (void); char * nul_buffer_free (nul_buffer_t *queue, nul_bool_t free_data); gsize nul_buffer_get_length (nul_buffer_t *queue); nul_bool_t nul_buffer_is_empty (nul_buffer_t *queue); const nul_string_t *nul_buffer_peek (nul_buffer_t *queue, gsize *n_bytes); nul_string_t * nul_buffer_steal (nul_buffer_t *queue, gsize *n_bytes); nul_string_t * nul_buffer_alloc_tail (nul_buffer_t *queue, gsize size); void nul_buffer_append (nul_buffer_t *queue, const char *bytes, gsize n_bytes); void nul_buffer_append_printf (nul_buffer_t *queue, const char *fmt, ...); void nul_buffer_transfer_data (nul_buffer_t *dest, nul_buffer_t *src, gssize n_bytes); void nul_buffer_delete_head (nul_buffer_t *queue, gsize size); void nul_buffer_delete_tail (nul_buffer_t *queue, gsize size); /* * Hash tables */ typedef struct nul_hash_t nul_hash_t; typedef size_t (* nul_hash_func_t) (nul_const_ptr_t key); typedef nul_bool_t (* nul_hash_equal_func_t) (nul_const_ptr_t key1, nul_const_ptr_t key2); typedef void (* nul_free_func_t) (nul_ptr_t data); nul_hash_t *nul_hash_new (nul_hash_func_t hash, nul_hash_equal_func_t equal, nul_free_func_t free_key, nul_free_func_t free_value); void nul_hash_insert (nul_hash_t *hash, nul_ptr_t key, nul_ptr_t value); nul_bool_t nul_hash_remove (nul_hash_t *hash, nul_ptr_t key); nul_ptr_t nul_hash_lookup (nul_hash_t *hash, nul_ptr_t key); nul_bool_t nul_hash_has_key (nul_hash_t *hash, nul_ptr_t key); void nul_hash_free (nul_hash_t *hash); /* * Dynamic function calls */ typedef union { uint32_t v_uint32; int32_t v_int32; uint16_t v_uint16; int16_t v_int16; uint8_t v_uint8; int8_t v_int8; unsigned int v_uint; int v_int; unsigned short v_ushort; short v_short; unsigned char v_uchar; signed char v_schar; char v_char; void * v_pointer; float v_float; double v_double; } nul_arg_t; typedef enum { NUL_TYPE_UINT32, NUL_TYPE_INT32, NUL_TYPE_UINT16, NUL_TYPE_INT16, NUL_TYPE_UINT8, NUL_TYPE_INT8, NUL_TYPE_UINT, NUL_TYPE_INT, NUL_TYPE_USHORT, NUL_TYPE_SHORT, NUL_TYPE_UCHAR, NUL_TYPE_SCHAR, NUL_TYPE_CHAR, NUL_TYPE_POINTER, NUL_TYPE_STRING, NUL_TYPE_DOUBLE, NUL_TYPE_FLOAT, NUL_TYPE_VOID } nul_type_t; typedef void (* nul_function_t)(); typedef struct nul_fun_def_t nul_fun_def_t; nul_fun_def_t *nul_fun_def_new (nul_type_t ret_type, int n_args, nul_type_t *arg_types); nul_arg_t nul_fun_def_invoke (nul_fun_def_t *fun, nul_function_t f, nul_arg_t *args); void nul_fun_def_free (nul_fun_def_t *fun); /* * Polling filedescriptors */ typedef struct nul_poll_t nul_poll_t; typedef enum { NUL_POLL_READ = 1 << 0, NUL_POLL_WRITE = 1 << 1, NUL_POLL_HANGUP = 1 << 2, NUL_POLL_ERROR = 1 << 3, NUL_POLL_PRIORITY = 1 << 4, NUL_POLL_RESERVED = 1 << 5 /* This and higher bits are reserved */ } nul_poll_event_type_t; typedef struct { nul_poll_event_type_t events; int fd; } nul_poll_event_t; nul_poll_t *nul_poll_new (void); void nul_poll_add_fd (nul_poll_t *epoll, int fd, nul_poll_event_type_t mask, gpointer data); void nul_poll_remove_fd (nul_poll_t *epoll, int fd); gpointer nul_poll_get_fd_data (nul_poll_t *epoll, int fd); nul_bool_t nul_poll_has_fd (nul_poll_t *epoll, int fd); void nul_poll_reenable_fd (nul_poll_t *epoll, int fd); gint nul_poll_get_n_fds (nul_poll_t *epoll); nul_poll_event_t * nul_poll_wait (nul_poll_t *epoll, int *n_events, int timeout); /* * Watching file descriptors */ typedef void (* WatchCallback) (gpointer data); void nul_fd_add_watch (int fd, gpointer data); gpointer nul_fd_get_data (int fd); void nul_fd_set_data (int fd, gpointer data); void nul_fd_set_read_callback (int fd, WatchCallback read_cb); void nul_fd_set_write_callback (int fd, WatchCallback write_cb); void nul_fd_set_hangup_callback (int fd, WatchCallback hangup_cb); void nul_fd_set_error_callback (int fd, WatchCallback error_cb); void nul_fd_set_priority_callback (int fd, WatchCallback priority_cb); void nul_fd_set_poll_handler (int fd, WatchCallback poll_handler); void nul_fd_remove_watch (int fd); nul_bool_t nul_fd_is_watched (int fd); /* * File utilities */ char *nul_canonicalize_filename (const char *filename); /* * Random numbers */ void nul_random_set_seed (uint32_t seed); uint32_t nul_random_int (void); int32_t nul_random_int_range (int32_t begin, int32_t end); double nul_random_double (void); double nul_random_double_range (double begin, double end); #define nul_random_boolean() ((nul_random_int () & (1 << 15)) != 0) /* * Unix signal handlers */ typedef void (* signal_func_t) (int signo, gpointer data); /* FIXME: error out is required */ nul_bool_t nul_signal_set_handler (int signo, signal_func_t handler, gpointer data, GError **err); /* Implementing a service */ typedef struct nul_dbus_service_t nul_dbus_service_t; typedef struct nul_dbus_object_t nul_dbus_object_t; typedef struct nul_dbus_member_t nul_dbus_member_t; typedef struct nul_dbus_interface_t nul_dbus_interface_t; typedef struct nul_dbus_type_t nul_dbus_type_t; typedef struct nul_dbus_parameter_t nul_dbus_parameter_t; typedef struct nul_dbus_arg_t nul_dbus_arg_t; /* Return TRUE for handled, FALSE for not handled */ typedef nul_bool_t (* nul_dbus_function_t) (); nul_dbus_service_t * nul_dbus_session_service (const char *name, nul_dbus_object_t *object1, ...); nul_dbus_object_t * nul_dbus_object (const char *name, gpointer data, nul_dbus_interface_t *interface1, ...); nul_dbus_interface_t *nul_dbus_interface (const char *name, nul_dbus_member_t *member1, ...); nul_dbus_member_t * nul_dbus_method (const char *name, nul_dbus_function_t function, nul_dbus_parameter_t *parameter1, ...); nul_dbus_parameter_t *nul_dbus_parameter_in (const char *name, const nul_dbus_type_t *type); nul_dbus_parameter_t *nul_dbus_parameter_out (const char *name, const nul_dbus_type_t *type); nul_bool_t nul_dbus_service_start (nul_dbus_service_t *service); void nul_dbus_service_stop (nul_dbus_service_t *service); void nul_dbus_service_set_object_data (nul_dbus_service_t *service, const char *obj_name, gpointer data); /* The returned values here are automatically freed at idle. You * must copy them if you want to keep them around */ const nul_dbus_type_t * nul_dbus_type_int32 (void); const nul_dbus_type_t * nul_dbus_type_uint32 (void); const nul_dbus_type_t * nul_dbus_type_string (void); /* Using a service */ void nul_dbus_invoke (nul_dbus_service_t *service, const char *method_desc, nul_dbus_function_t callback, gpointer data, ...); /* Elf */ /* * The ELF code is MIT licensed: * * 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 (including the next * paragraph) 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. */ typedef struct elf_sym_t elf_sym_t; typedef struct elf_file_t elf_file_t; elf_file_t * elf_file_new_from_data (const uint8_t *data, size_t length); elf_file_t * elf_file_new (const char *filename, GError **err); void elf_file_free (elf_file_t *parser); const char * elf_file_get_debug_link (elf_file_t *parser, uint32_t *crc32); const char * elf_file_get_build_id (elf_file_t *parser); const uint8_t *elf_file_get_eh_frame (elf_file_t *parser); const uint8_t *elf_file_get_debug_frame (elf_file_t *parser); size_t elf_file_get_text_offset (elf_file_t *parser); /* Lookup a symbol in the file. * * The symbol returned is const, so don't free it. It is valid until * elf_file_free() is called on the elf file. * * The address should be given in "file coordinates". This means that * if the file is mapped at address m and offset o, then an address a * should be looked up as "a - (m - o)". (m - o) is where the start * of the file would have been mapped, so a - (m - o) is the position * in the file of a. */ const elf_sym_t *elf_file_lookup_symbol (elf_file_t *parser, size_t address); uint32_t elf_file_get_crc32 (elf_file_t *parser); const char * elf_file_get_sym_name (elf_file_t *parser, const elf_sym_t *sym); size_t elf_file_get_sym_address (elf_file_t *parser, const elf_sym_t *sym); nul_bool_t elf_file_owns_symbol (elf_file_t *parser, const elf_sym_t *sym); /* Implementation of the array macros */ #define _NUL_TYPE_CHECK_ARRAY(array,value) \ NUL_COMPILE_TIME_ASSERT( \ __builtin_types_compatible_p(typeof (*array),typeof(value)), \ incompatible_types \ ) #define _nul_array_new_impl(type) \ ((type *)nul_garray_new(sizeof(type))) #define _nul_array_append_impl(array,value) \ ({ typeof (value) __nul_temp = value; \ ((typeof (array)) \ nul_garray_append(array, ({ \ _NUL_TYPE_CHECK_ARRAY(array,value); \ &__nul_temp; \ }))); \ }) #define _nul_array_remove_impl(array,value) \ ({ typeof (value) __nul_temp = value; \ ((typeof (array)) \ nul_garray_remove(array, ({ \ _NUL_TYPE_CHECK_ARRAY(array,value); \ &__nul_temp; \ }))); \ }) #define _nul_array_remove_fast_impl(array,value) \ ({ typeof (value) __nul_temp = value; \ ((typeof (array)) \ nul_garray_remove_fast(array, ({ \ _NUL_TYPE_CHECK_ARRAY(array,value); \ &__nul_temp; \ }))); \ }) /* Prefix arrays */ #define _nul_prefix_array_new_impl(type,member) \ ((type *)nul_garray_new_prefix( \ sizeof(((type *)NULL)->member[0]), \ NUL_STRUCT_OFFSET(type,member))) #define _nul_prefix_array_append_impl(array,member,value) \ ({ typeof (value) __nul_temp = (value); \ ((typeof (array)) \ nul_garray_append(array, ({ \ _NUL_TYPE_CHECK_ARRAY(&((array)->member)[0], (value)); \ &__nul_temp; \ }))); \ }) #define _nul_prefix_array_remove_impl(array,member,value) \ ({ typeof (value) __nul_temp = (value); \ ((typeof (array)) \ nul_garray_remove(array, ({ \ _NUL_TYPE_CHECK_ARRAY(&((array)->member)[0], (value)) \ &__nul_temp; \ }))); \ }) #define _nul_prefix_array_remove_fast_impl(array,member,value) \ ({ typeof (value) __nul_temp = (value); \ ((typeof (array)) \ nul_garray_remove_fast(array, ({ \ _NUL_TYPE_CHECK_ARRAY(&((array)->member)[0], (value)) \ &__nul_temp; \ }))); \ }) #define _nul_prefix_array_len_impl(array,member) \ ({ (void)((array)->member); \ nul_garray_len(array); \ }) #define _nul_prefix_array_set_size_impl(array,member,size) \ ({ (void)((array)->member); \ nul_garray_set_size(array,size); \ }) #define _nul_prefix_array_free_impl(array,member) \ ({ (void)((array)->member); \ nul_garray_free(array); \ }) #endif