From a0e5a4fac8ae77288c6a49f2ae4b8503b38adc0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sat, 28 Jun 2014 01:53:29 +0200 Subject: [PATCH 01/49] Initial cmd.. --- include/ucore/cmd/cmd.h | 48 +++++++++++++++++++++++++++++++++++++++++ src/cmd/cmd.c | 17 +++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 include/ucore/cmd/cmd.h create mode 100644 src/cmd/cmd.c diff --git a/include/ucore/cmd/cmd.h b/include/ucore/cmd/cmd.h new file mode 100644 index 0000000..8c9880a --- /dev/null +++ b/include/ucore/cmd/cmd.h @@ -0,0 +1,48 @@ +#ifndef UC_CMD_H_ +#define UC_CMD_H_ + +#include + +enum UCCmdResult { + UC_CMDRES_OK, + UC_CMDRES_WARN, + UC_CMDRES_ERR +}; + +struct UCCmdDef; +struct UCVTerm; +typedef enum UCCmdResult (*uc_cmd_handler)(struct UCCmd *cmd, struct UCVTerm *term, int arg, char *argv[]); + +struct UCCmdDef { + uint32_t cmd_id; + uint32_t cmd_flags; + const char *cmd_syntax; + const char *cmd_desc; + uc_cmd_handler cmd_cb; +}; + + +#define UC_DEF_CMD_DEF(id, flags, syntax, desc)\ +static const struct UCCmdDef uc_cmd_def ## cmd_id {\ + .cmd_id = cmd_id,\ + .cmd_flags = flags,\ + .cmd_syntax = syntax,\ + .cmd_desc = desc,\ +}; + +#define UC_DEF_CMD_FUNC(id)\ +static enum UCCmdResult uc_cmd_func_ ## id (struct UCCmd *cmd, struct UCVTerm *term, int nargs, char *args[]) + +#define UC_DEF_CMD(id, flags, syntax, desc)\ + UC_DEF_CMD_DEF(id, flags, syntax, desc)\ + UC_DEF_CMD_FUNC(id) + +UC_DEF_CMD(111, 0 , +"show peers", +"Show all connected peers") +{ + +} + +#endif +/ diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c new file mode 100644 index 0000000..3bf0cf4 --- /dev/null +++ b/src/cmd/cmd.c @@ -0,0 +1,17 @@ +#include + +enum UCCmdNodeType { + UC_CMDNODE_ROOT, + UC_CMDNODE_KEYWORD, + UC_CMD-zzzzzzzzzzzzzzzz + +}; + + +struct UCCmdNode { + enum UCCmdNodeType type; + uint32_t flags; + void *param; + struct UCCmdNode *next; + struct UCCmdNode *child; +}; From 7e8c59699ac3b39bf1ef2ed219baaf38a10d2a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 26 Aug 2014 20:12:22 +0200 Subject: [PATCH 02/49] Fix confusing if vec_len is bytes or number of elements --- src/bitvec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bitvec.c b/src/bitvec.c index edb6cc3..8286d36 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -1,4 +1,5 @@ #include +#include #include #include #include "ucore/bitvec.h" @@ -68,6 +69,7 @@ void uc_bv_set_bits_from_array(struct UCBitVec *v,char *array,size_t array_len) for (i = 0; i < array_len; i++) { size_t idx = (size_t)bit_index(array_len); + if (unlikely(idx >= v->vec_len)) break; From e45a4d5643b52ac4c29def842731c31e30264535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 26 Aug 2014 21:38:09 +0200 Subject: [PATCH 03/49] Improve doxygen documentation. --- Doxyfile | 14 +++--- include/ucore/atomic.h | 3 +- include/ucore/bitvec.h | 17 ++++--- include/ucore/dbuf.h | 21 +++++---- include/ucore/dstr.h | 9 ++-- include/ucore/heapsort.h | 10 ++-- include/ucore/htable.h | 3 +- include/ucore/iomux_waker.h | 7 ++- include/ucore/logging.h | 3 +- include/ucore/mbuf.h | 63 ++++++++++++++----------- include/ucore/mersenne_twister.h | 2 +- include/ucore/pack.h | 3 +- include/ucore/rate_limit.h | 3 +- include/ucore/salloc.h | 3 +- include/ucore/saturating_math.h | 3 +- include/ucore/threadqueue.h | 81 ++++++++++++++++---------------- include/ucore/val_str.h | 6 +++ 17 files changed, 143 insertions(+), 108 deletions(-) diff --git a/Doxyfile b/Doxyfile index 2f3d864..fc825f1 100644 --- a/Doxyfile +++ b/Doxyfile @@ -61,7 +61,7 @@ OUTPUT_DIRECTORY = doc # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. -CREATE_SUBDIRS = YES +CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this @@ -106,7 +106,7 @@ ABBREVIATE_BRIEF = # Doxygen will generate a detailed section even if there is only a brief # description. -ALWAYS_DETAILED_SEC = NO +ALWAYS_DETAILED_SEC = YES # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those @@ -119,7 +119,7 @@ INLINE_INHERITED_MEMB = NO # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. -FULL_PATH_NAMES = NO +FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is @@ -128,7 +128,7 @@ FULL_PATH_NAMES = NO # If left blank the directory from which doxygen is run is used as the # path to strip. -STRIP_FROM_PATH = +STRIP_FROM_PATH = include # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells @@ -137,7 +137,7 @@ STRIP_FROM_PATH = # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = include # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system @@ -790,7 +790,7 @@ INLINE_SOURCES = NO # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. -STRIP_CODE_COMMENTS = YES +STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented @@ -1130,7 +1130,7 @@ GENERATE_TREEVIEW = YES # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. -ENUM_VALUES_PER_LINE = 4 +ENUM_VALUES_PER_LINE = 1 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree diff --git a/include/ucore/atomic.h b/include/ucore/atomic.h index bc105b9..84e34d5 100644 --- a/include/ucore/atomic.h +++ b/include/ucore/atomic.h @@ -1,7 +1,8 @@ #ifndef UC_ATOMIC_H_ #define UC_ATOMIC_H_ -/** Atomic functions (macros). The ptr argument must be a pointer to +/** @file + * Atomic functions (macros). The ptr argument must be a pointer to * an integer type. * For gcc, see http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/_005f_005fsync-Builtins.html */ diff --git a/include/ucore/bitvec.h b/include/ucore/bitvec.h index 06085b8..a3e224b 100644 --- a/include/ucore/bitvec.h +++ b/include/ucore/bitvec.h @@ -13,19 +13,22 @@ typedef unsigned long uc_bv_integer; struct UCBitVec { //storage for the bits uc_bv_integer *vec; - //length in bytes of the above vec. + //number of elements int the above vec. size_t vec_len; }; /** - * Evaluates the length required for a bitvec to store nbit bits. + * Evaluates the number of uc_bv_integer elements required for a bitvec to store nbit bits. */ #define UC_BV_LEN(nbits) ((nbits/(sizeof(uc_bv_integer)*CHAR_BIT)) + (nbits % (sizeof(uc_bv_integer)*CHAR_BIT) == 0 ? 0 : 1)) -/** - * Use as : +/** Initialize a bitvec with predefined backing array. + * The backing array element type must be uc_bv_integer + * Use as + * @code * uc_bv_integer v[10]; * struct UCBitVec v = BITVEC_STATIC_INIT(v); + * @endcode */ #define UC_BV_STATIC_INIT(vec_data)\ {\ @@ -47,13 +50,13 @@ void uc_bv_free(struct UCBitVec *v); //Note that accessing a bit beyond the nbits originally initialized //for the given bitvec is undedefined -/** Sets bit no. b */ +/** Sets bit number b */ void uc_bv_set_bit(struct UCBitVec *v,int b); -/** Clears bit no. b*/ +/** Clears bit number b*/ void uc_bv_clr_bit(struct UCBitVec *v,int b); -/** Gets the current value (0 or 1) of bit no. b*/ +/** Gets the current value (0 or 1) of bit number @b*/ int uc_bv_get_bit(const struct UCBitVec *v,int b); /** Sets all bits to zero */ diff --git a/include/ucore/dbuf.h b/include/ucore/dbuf.h index 4dc497c..8b39d30 100644 --- a/include/ucore/dbuf.h +++ b/include/ucore/dbuf.h @@ -6,37 +6,38 @@ extern "C" { #endif -/** +/** @file * dbuf is a generic buffer that will grow automatically. - * call buf_ensure() to reserve space, and don't write more data - * than you told buf_ensure() to reserve. + * call uc_buf_ensure() to reserve space, and don't write more data + * than you told uc_buf_ensure() to reserve. * * You write data to buf->end * When finished writing data * you call dbuf_added/( with the no. of bytes you've added. * - * You read data from buf->start, the buffer has dbuf_len() bytes of data - * When you've read and processed the data, call dbuf_take() + * You read data from buf->start, the buffer has uc_dbuf_len() bytes of data + * When you've read and processed the data, call uc_dbuf_take() * to indicate you're done with the data. * * typically(but add error checking) * @code * DBuf buf; - * dbuf_init(&buf,4096); + * uc_dbuf_init(&buf,4096); * for(;;) { - * dbuf_ensure(buf,4096); + * uc_dbuf_ensure(buf,4096); * size_t len = fread(buf,4096,1,f); - * dbuf_added(&buf,len); + * uc_dbuf_added(&buf,len); * char *end; - * while((end = memchr(buf.start,'\n',dbuf_len(&dbuf))) != NULL) { //look for a newline + * while((end = memchr(buf.start,'\n',uc_dbuf_len(&dbuf))) != NULL) { //look for a newline * ++end; * int linelen = end - buf.start; * process_line(buf.start,linelen); - * dbuf_take(&dbuf,linelen); + * uc_dbuf_take(&dbuf,linelen); * } * } * @endcode */ + typedef struct DBuf DBuf; struct DBuf { /** Start of user data */ diff --git a/include/ucore/dstr.h b/include/ucore/dstr.h index 2057fc6..1ee79ee 100644 --- a/include/ucore/dstr.h +++ b/include/ucore/dstr.h @@ -8,7 +8,7 @@ extern "C" { #endif -/** A managed C-string, using dynalically allocated memory for the string. +/** A managed C-string, using dynamically allocated memory for the string. * * The .str member might not always be nul terminated, * Normally, use uc_dstr_str() to retreive the managed string @@ -52,8 +52,11 @@ int uc_dstr_init_str_sz(struct DStr *str, const char *init, size_t len); */ void uc_dstr_destroy(struct DStr *str); -/** Copy a DStr - * +/** Copy a DStr. + * The @dest string should not be an initialized string since it will be + * initialized by uc_dstr_copy, and would cause a memory leak if it's already + * initialized. + * * @param dest destination string to copy to, must not contain an existing string * @param src DStr to copy * diff --git a/include/ucore/heapsort.h b/include/ucore/heapsort.h index fcaf426..fc18ead 100644 --- a/include/ucore/heapsort.h +++ b/include/ucore/heapsort.h @@ -6,13 +6,17 @@ #ifdef __cplusplus extern "C" { #endif -///compare function. Needs only to return < 0 if -//a is less tan b +/** Compare function. Needs only to return < 0 if +* a is less than b +*/ typedef int (*uc_hs_cmp)(const void *a, const void *b, void *cookie); -//swap function, must swap around element a and b +/** Swap function, Must swap around element a and b + */ typedef void (*uc_hs_swp)(void *a, void *b); /** Sort an array. + * As the name implies this sorts using the heapsort algorithm. + * * @param base start of array * @param count number of elements in array * @param width size of each element diff --git a/include/ucore/htable.h b/include/ucore/htable.h index 1702c5f..46e4168 100644 --- a/include/ucore/htable.h +++ b/include/ucore/htable.h @@ -3,7 +3,8 @@ #include -/** Building block for hash table. +/** @file + * Building block for hash table. * The hash table is stored using a chained list of buckets. * Nodes with different hash value can be stored in the same bucket. * diff --git a/include/ucore/iomux_waker.h b/include/ucore/iomux_waker.h index bf382e2..fa76048 100644 --- a/include/ucore/iomux_waker.h +++ b/include/ucore/iomux_waker.h @@ -15,16 +15,19 @@ struct IOMuxSignaller { int fd; }; -/** These are primitives to wake up an IOMux. +/** @file + * These are primitives to wake up an IOMux. * An IOMux event loop can be woken up from e.g. an unix signal handler * or another thread. The IOMuxWaker itself is not thread safe, it's members - * must not be accessed from anything other than the loop it's connected to. + * except for the signaller must not be accessed from anything other than the + * IOMux it's connected to. * Only uc_iomux_waker_signal() can be called from another thread/signal handler * than the IOMux it's connected to. * * Note that several signals to wake up a loop can get merged, the callback * handler can be called only once for several signals. */ + struct IOMuxWaker { //private fields struct IOMuxFD read_fd; diff --git a/include/ucore/logging.h b/include/ucore/logging.h index 3c19f7d..37234dd 100644 --- a/include/ucore/logging.h +++ b/include/ucore/logging.h @@ -2,7 +2,8 @@ #define UC_LOGGING_H_ #include "utils.h" -/** Logging functions. +/** @file + * Application logging framework. * All logging functions except uc_log_init are thread safe, * so logging can be performed from any thread after the logging * system have been initialized. diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 3972798..27cc959 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -16,6 +16,41 @@ #endif #endif +/** @file + * mbuf - A managed message/memory buffer. + * + * Concept: + @verbatim + <--------- allocated -----------> + <--- len --> + +--------------------------------+ + |Headroom| Data |Tailroom | + +--------------------------------+ + ^ ^ ^ + | | | + | | tail + | head + bufstart + + @endverbatim + * + * Initially when empty, head == tail, and the length is 0. + * Data is added to the tail. + * + * If head == bufstart, there is no headroom + * if tail points one past the allocated space, there is no + * tailroom (the buffer is full) + * + * Conventions: + * push - prepend data to the buffer (in the head room part) + * (move head to the left) + * pull - remove data from the beginning of the message. + * (move head to the right) + * put - Add data to the buffer. + * (move tail to the right) + */ + +/** Flags used internally */ enum UC_MBUF_FLAGS { UC_MBUF_FL_MALLOC = 0x0001, //MBuf and MBuf->bufstart are seperatly malloc'd UC_MBUF_FL_MALLOC_BUF = 0x0001, //MBuf is not malloc'd. MBuf->bufstart is malloc'd @@ -51,34 +86,6 @@ struct MBuf { uint8_t inline_data[0]; }; -/** - * Concept: - * <--------- allocated -----------> - * <--- len --> - * +--------------------------------+ - * |Headroom| Data |Tailroom | - * +--------------------------------+ - * ^ ^ ^ - * | | | - * | | tail - * | head - * bufstart - * - * Initially when empty, head == tail, and the length is 0. - * Data is added to the tail. - * - * If head == bufstart, there is no headroom - * if tail points one past the allocated space, there is no - * tailroom (the buffer is full) - * - * Conventions: - * push - prepend data to the buffer (in the head room part) - * (move head to the left) - * pull - remove data from the beginning of the message. - * (move head to the right) - * put - Add data to the buffer. - * (move tail to the right) - */ /** Allocate an mbuf with a length and headroom, * the buffer will have the flag UC_MBUF_FL_MALLOC diff --git a/include/ucore/mersenne_twister.h b/include/ucore/mersenne_twister.h index b2604e1..748d097 100644 --- a/include/ucore/mersenne_twister.h +++ b/include/ucore/mersenne_twister.h @@ -5,8 +5,8 @@ extern "C" { #endif -/** Context used for the PRNG*/ #define MT_RAND_N 624 +/** Context used for the PRNG*/ typedef struct { unsigned int x[MT_RAND_N]; int i; diff --git a/include/ucore/pack.h b/include/ucore/pack.h index 9160e01..6553b7e 100644 --- a/include/ucore/pack.h +++ b/include/ucore/pack.h @@ -15,7 +15,8 @@ #endif #endif -/** Functions for serializing/de-serializing integers to and from +/** @file + * Functions for serializing/de-serializing integers to and from * byte arrays. * These functions are independant of the host endian. Only * thing to care about is the endian format of the data in diff --git a/include/ucore/rate_limit.h b/include/ucore/rate_limit.h index 367aae9..fdcb656 100644 --- a/include/ucore/rate_limit.h +++ b/include/ucore/rate_limit.h @@ -1,7 +1,8 @@ #ifndef UC_RATE_LIMIT_H_ #define UC_RATE_LIMIT_H_ -/** This is a rate limiter, based on the token bucket principle. +/** @file + * This is a rate limiter, based on the token bucket principle. * We have X amount of tickets(=our rate) per Y amount of time, * * The allowed tickets increases with X per Y amount of time. diff --git a/include/ucore/salloc.h b/include/ucore/salloc.h index d9f5d44..ca336d3 100644 --- a/include/ucore/salloc.h +++ b/include/ucore/salloc.h @@ -6,7 +6,8 @@ #ifdef __cplusplus extern "C" { #endif -/** Sequntial memory allocator +/** @file + * Sequntial memory allocator * * Allocates bigger chunks of memory at a time, to save the amount of malloc call, * and enables you to free all that memory in one sweep. diff --git a/include/ucore/saturating_math.h b/include/ucore/saturating_math.h index 4ef5ff0..6b9228f 100644 --- a/include/ucore/saturating_math.h +++ b/include/ucore/saturating_math.h @@ -2,7 +2,8 @@ #define UC_SATMATH_H_ #include -/** Implementation of saturated operation on uintxx_t. +/** @file + * Implementation of saturated operation on uintxx_t. * * Operations are clamped between 0 and UINTxx_MAX instead of * wrapping around. diff --git a/include/ucore/threadqueue.h b/include/ucore/threadqueue.h index dd189d1..eacf9ab 100644 --- a/include/ucore/threadqueue.h +++ b/include/ucore/threadqueue.h @@ -12,7 +12,47 @@ extern "C" { * * Little API for waitable queues, typically used for passing messages * between threads. + * + * The uc_thread_queue_ functions only deal with struct uc_threadmsg + * structs. + * In order for the message passing to be useful, more data needs to be + * associated with a message, it's up to the application to manage this. + * One way is to e.g. add the struct uc_threadmsg as the first member + * of a larger struct, and recover the larger struct after getting a + * struct uc_threadmsg out of the queue. e.g. + * + * @code + * struct my_msg { + * struct uc_threadmsg tmsg; + * int foo; + * char bar[32]; + * }; + * + * struct my_msg *msg = malloc(sizeof *msg); + * msg->tmsg.msgtype = MSGTYP1; + * ... + * uc_thread_queue_add(queue, &msg->tmsg); + * + * The receiver end does e.g. + * + * struct uc_threadmsg *tmsg; + * uc_thread_queue_get(queue, NULL, &tmsg); + * switch(tmsg->msgtype) { + * case MYMSG1; { + * struct my_msg *msg = (struct my_msg*)tmsg; + * ... + * free(msg); + * break + * ... + * } + * } + * + * @endcode + * + * As such, a struct uc_threadmsg must live as long as it resides in a thread queue, + * and must be removed from the queue before the struct uc_threadmsg is destroyed/deallocated. * + * * @author Nils O. Selåsdal */ @@ -55,45 +95,6 @@ typedef void (*uc_thread_queue_walk_func) (struct uc_threadmsg *msg, void *cooki * the variables in this struct. * You have been warned. * - * The uc_thread_queue_ functions only deal with struct uc_threadmsg - * structs. - * In order for the message passing to be useful, more data needs to be - * associated with a message, it's up to the application to manage this. - * One way is to e.g. add the struct uc_threadmsg as the first member - * of a larger struct, and recover the larger struct after getting a - * struct uc_threadmsg out of the queue. e.g. - * - * @code - * struct my_msg { - * struct uc_threadmsg tmsg; - * int foo; - * char bar[32]; - * }; - * - * struct my_msg *msg = malloc(sizeof *msg); - * msg->tmsg.msgtype = MSGTYP1; - * ... - * uc_thread_queue_add(queue, &msg->tmsg); - * - * The receiver end does e.g. - * - * struct uc_threadmsg *tmsg; - * uc_thread_queue_get(queue, NULL, &tmsg); - * switch(tmsg->msgtype) { - * case MYMSG1; { - * struct my_msg *msg = (struct my_msg*)tmsg; - * ... - * free(msg); - * break - * ... - * } - * } - * - * @endcode - * - * - * - * */ struct uc_threadqueue { /** @@ -137,7 +138,7 @@ struct uc_threadqueue { * thread_queue_init initializes a new threadqueue. A new queue must always * be initialized before it is used. * A max number of elements the queue will hold must be given. - * Adding more elements than a queue will hold will e.g. cause + * Adding more elements than a queue will hold will cause * uc_thread_queue_add to block until space becomes available. * * @param queue Pointer to the queue that should be initialized diff --git a/include/ucore/val_str.h b/include/ucore/val_str.h index 9ee6cae..a724439 100644 --- a/include/ucore/val_str.h +++ b/include/ucore/val_str.h @@ -3,11 +3,17 @@ #include +/** @file + * Utility functions to map integers to strings and strings to strings. + */ + +/** Mapping from an unsigned int to a string*/ struct UCValStr { unsigned int val; const char *str; }; +/** Mapping from a string to another string*/ struct UCStrStr { const char *val; const char *str; From b446022e6d95da02a670dee5d0ff41b956a20434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 8 Sep 2014 22:24:08 +0200 Subject: [PATCH 04/49] Fix RATE_LIMIT_INITIALIZER --- include/ucore/rate_limit.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ucore/rate_limit.h b/include/ucore/rate_limit.h index 367aae9..748bef3 100644 --- a/include/ucore/rate_limit.h +++ b/include/ucore/rate_limit.h @@ -70,8 +70,8 @@ struct RateLimit { * @param tickets number of tickets (bucket depth) * @param period per this period */ -#define UC_RATELIMIT_INITIALIZER(tickets)\ -{ tickets, period, 0, -period} +#define UC_RATELIMIT_INITIALIZER(tickets, period)\ +{ (tickets,) (period), 0, -(period)} From 045d7c2463537129f40f3d99f406c537904e3b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 15 Sep 2014 21:13:43 +0200 Subject: [PATCH 05/49] Improve doxygen comments --- include/ucore/dstr.h | 21 ++++++++++++++------- include/ucore/strvec.h | 3 ++- include/ucore/timers.h | 2 +- test/test_dstr.c | 2 +- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/ucore/dstr.h b/include/ucore/dstr.h index 1ee79ee..c1295a6 100644 --- a/include/ucore/dstr.h +++ b/include/ucore/dstr.h @@ -8,16 +8,22 @@ extern "C" { #endif -/** A managed C-string, using dynamically allocated memory for the string. +/**@file + * A managed C-string, using dynamically allocated memory for the string. * - * The .str member might not always be nul terminated, - * Normally, use uc_dstr_str() to retreive the managed string - * instead of accessing ->str directly. + * The .str member might not always be nul terminated, and should not be + * accessed directly. Instead use uc_dstr_str() to retreive the managed string + * which will always ensure the string is nul terminated * - * Normally, let the DSTR manage the nul terminator as manually adding + * Normally, let the DSTR manage the nul terminator as manually adding * a nul byte and potintially adding more data to the DStr would append * it after that nul terminator. */ + +/** Dynamic string struct. The user is responsible for managing + * the struct Dstr memory, and the uc_dstr_ functions will manage + * the memory held in .str. + */ struct DStr { /** Length of the managed string.*/ size_t len; @@ -27,10 +33,11 @@ struct DStr { char *str; }; -#define UC_DSTR_STATIC_INIT {0, 0, NULL} +#define UC_DSTR_INITIALIZER {0, 0, NULL} /** Initialize a DStr. * Note that str->str will be NULL after initialization. + * (However uc_dstr_str() will return a valid (empty) string. * */ void uc_dstr_init(struct DStr *str); @@ -94,7 +101,7 @@ void uc_dstr_terminate(struct DStr *str); char *uc_dstr_str(struct DStr *str); /** Reserve len bytes for appending to the dstr - * you must fill in a string in the 0-len range of + * you must copy characters to all bytes in the [0-len) range of * the returned pointer. * * @param len bytes to reseve diff --git a/include/ucore/strvec.h b/include/ucore/strvec.h index f4be722..4bbe887 100644 --- a/include/ucore/strvec.h +++ b/include/ucore/strvec.h @@ -82,7 +82,8 @@ void uc_strv_clear(struct UCStrv *strv); /** * free all elements as well as the underlying array, the UCStrv is - * unusable after this call + * unusable after this call until it is initialized again. + * (strv itself is not free'd) * * @param strv UCStrv to destroy */ diff --git a/include/ucore/timers.h b/include/ucore/timers.h index c202cb0..ecdd2e0 100644 --- a/include/ucore/timers.h +++ b/include/ucore/timers.h @@ -152,5 +152,5 @@ int uc_timers_run(struct UCTimers *timers); } #endif -/** @{ (addtogroup) */ +/** @} (addtogroup) */ #endif diff --git a/test/test_dstr.c b/test/test_dstr.c index ff9cc33..f30a0a4 100644 --- a/test/test_dstr.c +++ b/test/test_dstr.c @@ -85,7 +85,7 @@ START_TEST (test_dstr_own_steal) END_TEST START_TEST (test_dstr_trim) - struct DStr str = UC_DSTR_STATIC_INIT; + struct DStr str = UC_DSTR_INITIALIZER; uc_dstr_append_str(&str, " \t \nHello !\r\n"); uc_dstr_trim(&str); From b5465012aeafe4253e42e992f5ed6c6061808766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 16 Sep 2014 01:11:32 +0200 Subject: [PATCH 06/49] Doxygen, generate struct docs in same page as the module it's in --- Doxyfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doxyfile b/Doxyfile index fc825f1..df415e7 100644 --- a/Doxyfile +++ b/Doxyfile @@ -298,7 +298,7 @@ SUBGROUPING = YES # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). -INLINE_GROUPED_CLASSES = NO +INLINE_GROUPED_CLASSES = YES # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation From 9ce3a4ebf8b43e82145e46d631938fd68a476ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 16 Sep 2014 01:28:23 +0200 Subject: [PATCH 07/49] Rework iomux_select, so it doesn't need to deald with dynamically allocating space for the IOMuxFD's --- src/iomux_select.c | 103 ++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 61 deletions(-) diff --git a/src/iomux_select.c b/src/iomux_select.c index f680d60..fb1517a 100644 --- a/src/iomux_select.c +++ b/src/iomux_select.c @@ -14,54 +14,28 @@ struct IOMuxSelect { fd_set master_read_set; fd_set master_write_set; - struct IOMuxFD **descriptors; // array of pointers to the user IOMuxFD's + struct IOMuxFD *descriptors[FD_SETSIZE]; // array of pointers to the user IOMuxFD's size_t alloc_descriptors; //allocated descriptors in 'descriptors' size_t num_descriptors; //number of descriptors we're watching - size_t deleted_cnt; //used to rebuild the descriptors array + int recalc_max; int max_fd; //keeps track of the max fd for select() }; static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd); -//grows the descriptor array. We never shrink it. -static int iomux_select_grow(struct IOMuxSelect *mux) -{ - void *tmp = realloc(mux->descriptors, (mux->num_descriptors + IOMUX_GROW_CHUNK) * sizeof *mux->descriptors); - assert(tmp != NULL); - if (tmp == NULL) - return ENOMEM; - mux->alloc_descriptors += IOMUX_GROW_CHUNK; - mux->descriptors = tmp; - - return 0; -} - -static void iomux_select_remove(struct IOMuxSelect *mux, size_t idx) -{ - if (mux->num_descriptors > 1) { - //move last element into the empty slot - size_t last_idx = mux->num_descriptors - 1; - mux->descriptors[idx] = mux->descriptors[last_idx]; - mux->descriptors[last_idx] = NULL; - } - - mux->num_descriptors--; -} - -static void iomux_select_rebuild(struct IOMuxSelect *mux) +static void iomux_select_recalc_max(struct IOMuxSelect *mux) { size_t i; - mux->max_fd = -1; + for (i = 0; i < mux->num_descriptors; ) { - if (mux->descriptors[i] == NULL) { - iomux_select_remove(mux, i); - //a deleted fd slot needs to be rechecked, no i++ here - } else { + if (mux->descriptors[i] != NULL) { mux->max_fd = UC_MAX(mux->descriptors[i]->fd, mux->max_fd); i++; } + + assert(i < FD_SETSIZE); } } @@ -70,6 +44,10 @@ static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd) { struct IOMuxSelect *mux = mux_->instance; + if (fd->fd < 0 || fd->fd >= FD_SETSIZE) { + return EINVAL; + } + if (fd->what & MUX_EV_READ) FD_SET(fd->fd, &mux->master_read_set); else @@ -86,18 +64,19 @@ static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd) static int iomux_select_register_fd(struct IOMux *mux_, struct IOMuxFD *fd) { struct IOMuxSelect *mux = mux_->instance; - if (fd->what == 0 || fd->callback == NULL) + int rc; + + if ((fd->what & MUX_EV_MASK) == 0 || fd->callback == NULL) return EINVAL; - if (mux->num_descriptors == mux->alloc_descriptors) { - if (iomux_select_grow(mux) != 0) - return ENOMEM; + rc = iomux_select_update_events(mux_, fd); + if (rc != 0) { + return ENFILE; } - mux->descriptors[mux->num_descriptors] = fd; + mux->descriptors[fd->fd] = fd; mux->num_descriptors++; - iomux_select_update_events(mux_, fd); mux->max_fd = UC_MAX(fd->fd, mux->max_fd); @@ -109,18 +88,21 @@ static int iomux_select_unregister_fd(struct IOMux *mux_, struct IOMuxFD *fd) struct IOMuxSelect *mux = mux_->instance; int rc = ENOENT; - size_t i; - for (i = 0; i < mux->num_descriptors; i++) { - if (fd == mux->descriptors[i]) { - unsigned int what = fd->what; //make sure we don't alter 'what' as seen from the user - fd->what &= ~MUX_EV_MASK; - iomux_select_update_events(mux_, fd); - mux->descriptors[i] = NULL; //set the slot to NULL, the event loop needs to rebuild it. - mux->deleted_cnt++; - fd->what = what; - rc = 0; - break; - } + if (fd->fd < 0 || fd->fd >= FD_SETSIZE) { + return ENFILE; + } + + if (mux->descriptors[fd->fd] != NULL) { + unsigned int what = fd->what; //make sure we don't alter 'what' as seen from the user + + fd->what = 0; + iomux_select_update_events(mux_, fd); + mux->descriptors[fd->fd] = NULL; + mux->recalc_max = 1; + fd->what = what; + + rc = 0; + mux->num_descriptors--; } return rc; @@ -136,9 +118,9 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout) fd_set read_set; fd_set write_set; - if (mux->deleted_cnt) { - iomux_select_rebuild(mux); - mux->deleted_cnt = 0; + if (mux->recalc_max) { + iomux_select_recalc_max(mux); + mux->recalc_max = 0; } if (mux->max_fd == -1 && timeout == NULL) @@ -161,8 +143,8 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout) if (rc == 0) //no fd's were ready, no more work to do return event_cnt; - for (i = 0; rc > 0 && i < mux->num_descriptors; i++) { - unsigned int events = 0; + for (i = 0; rc > 0 && i < FD_SETSIZE; i++) { + int had_event = 0; //deliver only one event at a time , to simplify application //programming @@ -171,7 +153,7 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout) rc--; assert(mux->descriptors[i]->callback != NULL); mux->descriptors[i]->callback(mux_, mux->descriptors[i], MUX_EV_READ); - events = 1; + had_event = 1; } //need to re-check in case the callback deleted the IOMuxFD @@ -180,10 +162,11 @@ static int iomux_select_run(struct IOMux *mux_, struct timeval *timeout) rc--; assert(mux->descriptors[i]->callback != NULL); mux->descriptors[i]->callback(mux_, mux->descriptors[i], MUX_EV_WRITE); - events = 1; + had_event = 1; } - event_cnt += events; + event_cnt += had_event; + } return event_cnt; @@ -193,8 +176,6 @@ static void iomux_select_delete(struct IOMux *mux) { if (mux != NULL && mux->instance != NULL) { struct IOMuxSelect *mux_select = mux->instance; - free(mux_select->descriptors); - mux_select->descriptors = NULL; free(mux_select); mux->instance = NULL; } From 13e611c79d60d542ca56efbe98b288026972a624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 16 Sep 2014 13:30:51 +0200 Subject: [PATCH 08/49] Generalise the logging function to a function pointer --- src/logging.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/logging.c b/src/logging.c index 567696a..dc0430b 100644 --- a/src/logging.c +++ b/src/logging.c @@ -34,6 +34,9 @@ struct UCLogModule_setting { int log_level; }; +struct UCLogArgs; +typedef void (*uc_vlog_func)(const struct UCLogArgs *args, const char *fmt, va_list ap); + struct UCLogDestination { struct TailQ entry; enum UC_LOG_DESTINATION dest_type; @@ -57,6 +60,8 @@ struct UCLogDestination { struct UCLogRotateSettings rotate; } file; } type; + + uc_vlog_func log_func; }; /* Helper struct for arguments to our main logging function */ @@ -87,6 +92,9 @@ static const struct UCLogModule g_unknown_module = { //this list an anything contained within it. static UC_TAILQ_HEAD(g_destinations); static int uc_log_reopen_file(struct UCLogDestination *dest); +static inline void uc_log_file_rotate_if_neeed(struct UCLogDestination *dest, time_t tstamp); +static void uc_vlog_file(const struct UCLogArgs *args, const char *fmt, va_list ap); +static void uc_vlog_syslog(const struct UCLogArgs *args, const char *fmt, va_list ap); //Uses enum UC_LOG_LEVEL as index static const char *const g_log_levels[] = { "UNKNOWN_0", @@ -185,6 +193,7 @@ struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location) dest->type.file.size = 0; dest->log_level = log_level;; dest->log_location = log_location; + dest->log_func = uc_vlog_file; return dest; } @@ -217,6 +226,7 @@ struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int dest->type.syslog.facility = facility; dest->log_level = log_level;; dest->log_location = log_location; + dest->log_func = uc_vlog_syslog; return dest; } @@ -261,6 +271,8 @@ struct UCLogDestination *uc_log_new_file(const char *filename, int log_level, in dest->type.file.rotate.policy = UC_LOG_ROTATE_NONE; + dest->log_func = uc_vlog_file; + return dest; } @@ -453,16 +465,19 @@ void uc_log_init(struct UCLogModules *user_modules) } //hold g_log_lock while calling this -static inline void uc_vlog_file(const struct UCLogArgs *args, time_t tstamp, const char *fmt, va_list ap) +static void uc_vlog_file(const struct UCLogArgs *args, const char *fmt, va_list ap) { struct UCLogDestination *dest = args->dest; char time_buf[48]; struct tm t; + time_t tstamp; int rc = 0; if (dest->type.file.file == NULL) return; + tstamp = time(NULL); + localtime_r(&tstamp, &t); if (!args->raw) { snprintf(time_buf, sizeof time_buf, "%04d-%02d-%02d %02d:%02d:%02d", @@ -495,10 +510,12 @@ static inline void uc_vlog_file(const struct UCLogArgs *args, time_t tstamp, con rc = fflush(dest->type.file.file); //strictly not needed for stderr // though stderr could be redirected to a file } + + uc_log_file_rotate_if_neeed(dest, tstamp); } //hold g_log_lock while calling this -static inline void uc_vlog_syslog(const struct UCLogArgs *args, const char *fmt, va_list ap) +static void uc_vlog_syslog(const struct UCLogArgs *args, const char *fmt, va_list ap) { struct UCLogDestination *dest = args->dest; @@ -705,25 +722,11 @@ void uc_logf(int log_level, int module, int raw, .raw = raw }; - time_t tstamp; - //log func will mess with the va_list, + //log_func will mess with the va_list, //so make a copy va_copy(apc, ap); - switch (dest->dest_type) { - case UC_LDEST_SYSLOG: - uc_vlog_syslog(&args, fmt, apc); - break; - case UC_LDEST_STDERR: - tstamp = time(NULL); - uc_vlog_file(&args, tstamp,fmt, apc); - break; - case UC_LDEST_FILE: - tstamp = time(NULL); - uc_vlog_file(&args, tstamp, fmt, apc); - uc_log_file_rotate_if_neeed(dest, tstamp); - break; - } + dest->log_func(&args, fmt, apc); va_end(apc); } From 749c5ef0df5ad03f87b1e7e84ee3d121461b98ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 29 Sep 2014 16:16:40 +0200 Subject: [PATCH 09/49] Correct a few comments in threadqueue --- include/ucore/threadqueue.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/ucore/threadqueue.h b/include/ucore/threadqueue.h index eacf9ab..a85932f 100644 --- a/include/ucore/threadqueue.h +++ b/include/ucore/threadqueue.h @@ -153,6 +153,7 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, unsigned int max_elements * Adds a message to a queue * * thread_queue_add adds a "message" to the specified queue. + * If the queue is full, the call will block if the timeout agrument is non-NULL. * It is up to the application to manage the data and memory indicated by the * struct uc_threadmsg. * The struct uc_threadmsg is assumed to be an intrusive pointer, @@ -167,7 +168,8 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, unsigned int max_elements * the front of the queue, i.e. it can be considered a "priority" message. * * @param queue Pointer to the queue on where the message should be added. - * @param timeout timeout on how long to wait on a message, or NULL for no timeout + * @param timeout timeout on how long to wait until the queue has capacity to add the message + * to the queue. * @param data the "message". * @return 0 on succes ENOMEM if out of memory EINVAL if queue is NULL, ETIMEDOUT if timeout occured or other * errno values if pthread functions failed. From 959d525938b8a736daae406c5067c5929c87ffa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 29 Sep 2014 16:16:55 +0200 Subject: [PATCH 10/49] Use correct return value on error --- src/threadqueue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/threadqueue.c b/src/threadqueue.c index e7a13c1..32d01c3 100644 --- a/src/threadqueue.c +++ b/src/threadqueue.c @@ -270,7 +270,7 @@ unsigned int uc_thread_queue_length(struct uc_threadqueue *queue) unsigned int length; if (queue == NULL ) { - return -EINVAL; + return EINVAL; } // get the length properly pthread_mutex_lock(&queue->mutex); @@ -285,7 +285,7 @@ int uc_thread_queue_clear(struct uc_threadqueue *queue, void *cookie) { if (queue == NULL) { - return -EINVAL; + return EINVAL; } pthread_mutex_lock(&queue->mutex); From 6247bcbdfd166a5dfac5e96b9778c9f0e22c9673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sat, 20 Sep 2014 21:47:29 +0200 Subject: [PATCH 11/49] Also build a shared library --- SConstruct | 4 ++++ src/SConscript | 8 +++++--- test/SConscript | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/SConstruct b/SConstruct index f0fc4bb..160a212 100644 --- a/SConstruct +++ b/SConstruct @@ -9,6 +9,9 @@ version_info = { 'version_minor': 0 , 'version_patch': 0 , 'version_revision': revision, +#version_abi is the abi version of the shared library. Only bump it when +#backwards compatibility breaks. Strive to not break the ABI. + 'version_abi': '1.0.0' } version_info['version_str'] = "%d.%d.%d.%s" % ( version_info['version_major'], @@ -99,6 +102,7 @@ env.Append(CFLAGS = ['-Wno-unused-parameter', '-Werror=implicit-function-declara env.Append(LINKFLAGS = ['-O2', '-pthread']) env.Append(CPPDEFINES = ['_FILE_OFFSET_BITS=64']) env.Append(CPPPATH = ['#include']) +env.Append(SHLIBVERSION = version_info['version_abi']) if GetOption('force32bit'): env.Append(CFLAGS = ['-m32']) diff --git a/src/SConscript b/src/SConscript index 1367097..7d060a3 100644 --- a/src/SConscript +++ b/src/SConscript @@ -13,9 +13,11 @@ sources = ucore_env.Glob('*.c') #print 'sources:', sources[len(sources)-2] #Build library -ucore_lib = ucore_env.StaticLibrary(target='ucore' + lib_suffix , source=sources) +ucore_staticlib = ucore_env.StaticLibrary(target='ucore' + lib_suffix , source=sources) +ucore_sharedlib = ucore_env.SharedLibrary(target='ucore' + lib_suffix , source=sources) #install targets ucore_env.Alias('install', - ucore_env.Install(os.path.join(prefix, 'lib'), ucore_lib)) - + ucore_env.Install(os.path.join(prefix, 'lib'), [ucore_staticlib])) +ucore_env.Alias('install', + ucore_env.InstallVersionedLib(os.path.join(prefix, 'lib'), [ucore_sharedlib])) diff --git a/test/SConscript b/test/SConscript index 30a17fa..2e42446 100644 --- a/test/SConscript +++ b/test/SConscript @@ -23,6 +23,9 @@ test_executable = 'test_runner' if test_xml: test_executable += ' -x' +#rpath to shared lib, so test_runner can actually be executed +test_env.Append(LINKFLAGS = ['-Wl,-rpath,\\$$ORIGIN/../src']) + prog = test_env.Program('test_runner', tests) cmd = test_env.Command(target='test_phony' , source = None, From 42136087b6f46335c3643498fed8a3708d8934d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 29 Sep 2014 21:09:50 +0200 Subject: [PATCH 12/49] Add note about scons 2.3.0 --- README | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README b/README index 6ae1c57..396f3e9 100644 --- a/README +++ b/README @@ -7,9 +7,13 @@ Build ===== In addition to basic C development tools, the following is needed: -* scons +* scons 2.3.0 or later * check Run scons --help to see the various options for building the library Run "scons test" to run the test suite +Note that scons v 2.3.1 or later is recommended, since scons v 2.3.0 +has a bug which prevents shared libraries from re-building properly. + + From 33b48c42761e3e459520d5aaeab1c63d1e55e9cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 29 Sep 2014 21:29:02 +0200 Subject: [PATCH 13/49] More checks on test_mbuf_static --- test/test_mbuf.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/test_mbuf.c b/test/test_mbuf.c index 598779a..be2df35 100644 --- a/test/test_mbuf.c +++ b/test/test_mbuf.c @@ -221,6 +221,7 @@ START_TEST (test_mbuf_static) uint8_t data[1024]; struct MBuf mbuf; + uint8_t *p; uc_mbuf_init(&mbuf, data, 1000, 24, UC_MBUF_FL_STATIC); @@ -234,6 +235,13 @@ START_TEST (test_mbuf_static) fail_if(mbuf.cookie != NULL); fail_if(mbuf.head != mbuf.tail); fail_if(mbuf.head != &data[24]); + p = uc_mbuf_put(&mbuf, 1000); + fail_if(p == NULL); + memset(p, 0xcc, 1000); + fail_if(uc_mbuf_len(&mbuf) != 1000); + p = uc_mbuf_put(&mbuf, 1); + fail_if(p != NULL); + uc_mbuf_free(&mbuf); From 9bd1336d26b9e07ab12e540dcd4b52b7e6df71d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 6 Oct 2014 21:52:28 +0200 Subject: [PATCH 14/49] have LOGF macros add a newline, so user code doesn't need to. --- include/ucore/logging.h | 9 +-- test/logging.c | 24 +++---- test/test_logging.c | 140 ++++++++++++++++++++-------------------- test/udp_heartbeat.c | 16 ++--- 4 files changed, 95 insertions(+), 94 deletions(-) diff --git a/include/ucore/logging.h b/include/ucore/logging.h index 37234dd..db4780c 100644 --- a/include/ucore/logging.h +++ b/include/ucore/logging.h @@ -305,9 +305,9 @@ void uc_logf(int log_level, int module, int raw, // to override that by defining UC_DEBUG_ALWAYS #if defined(DEBUG) || defined(UC_DEBUG_ALWAYS) # define UC_DEBUGF(mod, fmt, ...)\ - uc_logf(UC_LL_DEBUG, mod,0 , UC_SRC_LOCATION, fmt, ## __VA_ARGS__) + uc_logf(UC_LL_DEBUG, mod,0 , UC_SRC_LOCATION, fmt "\n", ## __VA_ARGS__) # define UC_DEBUGFR(mod, fmt, ...)\ - uc_logf(UC_LL_DEBUG, mod,1 , UC_SRC_LOCATION, fmt, ## __VA_ARGS__) + uc_logf(UC_LL_DEBUG, mod,1 , UC_SRC_LOCATION, fmt "\n", ## __VA_ARGS__) #else # define UC_DEBUGF(mod, fmt, ...) do {} while (0) # define UC_DEBUGFR(mod, fmt, ...) do {} while (0) @@ -317,6 +317,7 @@ void uc_logf(int log_level, int module, int raw, * * For log messages with UC_LL_DEBUG, the UC_DEBUGF() macro can be used, * UC_DEBUGF will only be compiled in if the DEBUG macro is defined + * fmt must be a string literal, and a newline will be added * * @param lvl log level of this log message * @param mod module id of this log messagex. @@ -324,11 +325,11 @@ void uc_logf(int log_level, int module, int raw, * @param ... printf style arguments */ #define UC_LOGF(lvl, mod, fmt, ...) \ - uc_logf(lvl, mod, 0, UC_SRC_LOCATION, fmt, ## __VA_ARGS__) + uc_logf(lvl, mod, 0, UC_SRC_LOCATION, fmt "\n", ## __VA_ARGS__) /** Raw logging ,Like UC_LOGF, but only prints the supplied - * data, not timestamp, log level etc. + * data, not timestamp, log level, newline, etc. */ #define UC_LOGFR(lvl, mod, fmt, ...) \ uc_logf(lvl, mod, 1, UC_SRC_LOCATION, fmt, ## __VA_ARGS__) diff --git a/test/logging.c b/test/logging.c index a083807..fbce752 100644 --- a/test/logging.c +++ b/test/logging.c @@ -49,27 +49,27 @@ int main(int argc, char *argv[]) uc_log_add_destination(dest); dest = uc_log_new_stderr(UC_LL_INFO, 0); uc_log_add_destination(dest); - UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 2); - UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 3); - UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 4); - UC_LOGF( UC_LL_INFO, CC, "Test cc info %d\n", 5); - UC_LOGF( UC_LL_WARNING, HO, "Test HO warning%d\n", 2); - UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN info \n" ); - UC_LOGF( UC_LL_WARNING, MAIN, "Test MAIN warning\n" ); + UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 2); + UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 3); + UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 4); + UC_LOGF( UC_LL_INFO, CC, "Test cc info %d", 5); + UC_LOGF( UC_LL_WARNING, HO, "Test HO warning%d", 2); + UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN info " ); + UC_LOGF( UC_LL_WARNING, MAIN, "Test MAIN warning" ); uc_log_destination_set_module_loglevel(dest, MAIN, UC_LL_INFO); - UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN INFO 2\n" ); + UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN INFO 2" ); - UC_LOGFR(UC_LL_INFO, MAIN, "Test RAW logging 1\n" ); + UC_LOGFR(UC_LL_INFO, MAIN, "Test RAW logging 1" ); uc_log_destination_set_module_loglevel(dest,MAIN, UC_LL_WARNING); - UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN INFO 3\n" ); + UC_LOGF( UC_LL_INFO, MAIN, "Test MAIN INFO 3" ); uc_log_destination_set_loglevel(dest, UC_LL_DEBUG); - UC_LOGF( UC_LL_DEBUG, MAIN, "Test MAIN DEBUG SHOULD NOT SHOW\n" ); + UC_LOGF( UC_LL_DEBUG, MAIN, "Test MAIN DEBUG SHOULD NOT SHOW" ); //uc_log_destination_set_module_loglevel(dest, MAIN, UC_LL_INFO); uc_log_destination_set_mask(dest, "HO=ERROR:MAIN=DEBUG:HO=DEBUG"); - UC_LOGF( UC_LL_DEBUG, MAIN, "Test MAIN DEBUG SHOULD SHOW\n" ); + UC_LOGF( UC_LL_DEBUG, MAIN, "Test MAIN DEBUG SHOULD SHOW" ); uc_log_delete_destination(dest); diff --git a/test/test_logging.c b/test/test_logging.c index 14a2ffc..d6a8a28 100644 --- a/test/test_logging.c +++ b/test/test_logging.c @@ -53,15 +53,15 @@ START_TEST (test_logfile_location) uc_log_add_destination(dest); uc_log_add_destination(dest); //adding this twice should do nothing - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2\n"); - UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n"); - UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n"); - UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n"); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2"); + UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3"); + UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4"); + UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5"); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 380, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_delete_destination) @@ -87,28 +87,28 @@ START_TEST (test_logfile_delete_destination) uc_log_add_destination(dest); uc_log_add_destination(dest); //adding this twice should do nothing - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2\n"); - UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n"); - UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n"); - UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n"); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2"); + UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3"); + UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4"); + UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5"); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 380, "was %ld", (long)st.st_size); uc_log_delete_destination(dest); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2\n"); - UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3\n"); - UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4\n"); - UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5\n"); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson 2"); + UC_LOGF(UC_LL_INFO, 0, "Lorum ipson 3"); + UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson 4"); + UC_LOGF(UC_LL_ERROR, 0, "Lorum ipson 5"); //since we deleted destinatiion, no more logging should appear in the file rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 380, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 380, "was %ld", (long)st.st_size); END_TEST @@ -134,12 +134,12 @@ START_TEST (test_logfile_no_location) fail_if(dest == NULL); uc_log_add_destination(dest); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 52*2, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 52*2, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_loglevel_surpressed_dest) @@ -169,9 +169,9 @@ START_TEST (test_logfile_loglevel_surpressed_dest) UC_LOGF(UC_LL_INFO, 1, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); - fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size); + fail_if(st.st_size != 0, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_loglevel_surpressed_module) @@ -201,9 +201,9 @@ START_TEST (test_logfile_loglevel_surpressed_module) UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 100); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); - fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size); + fail_if(st.st_size != 0, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_reopen_files) @@ -228,24 +228,24 @@ START_TEST (test_logfile_reopen_files) fail_if(dest == NULL); uc_log_add_destination(dest); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size); rc = remove(FILE_NAME); - fail_if(rc != 0, "Remove failed %s\n", strerror(errno)); + fail_if(rc != 0, "Remove failed %s", strerror(errno)); rc = uc_log_reopen_files(); - fail_if(rc != 0, "uc_log_reopen_files failed: %d\n", rc); + fail_if(rc != 0, "uc_log_reopen_files failed: %d", rc); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 77, "was %ld\n", (long)st.st_size);//should only one line there now + fail_if(rc != 0, "2. stat failed: %s", strerror(errno)); + fail_if(st.st_size != 77, "was %ld", (long)st.st_size);//should only one line there now END_TEST @@ -277,29 +277,29 @@ START_TEST (test_logfile_remove_dest) uc_log_add_destination(dest1); uc_log_add_destination(dest2); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size); uc_log_remove_destination(dest1); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); //should not be logged now + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); //should not be logged now rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);//should be same size + fail_if(rc != 0, "2. stat failed: %s", strerror(errno)); + fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size //removing the last destination should be fine too uc_log_remove_destination(dest2); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "2. stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 77*2, "was %ld\n", (long)st.st_size);//should be same size + fail_if(rc != 0, "2. stat failed: %s", strerror(errno)); + fail_if(st.st_size != 77*2, "was %ld", (long)st.st_size);//should be same size END_TEST @@ -326,9 +326,9 @@ START_TEST (test_logfile_full_filesystem) uc_log_add_destination(dest); for (i = 0; i < 1024; i++) { - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d\n", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1); } END_TEST @@ -370,7 +370,7 @@ START_TEST (test_logfile_invalid_file_after_reopen) int rc; uc_log_init(&mods); - printf("SUBDIR_FILE_NAME= " SUBDIR_FILE_NAME " \n"); + printf("SUBDIR_FILE_NAME= " SUBDIR_FILE_NAME " "); dest = uc_log_new_file(SUBDIR_FILE_NAME, UC_LL_DEBUG, 1); fail_if(dest == NULL); @@ -378,18 +378,18 @@ START_TEST (test_logfile_invalid_file_after_reopen) logging_rm_subdir(); rc = access(SUBDIR_FILE_NAME, W_OK); - fail_if(rc == 0, "Test setup is wrong. Can still access" SUBDIR_FILE_NAME "\n"); + fail_if(rc == 0, "Test setup is wrong. Can still access" SUBDIR_FILE_NAME ""); - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d\n", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1); uc_log_reopen_files(); //this should not crash now. - UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1); - UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d\n", 1); + UC_LOGF(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_WARNING, 0, "Lorum ipson %d", 1); + UC_LOGF(UC_LL_INFO, 0, "Lorum ipson %d", 1); END_TEST @@ -419,8 +419,8 @@ START_TEST (test_logfile_raw) UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 14*2, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size); END_TEST START_TEST (test_logfile_dest_mask) @@ -454,19 +454,19 @@ START_TEST (test_logfile_dest_mask) uc_log_add_destination(dest); UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); - UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); + UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 0, "was %ld", (long)st.st_size); uc_log_destination_set_mask(dest, "MOD1=DEBUG:mod2=Debug"); UC_LOGFR(UC_LL_DEBUG, 0, "Lorum ipson %d\n", 1); UC_LOGFR(UC_LL_DEBUG, 1, "Lorum ipson %d\n", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 14*2, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 14*2, "was %ld", (long)st.st_size); END_TEST START_TEST (test_loglevel_module_none) @@ -494,8 +494,8 @@ START_TEST (test_loglevel_module_none) UC_LOGFR(UC_LL_ERROR, 0, "Lorum ipson %d\n", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 0, "was %ld", (long)st.st_size); END_TEST START_TEST (test_loglevel_dest_none) @@ -523,8 +523,8 @@ START_TEST (test_loglevel_dest_none) UC_LOGFR(UC_LL_WARNING, 0, "Lorum ipson %d\n", 1); rc = stat(FILE_NAME, &st); - fail_if(rc != 0, "stat failed: %s\n", strerror(errno)); - fail_if(st.st_size != 0, "was %ld\n", (long)st.st_size); + fail_if(rc != 0, "stat failed: %s", strerror(errno)); + fail_if(st.st_size != 0, "was %ld", (long)st.st_size); END_TEST diff --git a/test/udp_heartbeat.c b/test/udp_heartbeat.c index 66bb717..f313b07 100644 --- a/test/udp_heartbeat.c +++ b/test/udp_heartbeat.c @@ -99,7 +99,7 @@ void peer_add_addr(struct HBContext *ctx, const struct sockaddr_in *addr) int usec; if (peer != NULL) { - UC_LOGF(UC_LL_INFO, LMAIN, "Ignoring adding existing peer %s:%u\n", + UC_LOGF(UC_LL_INFO, LMAIN, "Ignoring adding existing peer %s:%u", inet_ntoa(addr->sin_addr), addr->sin_port); return; } @@ -169,12 +169,12 @@ void peer_do_state(struct HBPeer *peer, enum PeerEvent event) { if (peer->state == PeerUnknown || peer->state == PeerDead) { if (event == PeerReceived) { - UC_LOGF(UC_LL_INFO, LMAIN, "Peer is now alive\n"); + UC_LOGF(UC_LL_INFO, LMAIN, "Peer is now alive"); peer->state = PeerAlive; } } else if (peer->state == PeerAlive) { if (event == PeerTimedout) { - UC_LOGF(UC_LL_INFO, LMAIN, "Peer is dead !\n"); + UC_LOGF(UC_LL_INFO, LMAIN, "Peer is dead !"); peer->state = PeerDead; } } @@ -206,7 +206,7 @@ void hb_read(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) return; } - UC_LOGF(UC_LL_INFO, LMAIN, "Message from %s:%u\n", inet_ntoa(peer_addr.sin_addr), + UC_LOGF(UC_LL_INFO, LMAIN, "Message from %s:%u", inet_ntoa(peer_addr.sin_addr), ntohs(peer_addr.sin_port)); if (rc < 4) { @@ -216,13 +216,13 @@ void hb_read(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) magic = uc_unpack_32_be(buf); if (magic != HB_MAGIX) { - UC_LOGF(UC_LL_WARNING, LMAIN, "Received unknown message, magic = 0x%X\n", magic); + UC_LOGF(UC_LL_WARNING, LMAIN, "Received unknown message, magic = 0x%X", magic); return; } peer = hb_peer_find(ctx, &peer_addr); if (peer == NULL) { - UC_LOGF(UC_LL_WARNING, LMAIN, "Found no peer\n"); + UC_LOGF(UC_LL_WARNING, LMAIN, "Found no peer"); return; } @@ -241,13 +241,13 @@ void init_hb_context(struct HBContext *ctx, uint16_t local_port) sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock_fd == -1) { - UC_LOGF(UC_LL_ERROR, LMAIN, "socket failed : %s\n", strerror(errno)); + UC_LOGF(UC_LL_ERROR, LMAIN, "socket failed : %s", strerror(errno)); return; } if (bind(sock_fd, (struct sockaddr*)&addr, sizeof addr) != 0) { - UC_LOGF(UC_LL_ERROR, LMAIN, "Cannot bind socket to port %u : %s\n", + UC_LOGF(UC_LL_ERROR, LMAIN, "Cannot bind socket to port %u : %s", local_port, strerror(errno)); close(sock_fd); return; From fe3e4d8e3c438aed9081367bb2ca877c2a81fdeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 26 Oct 2014 14:27:26 +0100 Subject: [PATCH 15/49] Add missing prototypes and includes --- include/ucore/hash.h | 2 ++ include/ucore/iomux.h | 7 +++++++ src/sdmhash.c | 2 ++ src/strlcpy.c | 1 + src/supervisor.c | 1 + 5 files changed, 13 insertions(+) diff --git a/include/ucore/hash.h b/include/ucore/hash.h index 750b446..3c185d8 100644 --- a/include/ucore/hash.h +++ b/include/ucore/hash.h @@ -28,6 +28,8 @@ uc_pjwhash(const char *str,size_t len); uint32_t uc_sax_hash(void *key, size_t len); +unsigned long +uc_sdbmhash(const unsigned char *str); #ifdef __cplusplus } #endif diff --git a/include/ucore/iomux.h b/include/ucore/iomux.h index 414ce21..efcc3a1 100644 --- a/include/ucore/iomux.h +++ b/include/ucore/iomux.h @@ -137,6 +137,13 @@ struct UCTimers *iomux_get_timers(struct IOMux *mux); * or indirectly by the UCTimers provieded in a timer callback handler. */ struct IOMux *iomux_from_timers(struct UCTimers *timers); + + +/** Get the clock associated with the IOMux. This is the clock used + * used to drive the UCTimers associated with this IOMux + */ +struct UCoreClock *iomux_get_clock(struct IOMux *mux); + #ifdef __cplusplus } #endif diff --git a/src/sdmhash.c b/src/sdmhash.c index da7d0fb..6fde471 100644 --- a/src/sdmhash.c +++ b/src/sdmhash.c @@ -1,3 +1,5 @@ +#include "ucore/hash.h" + unsigned long uc_sdbmhash(const unsigned char *str) { diff --git a/src/strlcpy.c b/src/strlcpy.c index 6f9682a..36c3e6b 100644 --- a/src/strlcpy.c +++ b/src/strlcpy.c @@ -1,4 +1,5 @@ #include +#include "ucore/string.h" size_t uc_strlcpy(char *restrict dst, const char *restrict src, size_t max) { diff --git a/src/supervisor.c b/src/supervisor.c index b5f41d8..783ef7a 100644 --- a/src/supervisor.c +++ b/src/supervisor.c @@ -8,6 +8,7 @@ #include #include #include +#include "ucore/supervisor.h" #define CLEAN_EXIT 11 From 8c36756170c7574e6f62fdd4a8d005fe97414f29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 10 Nov 2014 21:05:45 +0100 Subject: [PATCH 16/49] Increase timeout on thread queue test to make it pass on the slow raspberrypis --- test/test_threadqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_threadqueue.c b/test/test_threadqueue.c index b08792c..a8d5db0 100644 --- a/test/test_threadqueue.c +++ b/test/test_threadqueue.c @@ -390,7 +390,7 @@ Suite *threadqueue_suite(void) tcase_add_test(tc1, test_thread_queue_clear); //lets start with this: - tcase_set_timeout(tc1, 15); + tcase_set_timeout(tc1, 25); suite_add_tcase(s, tc1); From dd925b3654f38c8b222f29fc5bb5b86126f29e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 2 Dec 2014 23:22:18 +0100 Subject: [PATCH 17/49] int log_level->enum UC_LOG_LEVEL --- include/ucore/logging.h | 10 +++++----- src/logging.c | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/ucore/logging.h b/include/ucore/logging.h index db4780c..c63ebef 100644 --- a/include/ucore/logging.h +++ b/include/ucore/logging.h @@ -108,7 +108,7 @@ struct UCLogModule { * log statements with a level >= the log_level * are actually logged, but the log_level of a destination * can restrict the logging further*/ - int log_level; + enum UC_LOG_LEVEL log_level; }; /* A collection of struct UCLogModule */ @@ -168,7 +168,7 @@ const char *uc_ll_2_str(enum UC_LOG_LEVEL l); * @return An opaque uc_log_destination that can be added as a destination to * the ucore logging system */ -struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location); +struct UCLogDestination *uc_log_new_stderr(enum UC_LOG_LEVEL log_level, int log_location); /* creates a new uc_log_destination for logging to syslog * @@ -181,7 +181,7 @@ struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location); * @return An opaque uc_log_destination that can be added as a destination to * the ucore logging system */ -struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int log_level, int log_location); +struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, enum UC_LOG_LEVEL log_level, int log_location); /* creates a new uc_log_destination for printing on stderr. * @@ -192,7 +192,7 @@ struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int * @param return An opaque uc_log_destination that can be added as a destination to * the ucore logging system */ -struct UCLogDestination *uc_log_new_file(const char *filename, int log_level, int log_location); +struct UCLogDestination *uc_log_new_file(const char *filename, enum UC_LOG_LEVEL log_level, int log_location); /** Add a uc_log_destination to the logging system. * @@ -297,7 +297,7 @@ int uc_log_reopen_files(void); */ void uc_log_init(struct UCLogModules *user_modules); -void uc_logf(int log_level, int module, int raw, +void uc_logf(enum UC_LOG_LEVEL log_level, int module, int raw, const char *location, const char *fmt, ...) __attribute__((format(printf, 5, 6))); diff --git a/src/logging.c b/src/logging.c index dc0430b..d85206f 100644 --- a/src/logging.c +++ b/src/logging.c @@ -30,8 +30,8 @@ enum UC_LOG_DESTINATION { #define UC_MAX_RENAME_CNT (128) //used to realise per destination settings -struct UCLogModule_setting { - int log_level; +struct UCLogModuleSetting { + enum UC_LOG_LEVEL log_level; }; struct UCLogArgs; @@ -41,10 +41,10 @@ struct UCLogDestination { struct TailQ entry; enum UC_LOG_DESTINATION dest_type; //log level for this destination - int log_level; + enum UC_LOG_LEVEL log_level; //Whether to log the source file name and line number int log_location; - struct UCLogModule_setting *module_settings; + struct UCLogModuleSetting *module_settings; union { //for syslog openlog() struct { @@ -68,7 +68,7 @@ struct UCLogDestination { struct UCLogArgs { struct UCLogDestination *dest; const struct UCLogModule *module; - int log_level; + enum UC_LOG_LEVEL log_level; const char *location; int raw; }; @@ -176,7 +176,7 @@ static int uc_log_init_common(struct UCLogDestination *dest) return rc; } -struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location) +struct UCLogDestination *uc_log_new_stderr(enum UC_LOG_LEVEL log_level, int log_location) { struct UCLogDestination *dest = calloc(1, sizeof *dest); @@ -198,7 +198,7 @@ struct UCLogDestination *uc_log_new_stderr(int log_level, int log_location) return dest; } -struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int log_level, int log_location) +struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, enum UC_LOG_LEVEL log_level, int log_location) { struct UCLogDestination *dest = calloc(1, sizeof *dest); char *id; @@ -231,7 +231,7 @@ struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, int return dest; } -struct UCLogDestination *uc_log_new_file(const char *filename, int log_level, int log_location) +struct UCLogDestination *uc_log_new_file(const char *filename, enum UC_LOG_LEVEL log_level, int log_location) { struct UCLogDestination *dest = calloc(1, sizeof *dest); FILE *f; @@ -679,7 +679,7 @@ static inline void uc_log_file_rotate_if_neeed(struct UCLogDestination *dest, ti } } -void uc_logf(int log_level, int module, int raw, +void uc_logf(enum UC_LOG_LEVEL log_level, int module, int raw, const char *location, const char *fmt, ...) { va_list ap; @@ -693,7 +693,7 @@ void uc_logf(int log_level, int module, int raw, UC_TAILQ_FOREACH_CONTAINER(dest, entry, &g_destinations) { const struct UCLogModule *log_module; va_list apc; - int module_log_level; + enum UC_LOG_LEVEL module_log_level; //destnation level From ab70a2c5beb3d45f01dd71c44ded5213fda68818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 2 Dec 2014 23:38:24 +0100 Subject: [PATCH 18/49] Make uc_log_init argument const --- include/ucore/logging.h | 7 +++++-- src/logging.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/ucore/logging.h b/include/ucore/logging.h index c63ebef..b7800ed 100644 --- a/include/ucore/logging.h +++ b/include/ucore/logging.h @@ -100,9 +100,12 @@ struct UCLogModule { int id; /** A short name for the module. + * (must point to static storage) * This will appear in log messages */ const char *short_name; - /** A longer description for the log module*/ + /** A longer description for the log module + * (must point to static storage) + */ const char *long_name; /** The log level of this module. Only * log statements with a level >= the log_level @@ -295,7 +298,7 @@ int uc_log_reopen_files(void); * * @param user_struct containing an array of all the modules defined by the application. */ -void uc_log_init(struct UCLogModules *user_modules); +void uc_log_init(const struct UCLogModules *user_modules); void uc_logf(enum UC_LOG_LEVEL log_level, int module, int raw, const char *location, const char *fmt, ...) diff --git a/src/logging.c b/src/logging.c index d85206f..c235546 100644 --- a/src/logging.c +++ b/src/logging.c @@ -459,7 +459,7 @@ int uc_log_reopen_files(void) return rc; } -void uc_log_init(struct UCLogModules *user_modules) +void uc_log_init(const struct UCLogModules *user_modules) { g_modules = *user_modules; } From 0622c57d4261e6fdbab1849d1ac897dfa210409a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 7 Dec 2014 15:39:32 +0100 Subject: [PATCH 19/49] Initial attempt --- src/cmd/cmd.c | 55 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c index 3bf0cf4..9459958 100644 --- a/src/cmd/cmd.c +++ b/src/cmd/cmd.c @@ -1,17 +1,54 @@ #include -enum UCCmdNodeType { - UC_CMDNODE_ROOT, - UC_CMDNODE_KEYWORD, - UC_CMD-zzzzzzzzzzzzzzzz - +enum UCCmdRc { + /**Executed ok */ + UC_CMD_OK, + /**Executed with warning */ + UC_CMD_WARNING, + /*Not executed, incomplete command */ + UC_CMD_INCOMPLETE, + /*Not executed, generic error */ + UC_CMD_ERROR, }; +typedef enum UCCmdRc (*uc_cmd_handler)(int narg, char *args[]); +typedef void (*uc_cmd_write_cfg)(void); + +#define UC_CMD_FL_HIDDEN (1 << 0) + +struct UCCmdNode; +struct UCCmdDef; + +struct UCCmdSettings { + const char *name; + const char *version; + const char *boot_cfg_file; + + struct UCCmdNode *initial_node; + struct UCCmdNode *node_head; +}; struct UCCmdNode { - enum UCCmdNodeType type; - uint32_t flags; - void *param; + int id; + uc_cmd_write_cfg write_func; + struct UCCmdDef *cmd_head; //linked list of UCCmdDef struct UCCmdNode *next; - struct UCCmdNode *child; }; + +struct UCCmdDef { + const char *cmd; + const char **help; + size_t cmd_len; + uc_cmd_handler cb; + uint32_t flags; + + struct UCCmdDef *next; +}; + + +void uc_cmd_init(const char *app_name, const char *version); +int uc_cmd_read_config(const char *filename); +void uc_cmd_set_configfile(const char *filename); +void uc_cmd_add_cmd(struct UCCmdDef *cmd, int parent_node_id); +void uc_cmd_set_default_node(int node_id); + From a367e84b001d045939bfbbbf7665b46428946e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sat, 3 Jan 2015 01:51:18 +0100 Subject: [PATCH 20/49] Move UC_INLINE to utils.h --- include/ucore/mbuf.h | 13 ------------- include/ucore/pack.h | 13 +------------ include/ucore/tailq.h | 15 ++------------- include/ucore/utils.h | 11 +++++++++++ 4 files changed, 14 insertions(+), 38 deletions(-) diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 27cc959..f6a1767 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -4,17 +4,6 @@ #include #include "tailq.h" -#ifndef UC_INLINE -#ifdef __GNUC__ -# ifdef __clang__ -# define UC_INLINE inline __attribute__((always_inline)) -# else -# define UC_INLINE inline __attribute__((always_inline,flatten)) -# endif -#else -# define UC_INLINE inline -#endif -#endif /** @file * mbuf - A managed message/memory buffer. @@ -220,6 +209,4 @@ static UC_INLINE uint8_t *uc_mbuf_head(struct MBuf* mbuf) return mbuf->head; } -#undef UC_INLINE - #endif diff --git a/include/ucore/pack.h b/include/ucore/pack.h index 6553b7e..889adcc 100644 --- a/include/ucore/pack.h +++ b/include/ucore/pack.h @@ -2,18 +2,7 @@ #define UC_PACK_H_ #include - -#ifndef UC_INLINE -#ifdef __GNUC__ -# ifdef __clang__ -# define UC_INLINE inline __attribute__((always_inline)) -# else -# define UC_INLINE inline __attribute__((always_inline,flatten)) -# endif -#else -# define UC_INLINE inline -#endif -#endif +#include "utils.h" /** @file * Functions for serializing/de-serializing integers to and from diff --git a/include/ucore/tailq.h b/include/ucore/tailq.h index a4ebd6f..ae6da60 100644 --- a/include/ucore/tailq.h +++ b/include/ucore/tailq.h @@ -1,17 +1,8 @@ #ifndef UC_TAILQ_H_ #define UC_TAILQ_H_ -#ifndef UC_INLINE -#ifdef __GNUC__ -# ifdef __clang__ -# define UC_INLINE inline __attribute__((always_inline)) -# else -# define UC_INLINE inline __attribute__((always_inline,flatten)) -# endif -#else -# define UC_INLINE inline -#endif -#endif +#include "utils.h" + /** * Doubly Linked List. * It is used either as @@ -253,6 +244,4 @@ static UC_INLINE void uc_tailq_move_tail(struct TailQ *entry, struct TailQ *head (ptr) = (prv),\ (prv) = UC_TAILQ_CONTAINER(UC_TAILQ_NEXT(&(ptr)->member), typeof(*ptr), member)) -#undef UC_INLINE - #endif diff --git a/include/ucore/utils.h b/include/ucore/utils.h index 44511ff..9811e1b 100644 --- a/include/ucore/utils.h +++ b/include/ucore/utils.h @@ -120,5 +120,16 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \ */ #define UC_UNUSED(x) x __attribute__((unused)) + +#ifdef __GNUC__ +# ifdef __clang__ +# define UC_INLINE inline __attribute__((always_inline)) +# else +# define UC_INLINE inline __attribute__((always_inline,flatten)) +# endif +#else +# define UC_INLINE inline +#endif + #endif From 603d86bb614c21bdda47bbb11343129344583dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sat, 3 Jan 2015 01:52:53 +0100 Subject: [PATCH 21/49] Remove stdio.h from utils.h. Manually include stdio.h if using the TRACEF() macro from utils.h --- include/ucore/utils.h | 2 +- src/iomux_impl.c | 2 +- test/test_heapsort.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/ucore/utils.h b/include/ucore/utils.h index 9811e1b..614b6bc 100644 --- a/include/ucore/utils.h +++ b/include/ucore/utils.h @@ -2,7 +2,6 @@ #define UC_UTILS_H_ #include -#include //Gnerate a compiler error if the compile time //constant expression fails @@ -74,6 +73,7 @@ const typeof( ((const type *)0)->member ) *__mptr = (ptr); \ #ifdef DEBUG + //include if using the TRACEF() macro #define TRACEF(fmt, ...)\ do { \ fprintf(stdout, "%s (%s)\t" fmt, UC_SRC_LOCATION, __FUNCTION__, ##__VA_ARGS__);\ diff --git a/src/iomux_impl.c b/src/iomux_impl.c index 6f60744..a577b5b 100644 --- a/src/iomux_impl.c +++ b/src/iomux_impl.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include "ucore/clock.h" #include "ucore/backtrace.h" diff --git a/test/test_heapsort.c b/test/test_heapsort.c index 0f23e10..3668593 100644 --- a/test/test_heapsort.c +++ b/test/test_heapsort.c @@ -1,4 +1,5 @@ #include +#include #include "ucore/utils.h" #include "ucore/heapsort.h" From f0c829a6c9c116700257e53dc723d6497ecffb04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sat, 3 Jan 2015 02:10:51 +0100 Subject: [PATCH 22/49] Added a main() to atomic.c --- test/atomic.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/atomic.c b/test/atomic.c index 6232ae0..ecec137 100644 --- a/test/atomic.c +++ b/test/atomic.c @@ -1,3 +1,5 @@ +#include + #include "ucore/atomic.h" UC_ATOMIC(unsigned int) i; @@ -48,3 +50,20 @@ unsigned int get_i_compbar() } +int main(int argc, char *argv[]) +{ + printf("i: %u\n", get_i()); + inc_i(); + printf("i: %u\n", get_i()); + inc_i(); + dec_i(); + printf("i: %u\n", get_i()); + add_i(100); + printf("i: %u\n", get_i()); + sub_i(50); + printf("i: %u\n", get_i_membar()); + + + return 0; +} + From 617ba23c393a386f3dc3bbfa8b2f2437a570f03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 10 Feb 2015 11:03:44 +0100 Subject: [PATCH 23/49] Make the clock_now interface const --- include/ucore/clock.h | 2 +- src/clock.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/ucore/clock.h b/include/ucore/clock.h index 7014c63..26aba2e 100644 --- a/include/ucore/clock.h +++ b/include/ucore/clock.h @@ -26,7 +26,7 @@ struct UCoreClock { * Wrapper for getting the current time. * @param tv timeval that will be filled in */ - void (*now)(struct UCoreClock *clock, struct timeval *tv); + void (*now)(const struct UCoreClock *clock, struct timeval *tv); }; /** Convenience macro for geting the time from a UCoreClock diff --git a/src/clock.c b/src/clock.c index aeb0538..bfdbcb7 100644 --- a/src/clock.c +++ b/src/clock.c @@ -7,12 +7,12 @@ #define UNUSED #endif -static void uc_timeofday_now(struct UCoreClock *uclock UNUSED, struct timeval *tv) +static void uc_timeofday_now(const struct UCoreClock *uclock UNUSED, struct timeval *tv) { gettimeofday(tv, NULL); } -static void uc_time_now(struct UCoreClock *uclock UNUSED, struct timeval *tv) +static void uc_time_now(const struct UCoreClock *uclock UNUSED, struct timeval *tv) { tv->tv_sec = time(NULL); tv->tv_usec = 0; @@ -28,11 +28,11 @@ struct UCoreClock uc_time_clock = { .now = uc_time_now, }; -static void uc_cached_clock_now(struct UCoreClock *uclock, +static void uc_cached_clock_now(const struct UCoreClock *uclock, struct timeval *tv) { - struct UCoreCachedClock *cached_clock; - cached_clock = UC_CONTAINER_OF(uclock, struct UCoreCachedClock, clock), + const struct UCoreCachedClock *cached_clock; + cached_clock = UC_CONST_CONTAINER_OF(uclock, const struct UCoreCachedClock, clock), *tv = cached_clock->cache; } @@ -52,10 +52,10 @@ void uc_cached_clock_update(struct UCoreCachedClock *uclock) uclock->real_clock->now(&uclock->clock, &uclock->cache); } -static void uc_settable_clock_now(struct UCoreClock *uclock, struct timeval *tv) +static void uc_settable_clock_now(const struct UCoreClock *uclock, struct timeval *tv) { - struct UCoreSettableClock *cached_clock; - cached_clock = UC_CONTAINER_OF(uclock, struct UCoreSettableClock, clock), + const struct UCoreSettableClock *cached_clock; + cached_clock = UC_CONST_CONTAINER_OF(uclock, const struct UCoreSettableClock, clock), *tv = cached_clock->now; } From 7dbdec1d5bc1bf325b43e239b66703be38d65c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Fri, 30 Jan 2015 00:51:38 +0100 Subject: [PATCH 24/49] Initial mkdir -p function --- src/mkdirp.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/mkdirp.c diff --git a/src/mkdirp.c b/src/mkdirp.c new file mode 100644 index 0000000..7deed44 --- /dev/null +++ b/src/mkdirp.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include + +int uc_mkdir_p(const char *full_path, mode_t mode) +{ + struct stat st; + int rc = 0; + char *path; + char *p; + + if (full_path == NULL || full_path[0] == 0) { + + errno = EINVAL; + return -1; + } + + rc = stat(full_path, &st); + if (rc == 0) { //already exists + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + return -1; + } + if (st.st_mode != (mode | S_IFDIR) && chmod(full_path, mode) != 0) { + return -1; + } + } + + path = strdup(full_path); + if (path == NULL) { + return -1; + } + + //skip leading / + for (p = path; *p == '/'; p++) + ; + + for (;;) { + p = strchr(p, '/'); + if (p == NULL) { + break; + } + + *p = 0; + + rc = stat(path, &st); + if (rc != 0) { //doesn't exist + if (mkdir(path, mode) != 0) { + free(path); + return -1; + } + } else if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + free(path); + return -1; + } else { //dir already exist + + if (st.st_mode != (mode | S_IFDIR) && chmod(path, mode) != 0) { + free(path); + return -1; + } + } + + //in case of multiple / , e.g. foo//bar + *p = '/'; + for (; *p == '/'; p++) + ; + } + + //last part, in case full_path does not end with a / + rc = stat(path, &st); + if (rc != 0) { + rc = mkdir(path, mode); + } + + free(path); + + return rc; +} + + +int main(int argc, char *argv[]) +{ + uc_mkdir_p("a/b//c/d", 0777); +} From a522c55155a1e9bbb127cd1880992afcf8c3eece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Fri, 30 Jan 2015 20:50:50 +0100 Subject: [PATCH 25/49] Finalize mkdirp --- src/mkdirp.c | 74 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/src/mkdirp.c b/src/mkdirp.c index 7deed44..009147e 100644 --- a/src/mkdirp.c +++ b/src/mkdirp.c @@ -5,15 +5,40 @@ #include #include + +static int uc_mkdir(const char *full_path, mode_t mode) +{ + struct stat st; + int rc; + int created = 0; + + rc = stat(full_path, &st); + if (rc == -1 && errno == ENOENT) { + rc = mkdir(full_path, mode); + if (rc == -1 && errno != EEXIST) { + return -1; + } + } else if (rc == 0) { + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + return -1; + } + } else { + return -1; + } + + return 0; +} + int uc_mkdir_p(const char *full_path, mode_t mode) { struct stat st; - int rc = 0; + int rc; char *path; char *p; + int create_final = 1; if (full_path == NULL || full_path[0] == 0) { - errno = EINVAL; return -1; } @@ -24,9 +49,8 @@ int uc_mkdir_p(const char *full_path, mode_t mode) errno = ENOTDIR; return -1; } - if (st.st_mode != (mode | S_IFDIR) && chmod(full_path, mode) != 0) { - return -1; - } + + return 0; } path = strdup(full_path); @@ -46,34 +70,28 @@ int uc_mkdir_p(const char *full_path, mode_t mode) *p = 0; - rc = stat(path, &st); - if (rc != 0) { //doesn't exist - if (mkdir(path, mode) != 0) { - free(path); - return -1; - } - } else if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - free(path); - return -1; - } else { //dir already exist - - if (st.st_mode != (mode | S_IFDIR) && chmod(path, mode) != 0) { - free(path); - return -1; - } + rc = uc_mkdir(path, mode); + if (rc != 0) { + free(path); + return -1; } - //in case of multiple / , e.g. foo//bar *p = '/'; + //in case of multiple / , e.g. foo//bar for (; *p == '/'; p++) ; + + if (*p == 0) { + create_final = 0; + break; + } } //last part, in case full_path does not end with a / - rc = stat(path, &st); - if (rc != 0) { - rc = mkdir(path, mode); + if (create_final) { + rc = uc_mkdir(path, mode); + } else { + rc = 0; } free(path); @@ -82,7 +100,9 @@ int uc_mkdir_p(const char *full_path, mode_t mode) } -int main(int argc, char *argv[]) +int main() { - uc_mkdir_p("a/b//c/d", 0777); + int rc = uc_mkdir_p("/tmp/a///", 0777); + printf("rc = %d\n", rc); } + From 7e1114c09b92305ad794248462d25a899db9f8e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 10 Feb 2015 20:45:14 +0100 Subject: [PATCH 26/49] Use function names that make more sense --- include/ucore/time.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/ucore/time.h b/include/ucore/time.h index 607bd44..e643f12 100644 --- a/include/ucore/time.h +++ b/include/ucore/time.h @@ -59,17 +59,17 @@ struct timespec *uc_tssub(struct timespec *dst, const struct timespec *a, const */ int uc_tscmp(const struct timespec *a, const struct timespec *b); -static inline uint64_t uc_tv2msec(const struct timeval *t) +static inline uint64_t uc_tv2milisec(const struct timeval *t) { return t->tv_sec * 1000 + t->tv_usec / 1000; } -static inline uint64_t uc_ts2msec(const struct timespec *t) +static inline uint64_t uc_ts2milisec(const struct timespec *t) { return t->tv_sec * 1000 + t->tv_nsec / 10000000; } -static inline uint64_t uc_ts2nsec(const struct timespec *t) +static inline uint64_t uc_ts2nanosec(const struct timespec *t) { return t->tv_sec * 1000000000ULL + t->tv_nsec; } From aeee4de26a836ce58135a400ba4603c261142694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 10 Feb 2015 20:45:40 +0100 Subject: [PATCH 27/49] Remove main() function --- src/mkdirp.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/mkdirp.c b/src/mkdirp.c index 009147e..93313e7 100644 --- a/src/mkdirp.c +++ b/src/mkdirp.c @@ -10,7 +10,6 @@ static int uc_mkdir(const char *full_path, mode_t mode) { struct stat st; int rc; - int created = 0; rc = stat(full_path, &st); if (rc == -1 && errno == ENOENT) { @@ -99,10 +98,3 @@ int uc_mkdir_p(const char *full_path, mode_t mode) return rc; } - -int main() -{ - int rc = uc_mkdir_p("/tmp/a///", 0777); - printf("rc = %d\n", rc); -} - From 83ce414beb318e846215fe7260821fe86e451f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 10 Feb 2015 20:57:36 +0100 Subject: [PATCH 28/49] make array parameter const --- include/ucore/bitvec.h | 2 +- src/bitvec.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ucore/bitvec.h b/include/ucore/bitvec.h index a3e224b..bb5dfe1 100644 --- a/include/ucore/bitvec.h +++ b/include/ucore/bitvec.h @@ -71,7 +71,7 @@ void uc_bv_set_all(struct UCBitVec *v); * int a[] = {0,1,1,1,0}; * set_bits_from_array(v,a,5); * */ -void uc_bv_set_bits_from_array(struct UCBitVec *v,char *array,size_t array_len); +void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len); #ifdef __cplusplus diff --git a/src/bitvec.c b/src/bitvec.c index 8286d36..cd73536 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -63,7 +63,7 @@ void uc_bv_set_bit(struct UCBitVec *v,int b) v->vec[bit_index(b)] |= 1UL << (bit_offset(b)); } -void uc_bv_set_bits_from_array(struct UCBitVec *v,char *array,size_t array_len) +void uc_bv_set_bits_from_array(struct UCBitVec *v,const char *array,size_t array_len) { size_t i; From d187c1d63be85ae0d0f7720a0b449de870c3723f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 10 Feb 2015 21:00:57 +0100 Subject: [PATCH 29/49] Clarify that uc_read_fd always close() the descriptor --- include/ucore/read_file.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/ucore/read_file.h b/include/ucore/read_file.h index e105b45..9d83a46 100644 --- a/include/ucore/read_file.h +++ b/include/ucore/read_file.h @@ -25,6 +25,8 @@ uc_read_file(const char *file_name, size_t *length, size_t max); * @see uc_read_file * This is similar but reads from a file descriptor, * of any type as long as it supports the read() call. + * + * uc_read_fd close() the fd in all cases before it returns */ char * uc_read_fd(int fd, size_t *length, size_t max); From c90ad5e257e99f3d382afc93596e7d75c65c2266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 10 Feb 2015 21:46:08 +0100 Subject: [PATCH 30/49] There's no good reason to not always reset the file size after re-opening --- src/logging.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/logging.c b/src/logging.c index c235546..1301bc8 100644 --- a/src/logging.c +++ b/src/logging.c @@ -447,10 +447,12 @@ int uc_log_reopen_files(void) UC_TAILQ_FOREACH_CONTAINER(dest, entry, &g_destinations) { if (dest->dest_type == UC_LDEST_FILE) { - rc = uc_log_reopen_file(dest); - if (rc == 0) { - dest->type.file.size = 0; + int r_rc; + r_rc = uc_log_reopen_file(dest); + if (r_rc != 0) { + rc = r_rc; } + dest->type.file.size = 0; } } @@ -633,7 +635,6 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest) char new_filename[_POSIX_PATH_MAX * 2]; char old_filename[_POSIX_PATH_MAX * 2]; unsigned int i; - int rc; if (dest->type.file.file_name == NULL) { return; @@ -653,10 +654,8 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest) rename(dest->type.file.file_name, new_filename); //re-open current file - rc = uc_log_reopen_file(dest); - if (rc == 0) { - dest->type.file.size = 0; - } + uc_log_reopen_file(dest); + dest->type.file.size = 0; return; } From db21dc41001adf978cffc5578d461d15720a2645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 11 Feb 2015 22:20:07 +0100 Subject: [PATCH 31/49] use %u instead of %d in file name format string --- src/logging.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logging.c b/src/logging.c index 1301bc8..301f5e5 100644 --- a/src/logging.c +++ b/src/logging.c @@ -643,8 +643,8 @@ static void uc_log_file_rotate_size(struct UCLogDestination *dest) //rotate existing .num files i = dest->type.file.rotate.size_settings.num_files -1; while (i > 0) { - snprintf(new_filename, sizeof new_filename, "%s.%d", dest->type.file.file_name, i); - snprintf(old_filename, sizeof old_filename, "%s.%d", dest->type.file.file_name, i - 1); + snprintf(new_filename, sizeof new_filename, "%s.%u", dest->type.file.file_name, i); + snprintf(old_filename, sizeof old_filename, "%s.%u", dest->type.file.file_name, i - 1); rename(old_filename, new_filename); i--; } From 20a01e49135a128c05d23fe68d4e2bce10f90c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 11 Feb 2015 23:10:49 +0100 Subject: [PATCH 32/49] Attempt at packagin the binary install --- .gitignore | 2 ++ SConstruct | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bd5cecc..603593c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ tags doc/ log_subdir/ coverage/ +install/ +libucore-* diff --git a/SConstruct b/SConstruct index 160a212..40e4f5a 100644 --- a/SConstruct +++ b/SConstruct @@ -150,6 +150,11 @@ subdirs = [ ] for subdir in subdirs: - SConscript(subdir + '/SConscript', variant_dir='#build/' + subdir, src_dir='#'+subdir, duplicate=0) + env.SConscript(subdir + '/SConscript', variant_dir='#build/' + subdir, src_dir='#'+subdir, duplicate=0) + +distfile='libucore-' + version_info['version_str'] + '.tar.gz' +distcmd = env.Tar(distfile,'install', TARFLAGS='-cz') +env.Alias('dist', distcmd) +env.Depends('dist', 'install') env.Default('src') From 61cec258e310e9492a03729184445b88d6de6d0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 15 Feb 2015 21:37:13 +0100 Subject: [PATCH 33/49] Add tar.gz binary package target to scons. Invoke with scons --install_sandbox=XXX package --- SConstruct | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/SConstruct b/SConstruct index 40e4f5a..b79ca22 100644 --- a/SConstruct +++ b/SConstruct @@ -89,7 +89,7 @@ def InstallPerm(env, dest, files, perm): return obj -env = Environment(tools = ['default', 'textfile']) +env = Environment(tools = ['default', 'textfile', 'packaging']) #allow shell environment to override compiler if os.environ.has_key('CC'): @@ -152,9 +152,16 @@ subdirs = [ for subdir in subdirs: env.SConscript(subdir + '/SConscript', variant_dir='#build/' + subdir, src_dir='#'+subdir, duplicate=0) -distfile='libucore-' + version_info['version_str'] + '.tar.gz' -distcmd = env.Tar(distfile,'install', TARFLAGS='-cz') -env.Alias('dist', distcmd) -env.Depends('dist', 'install') +env.Package(NAME = 'libucore', + VERSION = version_info['version_str'] + '.0', + PACKAGEVERSION = 0, + PACKAGETYPE = 'targz', + LICENSE = 'BSD', + SUMMARY = 'libucore is a C library of misc useful stuff including an eventloop, timer support and various data-structures.', + DESCRIPTION = 'libucore is a C library of misc useful stuff including an eventloop, timer support and various data-structures.', + X_RPM_GROUP = 'Development/Libraries' + + +) env.Default('src') From 610e4c89a7480877b81d1eba2aad06f9eb8e6840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 15 Feb 2015 21:47:40 +0100 Subject: [PATCH 34/49] Add comment: scons Paackage() bugs out if the VERSION does not end with a digit. --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index b79ca22..1686d1c 100644 --- a/SConstruct +++ b/SConstruct @@ -153,7 +153,7 @@ for subdir in subdirs: env.SConscript(subdir + '/SConscript', variant_dir='#build/' + subdir, src_dir='#'+subdir, duplicate=0) env.Package(NAME = 'libucore', - VERSION = version_info['version_str'] + '.0', + VERSION = version_info['version_str'] + '.0', #Trailing .0 is needed cause a SCons bug PACKAGEVERSION = 0, PACKAGETYPE = 'targz', LICENSE = 'BSD', From a55139aba614a9eb2799b334e0eac555dbf2d3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 15 Feb 2015 23:56:31 +0100 Subject: [PATCH 35/49] Work around the scons Package() VERSION attribute by specifying the target and source explicitly --- SConstruct | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/SConstruct b/SConstruct index 1686d1c..d52dec5 100644 --- a/SConstruct +++ b/SConstruct @@ -152,16 +152,16 @@ subdirs = [ for subdir in subdirs: env.SConscript(subdir + '/SConscript', variant_dir='#build/' + subdir, src_dir='#'+subdir, duplicate=0) -env.Package(NAME = 'libucore', - VERSION = version_info['version_str'] + '.0', #Trailing .0 is needed cause a SCons bug - PACKAGEVERSION = 0, - PACKAGETYPE = 'targz', - LICENSE = 'BSD', - SUMMARY = 'libucore is a C library of misc useful stuff including an eventloop, timer support and various data-structures.', - DESCRIPTION = 'libucore is a C library of misc useful stuff including an eventloop, timer support and various data-structures.', - X_RPM_GROUP = 'Development/Libraries' - - +env.Package(target = 'libucore-' + version_info['version_str'] + '.tar.gz', + source = env.FindInstalledFiles(), + NAME = 'libucore', + VERSION = version_info['version_str'], + PACKAGEVERSION = 0, + PACKAGETYPE = 'targz', + LICENSE = 'BSD', + SUMMARY = 'libucore is a C library of misc useful stuff including an eventloop, timer support and various data-structures.', + DESCRIPTION = 'libucore is a C library of misc useful stuff including an eventloop, timer support and various data-structures.', + X_RPM_GROUP = 'Development/Libraries' ) env.Default('src') From c6318c079dbfe51157d827341bd390d7e7f2b6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sat, 4 Apr 2015 23:29:27 +0200 Subject: [PATCH 36/49] Re-format code to avoid overly long lines and declarations --- include/ucore/clock.h | 6 +++--- include/ucore/htable.h | 3 ++- include/ucore/logging.h | 18 +++++++++++++----- include/ucore/mbuf.h | 3 ++- include/ucore/restart_counter.h | 3 +-- include/ucore/string.h | 12 +++++++++--- include/ucore/threadqueue.h | 26 +++++++++++++++++++------- include/ucore/ticket_lock.h | 4 +++- include/ucore/timers.h | 19 +++++++++++-------- src/heapsort.c | 4 ++-- src/hex.c | 5 ++++- src/logging.c | 5 ++++- src/mbuf.c | 6 +++++- src/restart_counter.c | 3 +-- src/supervisor.c | 15 ++++++++++----- src/threadqueue.c | 4 ++-- src/ticket_lock.c | 4 +++- 17 files changed, 94 insertions(+), 46 deletions(-) diff --git a/include/ucore/clock.h b/include/ucore/clock.h index 26aba2e..1f0ea52 100644 --- a/include/ucore/clock.h +++ b/include/ucore/clock.h @@ -82,7 +82,7 @@ extern struct UCoreClock uc_time_clock; * */ void uc_cached_clock_init(struct UCoreCachedClock *uclock, - struct UCoreClock *real_clock); + struct UCoreClock *real_clock); /** Update the cached clock from the real_clock */ @@ -103,7 +103,7 @@ void uc_settable_clock_init(struct UCoreSettableClock *uclock); * @param tv new timeval to set the clock to **/ void uc_settable_clock_set_tv(struct UCoreSettableClock *uclock, - const struct timeval *tv); + const struct timeval *tv); /** * Set the new time this clock will return @@ -114,7 +114,7 @@ void uc_settable_clock_set_tv(struct UCoreSettableClock *uclock, * @param usecs microseconds portion of the clock to set. **/ void uc_settable_clock_set(struct UCoreSettableClock *uclock, - time_t secs, suseconds_t usecs); + time_t secs, suseconds_t usecs); #ifdef __cplusplus } diff --git a/include/ucore/htable.h b/include/ucore/htable.h index 46e4168..5d9fa2c 100644 --- a/include/ucore/htable.h +++ b/include/ucore/htable.h @@ -73,7 +73,8 @@ static inline size_t uc_htable_bucket(const struct UHTable *table, size_t hash) * @param table table * @param hash hash */ -static inline struct UHNode *uc_htable_first_bucket(const struct UHTable *table, size_t hash) +static inline struct UHNode *uc_htable_first_bucket(const struct UHTable *table, + size_t hash) { size_t bucket = uc_htable_bucket(table, hash); diff --git a/include/ucore/logging.h b/include/ucore/logging.h index b7800ed..21402f4 100644 --- a/include/ucore/logging.h +++ b/include/ucore/logging.h @@ -171,7 +171,8 @@ const char *uc_ll_2_str(enum UC_LOG_LEVEL l); * @return An opaque uc_log_destination that can be added as a destination to * the ucore logging system */ -struct UCLogDestination *uc_log_new_stderr(enum UC_LOG_LEVEL log_level, int log_location); +struct UCLogDestination *uc_log_new_stderr(enum UC_LOG_LEVEL log_level, + int log_location); /* creates a new uc_log_destination for logging to syslog * @@ -184,7 +185,10 @@ struct UCLogDestination *uc_log_new_stderr(enum UC_LOG_LEVEL log_level, int log_ * @return An opaque uc_log_destination that can be added as a destination to * the ucore logging system */ -struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, enum UC_LOG_LEVEL log_level, int log_location); +struct UCLogDestination *uc_log_new_syslog(const char *ident, + int facility, + enum UC_LOG_LEVEL log_level, + int log_location); /* creates a new uc_log_destination for printing on stderr. * @@ -195,7 +199,9 @@ struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, enum * @param return An opaque uc_log_destination that can be added as a destination to * the ucore logging system */ -struct UCLogDestination *uc_log_new_file(const char *filename, enum UC_LOG_LEVEL log_level, int log_location); +struct UCLogDestination *uc_log_new_file(const char *filename, + enum UC_LOG_LEVEL log_level, + int log_location); /** Add a uc_log_destination to the logging system. * @@ -216,7 +222,8 @@ void uc_log_remove_destination(struct UCLogDestination *dest); * @param dest destination for which to set the log level * @param level The new log level */ -void uc_log_destination_set_loglevel(struct UCLogDestination *dest, enum UC_LOG_LEVEL level); +void uc_log_destination_set_loglevel(struct UCLogDestination *dest, + enum UC_LOG_LEVEL level); /** Change whether to log the location (file/line no.) of logging * output on a destination, @@ -224,7 +231,8 @@ void uc_log_destination_set_loglevel(struct UCLogDestination *dest, enum UC_LOG_ * @param dest log destination to change * @param log_location 1=log the locaton, 0=don't log the location */ -void uc_log_destination_set_log_location(struct UCLogDestination *dest, int log_location); +void uc_log_destination_set_log_location(struct UCLogDestination *dest, + int log_location); /** Sets the log rotation settings. * Does nothing if the destination is not a UC_LDEST_FILE, or the policy is invalid. diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index f6a1767..704cbe6 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -127,7 +127,8 @@ struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf); * @param headroom the headroom in the buffer * @param flags The appropriate UC_MBUF_FLAGS */ -void uc_mbuf_init(struct MBuf *mbuf, uint8_t *restrict buf, uint32_t len, uint32_t headroom, uint32_t flags); +void uc_mbuf_init(struct MBuf *mbuf, uint8_t *restrict buf, uint32_t len, + uint32_t headroom, uint32_t flags); /** Zero out all the data in this mbuf, including the headroom * diff --git a/include/ucore/restart_counter.h b/include/ucore/restart_counter.h index 806251e..502931f 100644 --- a/include/ucore/restart_counter.h +++ b/include/ucore/restart_counter.h @@ -54,8 +54,7 @@ typedef enum { * @param filename the filename to use to keep track of the state * @param flags one of UC_RC_FL_XX */ -UCRCResult uc_restart_counter_init( - struct UCRestartCounter *counter, +UCRCResult uc_restart_counter_init(struct UCRestartCounter *counter, const char *filename, unsigned int flags); diff --git a/include/ucore/string.h b/include/ucore/string.h index f1269fb..ccdb53d 100644 --- a/include/ucore/string.h +++ b/include/ucore/string.h @@ -36,7 +36,9 @@ uint8_t* uc_hex_decode(const char *restrict in, size_t maxlen,uint8_t *restrict /** As uc_hex_encode , but inserts the @delim string between each converted * byte (each 2 hex chars) */ -char* uc_hex_encode_delim(const uint8_t *restrict in, size_t inlen, char *restrict out, int outlen, const char *restrict delim); +char* uc_hex_encode_delim(const uint8_t *restrict in, size_t inlen, + char *restrict out, int outlen, + const char *restrict delim); /** * Convert the string to lowercase, calls tolower() on each char. @@ -67,7 +69,9 @@ void uc_str_toupper(char *s); * if the number of ASCII digits is odd. This would usually be 0x0 or 0xf. * @return the number of bytes written to bcdout */ -size_t uc_ascii2bcd(const char *restrict ascii, unsigned char *restrict bcdout, unsigned char filler); +size_t uc_ascii2bcd(const char *restrict ascii, + unsigned char *restrict bcdout, + unsigned char filler); /** Convert the BCD digits to ascii. * The resulting ascii string is 0 terminated. @@ -77,7 +81,9 @@ size_t uc_ascii2bcd(const char *restrict ascii, unsigned char *restrict bcdout, * @param asciiout buffer to place ASCII in, must be UC_ASCII_LEN(bcdlen)+1 big * @return the number of characters written to bcdout (this will always be UC_ASCII_LEN(bcdlen) */ -size_t uc_bcd2ascii(const unsigned char *restrict bcd, size_t bcdlen, char *restrict asciiout); +size_t uc_bcd2ascii(const unsigned char *restrict bcd, + size_t bcdlen, + char *restrict asciiout); /** uc_sprintb for converting the values into ascii bit representation * e.g. 0x3 -> "00000011". The result must be able to hold the max number diff --git a/include/ucore/threadqueue.h b/include/ucore/threadqueue.h index a85932f..9fd60fd 100644 --- a/include/ucore/threadqueue.h +++ b/include/ucore/threadqueue.h @@ -174,13 +174,16 @@ int uc_thread_queue_init(struct uc_threadqueue *queue, unsigned int max_elements * @return 0 on succes ENOMEM if out of memory EINVAL if queue is NULL, ETIMEDOUT if timeout occured or other * errno values if pthread functions failed. */ -int uc_thread_queue_tryadd(struct uc_threadqueue *queue, const struct timespec *timeout, struct uc_threadmsg *msg); +int uc_thread_queue_tryadd(struct uc_threadqueue *queue, + const struct timespec *timeout, + struct uc_threadmsg *msg); /** * Like uc_thread_queue_add but will wait indefintly. * @see uc_thread_queue_add */ -static inline int uc_thread_queue_add(struct uc_threadqueue *queue, struct uc_threadmsg *msg) +static inline int uc_thread_queue_add(struct uc_threadqueue *queue, + struct uc_threadmsg *msg) { return uc_thread_queue_tryadd(queue, NULL, msg); } @@ -207,14 +210,17 @@ static inline int uc_thread_queue_add(struct uc_threadqueue *queue, struct uc_th * * @return 0 on success EINVAL if queue is NULL ETIMEDOUT if timeout occurs */ -int uc_thread_queue_tryget(struct uc_threadqueue *queue, const struct timespec *timeout, struct uc_threadmsg **msg); +int uc_thread_queue_tryget(struct uc_threadqueue *queue, + const struct timespec *timeout, + struct uc_threadmsg **msg); /** * Like uc_thread_queue_tryget, but will wait indefintly for an item * to become available * @see uc_thread_queue_tryget */ -static inline int uc_thread_queue_get(struct uc_threadqueue *queue, struct uc_threadmsg **msg) +static inline int uc_thread_queue_get(struct uc_threadqueue *queue, + struct uc_threadmsg **msg) { return uc_thread_queue_tryget(queue, NULL, msg); } @@ -246,7 +252,9 @@ unsigned int uc_thread_queue_length( struct uc_threadqueue *queue ); * @param cookie pointer passed back to the uc_thread_queue_walk_func * @return 0 on success EINVAL if queue is NULL EBUSY if someone is holding any locks on the queue */ -int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func, void *cookie); +int uc_thread_queue_destroy(struct uc_threadqueue *queue, + uc_thread_queue_walk_func free_func, + void *cookie); /** * Walk the elements of the queue, intended for debugging @@ -261,7 +269,9 @@ int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_f * The function must not in anyway interact with the queue. * @return 0 on success */ -int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func walk_func, void *cookie); +int uc_thread_queue_walk(struct uc_threadqueue *queue, + uc_thread_queue_walk_func walk_func, + void *cookie); /** @@ -275,7 +285,9 @@ int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func * @param cookie pointer passed back to the uc_thread_queue_walk_func * @return 0 on success */ -int uc_thread_queue_clear(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func, void *cookie); +int uc_thread_queue_clear(struct uc_threadqueue *queue, + uc_thread_queue_walk_func free_func, + void *cookie); /** diff --git a/include/ucore/ticket_lock.h b/include/ucore/ticket_lock.h index f68c0a2..c7beb5a 100644 --- a/include/ucore/ticket_lock.h +++ b/include/ucore/ticket_lock.h @@ -32,7 +32,9 @@ int uc_ticket_lock_init(struct UCTicketLock *lock); * * @return 0 on success, errno value on failure */ -int uc_ticket_lock_init_ex(struct UCTicketLock *lock, pthread_mutexattr_t *mattr, pthread_condattr_t *cattr); +int uc_ticket_lock_init_ex(struct UCTicketLock *lock, + pthread_mutexattr_t *mattr, + pthread_condattr_t *cattr); /** Acquire the lock */ diff --git a/include/ucore/timers.h b/include/ucore/timers.h index ecdd2e0..4385298 100644 --- a/include/ucore/timers.h +++ b/include/ucore/timers.h @@ -46,8 +46,9 @@ typedef void (*uc_timer_cb)(struct UCTimers *timers, struct UCTimer *timer); struct UCTimer { //Internal members RBNode rb_node; //the RBNode will hold a data pointer to the - //the UCTimer it's a member of. We might get rid of that member, and use CONTAINER_OF - //to find the UCTimer from a RBNode (Or just cast it, it's the 1. member..) + //the UCTimer it's a member of. We might get rid of that + //member, and use CONTAINER_OF to find the UCTimer from + //a RBNode (Or just cast it, it's the 1. member..) //absolute time when the timer should be fired struct timeval timeout; @@ -73,7 +74,8 @@ struct UCTimers { RBTree timer_tree; struct UCoreClock *uclock; size_t seq; //used to generate unique timers - TAILQ_HEAD(, UCTimer) ready_list; //pending timers to be fired while inside uc_timers_run + TAILQ_HEAD(, UCTimer) ready_list; //pending timers to be fired while + //inside uc_timers_run }; /** Initialize a timer engine for use. @@ -103,8 +105,8 @@ void uc_timers_init_ex(struct UCTimers *t, struct UCoreClock *uclock); void uc_timers_add(struct UCTimers *timers, struct UCTimer *timer, int sec, int usec); /** Remove a timer. - * Note, the timer memory must have been zeroed out or the timer must have been added at least once - * before uc_timers_remove can be called on a UCTimer. + * Note, the timer memory must have been zeroed out or the timer must have been + * added at least once before uc_timers_remove can be called on a UCTimer. * uc_timers_remove does nothing if the timer has expired. * * @param timers timer engine to remove from @@ -131,7 +133,8 @@ size_t uc_timers_count(const struct UCTimers *timers); /** Check if a timer is running (i.e. hasn't expired and fired) * * @param timer timer to query - * @return 0 if the timer has expired (or was never added) non-0 if it's running (active or pending) + * @return 0 if the timer has expired (or was never added) non-0 if it's + * running (active or pending) */ int uc_timer_running(const struct UCTimer *timer); @@ -141,8 +144,8 @@ int uc_timer_running(const struct UCTimer *timer); * @param timers timer engine to run * @param now The curent time. The engine will fire all timers whose expiry time is * prior to this value. - * @return the number of timers fired, or negative if an error occured(presently no errors - * are possible and the return value is always >= 0 + * @return the number of timers fired, or negative if an error occured(presently + * no errors are possible and the return value is always >= 0 **/ int uc_timers_run(struct UCTimers *timers); diff --git a/src/heapsort.c b/src/heapsort.c index 45a56e5..25c65f1 100644 --- a/src/heapsort.c +++ b/src/heapsort.c @@ -3,7 +3,7 @@ static void uc_sift(unsigned char *base, size_t start, size_t count, size_t width, - uc_hs_cmp cmp, uc_hs_swp swap, void *cookie) +i uc_hs_cmp cmp, uc_hs_swp swap, void *cookie) { size_t root = start, child; @@ -27,7 +27,7 @@ uc_sift(unsigned char *base, size_t start, size_t count, size_t width, void uc_heapsort(void *base_, size_t count, size_t width, - uc_hs_cmp cmp, uc_hs_swp swap, void *cookie) + uc_hs_cmp cmp, uc_hs_swp swap, void *cookie) { long start; long end; diff --git a/src/hex.c b/src/hex.c index 1b01ad9..24d2b1f 100644 --- a/src/hex.c +++ b/src/hex.c @@ -28,7 +28,10 @@ uc_hex_encode(const uint8_t *restrict in, size_t len, char *restrict out) } char* -uc_hex_encode_delim(const uint8_t *restrict in, size_t inlen, char *restrict out, int outlen, const char *restrict delim) +uc_hex_encode_delim( + const uint8_t *restrict in, size_t inlen, + char *restrict out, int outlen, + const char *restrict delim) { size_t i; char *outp = out; diff --git a/src/logging.c b/src/logging.c index 301f5e5..fa716d7 100644 --- a/src/logging.c +++ b/src/logging.c @@ -198,7 +198,10 @@ struct UCLogDestination *uc_log_new_stderr(enum UC_LOG_LEVEL log_level, int log_ return dest; } -struct UCLogDestination *uc_log_new_syslog(const char *ident, int facility, enum UC_LOG_LEVEL log_level, int log_location) +struct UCLogDestination *uc_log_new_syslog(const char *ident, + int facility, + enum UC_LOG_LEVEL log_level, + int log_location) { struct UCLogDestination *dest = calloc(1, sizeof *dest); char *id; diff --git a/src/mbuf.c b/src/mbuf.c index b4ab023..7fa8abc 100644 --- a/src/mbuf.c +++ b/src/mbuf.c @@ -40,7 +40,11 @@ uint8_t *uc_mbuf_pull(struct MBuf *mbuf, uint32_t size) return data; } -void uc_mbuf_init(struct MBuf *mbuf, uint8_t *restrict buf, uint32_t len, uint32_t headroom, uint32_t flags) +void uc_mbuf_init(struct MBuf *mbuf, + uint8_t *restrict buf, + uint32_t len, + uint32_t headroom, + uint32_t flags) { mbuf->bufstart = buf; mbuf->p1 = mbuf->p2 = mbuf->p3 = mbuf->p4 = NULL; diff --git a/src/restart_counter.c b/src/restart_counter.c index b785844..b70c1d7 100644 --- a/src/restart_counter.c +++ b/src/restart_counter.c @@ -20,8 +20,7 @@ static UCRCResult uc_restart_counter_lock(int fd) return UC_RC_OK; } -UCRCResult uc_restart_counter_init( - struct UCRestartCounter *counter, +UCRCResult uc_restart_counter_init(struct UCRestartCounter *counter, const char *filename, unsigned int flags) { diff --git a/src/supervisor.c b/src/supervisor.c index 783ef7a..5efa924 100644 --- a/src/supervisor.c +++ b/src/supervisor.c @@ -66,18 +66,22 @@ again: } if (WIFSIGNALED(status)) { - syslog(LOG_ERR, "supervised process(pid %ld) exited cause of signal %d, status = 0x%X", (long)pid, WTERMSIG(status), status); + syslog(LOG_ERR, "supervised process(pid %ld) exited cause of signal %d, status = 0x%X", + (long)pid, WTERMSIG(status), status); return RESTART; } else if (WIFEXITED(status)) { - syslog(LOG_ERR, "supervised process(pid %ld) exited with code %d, status = 0x%X", (long)pid, WTERMSIG(status), status); + syslog(LOG_ERR, "supervised process(pid %ld) exited with code %d, status = 0x%X", + (long)pid, WTERMSIG(status), status); return RESTART; } /* Ok, can we ever get here ? */ - syslog(LOG_ERR, "waitpid of supervised process(pid %ld) status = 0x%X", (long)pid, status); + syslog(LOG_ERR, "waitpid of supervised process(pid %ld) status = 0x%X", + (long)pid, status); if (kill(pid, 0) == 0) { - syslog(LOG_ERR, "supervised process(pid %ld) seems to still be alive, not restarting", (long)pid); + syslog(LOG_ERR, "supervised process(pid %ld) seems to still be alive, not restarting", + (long)pid); goto again; } @@ -134,7 +138,8 @@ int uc_supervise(void) switch (cmd) { case CLEAN_EXIT: - syslog(LOG_INFO, "Terminating supervised pid %lu", (unsigned long)pid); + syslog(LOG_INFO, "Terminating supervised pid %lu", + (unsigned long)pid); kill_supervised_process(pid); wait(NULL); syslog(LOG_INFO, "Exiting"); diff --git a/src/threadqueue.c b/src/threadqueue.c index 32d01c3..95fe07e 100644 --- a/src/threadqueue.c +++ b/src/threadqueue.c @@ -281,8 +281,8 @@ unsigned int uc_thread_queue_length(struct uc_threadqueue *queue) } int uc_thread_queue_clear(struct uc_threadqueue *queue, - uc_thread_queue_walk_func free_func, - void *cookie) + uc_thread_queue_walk_func free_func, + void *cookie) { if (queue == NULL) { return EINVAL; diff --git a/src/ticket_lock.c b/src/ticket_lock.c index a5d5bfa..a58ab1f 100644 --- a/src/ticket_lock.c +++ b/src/ticket_lock.c @@ -13,7 +13,9 @@ int uc_ticket_lock_init(struct UCTicketLock *lock) return uc_ticket_lock_init_ex(lock, NULL, NULL); } -int uc_ticket_lock_init_ex(struct UCTicketLock *lock, pthread_mutexattr_t *mattr, pthread_condattr_t *cattr) +int uc_ticket_lock_init_ex(struct UCTicketLock *lock, + pthread_mutexattr_t *mattr, + pthread_condattr_t *cattr) { int rc; lock->queue_head = 0; From 2eacf252b7aa4f1b144dfdef2017db8e029ea913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Sun, 5 Apr 2015 13:14:16 +0200 Subject: [PATCH 37/49] Fix typo --- src/heapsort.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/heapsort.c b/src/heapsort.c index 25c65f1..8580a73 100644 --- a/src/heapsort.c +++ b/src/heapsort.c @@ -3,7 +3,7 @@ static void uc_sift(unsigned char *base, size_t start, size_t count, size_t width, -i uc_hs_cmp cmp, uc_hs_swp swap, void *cookie) + uc_hs_cmp cmp, uc_hs_swp swap, void *cookie) { size_t root = start, child; From 72dcd6e82c7803b88a601139ca5816fe3d83940d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Thu, 30 Apr 2015 16:36:15 +0200 Subject: [PATCH 38/49] Add not about the CK_FORK env variable --- test/test_runner.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_runner.c b/test/test_runner.c index 33b1ad4..264b135 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -91,6 +91,8 @@ main (int argc, char *argv[]) if (xml_output) srunner_set_xml(sr, "result.xml"); + //set the environment variable CK_FORK=no which means don't fork(). + //anything else means to fork() srunner_set_fork_status(sr, CK_FORK_GETENV); From 7f716e9ede9e8c0299c9bc297c3612099fa7227c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Thu, 30 Apr 2015 16:36:29 +0200 Subject: [PATCH 39/49] Add a few more dbuf tests --- test/test_dbuf.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test/test_dbuf.c b/test/test_dbuf.c index d0b6bc1..317f2ba 100644 --- a/test/test_dbuf.c +++ b/test/test_dbuf.c @@ -83,12 +83,90 @@ START_TEST (test_dbuf_take_fail) END_TEST +START_TEST (test_dbuf_take_all) + DBuf buf; + int rc; + + rc = uc_dbuf_init(&buf, 10); + + fail_if(rc != 0); + fail_if(uc_dbuf_buflen(&buf) != 10); + fail_if(uc_dbuf_remaining(&buf) != 10); + + strcpy((char *)buf.end, "12345679"); + uc_dbuf_added(&buf, 10); + fail_if(uc_dbuf_len(&buf) != 10); + fail_if(uc_dbuf_remaining(&buf) != 0); + + rc = uc_dbuf_take(&buf, 10); + fail_if(rc != 0); + fail_if(uc_dbuf_len(&buf) != 0); + fail_if(uc_dbuf_remaining(&buf) != 10); + + uc_dbuf_free(&buf); +END_TEST + +START_TEST (test_dbuf_add_ensure_take) + DBuf *buf; + int rc; + + int i; + buf = malloc(sizeof *buf); + fail_if(buf == NULL); + + + rc = uc_dbuf_init(buf, 10); + + fail_if(rc != 0); + fail_if(uc_dbuf_buflen(buf) != 10); + fail_if(uc_dbuf_remaining(buf) != 10); + + for (i = 0; i < 10; i++) { + rc = uc_dbuf_ensure(buf,10); + fail_if(rc != 0); + + uc_dbuf_added(buf, 2); + fail_if(uc_dbuf_len(buf) != 2); + fail_if(uc_dbuf_remaining(buf) != 8); + + uc_dbuf_added(buf, 8); + fail_if(uc_dbuf_len(buf) != 10); + fail_if(uc_dbuf_remaining(buf) != 0); + + rc = uc_dbuf_take(buf, 5); + fail_if(rc != 0); + fail_if(uc_dbuf_len(buf) != 5); + + rc = uc_dbuf_take(buf, 5); + fail_if(rc != 0); + fail_if(uc_dbuf_len(buf) != 0); + fail_if(uc_dbuf_remaining(buf) != 10); + } + + rc = uc_dbuf_ensure(buf,90); + fail_if(rc != 0); + //ok, dbuf adds the ensured capacity to the existing buflen + //so it becomes 100, not 90 even though the buffer is already empty + fail_if(uc_dbuf_remaining(buf) != 100, "remaining %zu", (uc_dbuf_remaining(buf))); + fail_if(uc_dbuf_buflen(buf) != 100); + memset(buf->end, 0xDE, 90); + uc_dbuf_added(buf, 90); + fail_if(uc_dbuf_remaining(buf) != 10); + + uc_dbuf_free(buf); + free(buf); +END_TEST + Suite *dbuf_suite(void) { Suite *s = suite_create("dbuf"); TCase *tc = tcase_create("dbuf tests"); tcase_add_test(tc, test_dbuf); + + tcase_add_test(tc, test_dbuf_take_all); + tcase_add_test(tc, test_dbuf_add_ensure_take); + #ifndef NDEBUG tcase_add_test_raise_signal(tc, test_dbuf_take_fail, SIGABRT); #else From 4a42c9a8deed2e40ee1b114d35ff5dccdcc843c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 4 May 2015 22:57:49 +0200 Subject: [PATCH 40/49] Improve mbuf documentation --- include/ucore/mbuf.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 704cbe6..9272568 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -24,16 +24,17 @@ @endverbatim * * Initially when empty, head == tail, and the length is 0. - * Data is added to the tail. + * Data can be added to the tailroom or the headroom. + * The data is the memory from (including) head to (excluding) tail. * * If head == bufstart, there is no headroom * if tail points one past the allocated space, there is no * tailroom (the buffer is full) * * Conventions: - * push - prepend data to the buffer (in the head room part) + * push - prepend data to the buffer in the head room part * (move head to the left) - * pull - remove data from the beginning of the message. + * pull - remove data from the beginning of the data * (move head to the right) * put - Add data to the buffer. * (move tail to the right) @@ -103,7 +104,12 @@ struct MBuf *uc_mbuf_new_inline_hr(uint32_t len, uint32_t headroom); /** As uc_mbuf_new_inline_hr, but without any headroom*/ #define uc_mbuf_new_inline(len) uc_mbuf_new_inline_hr((len), 0) -/** @param mbuf the mbuf to free. (passing NULL is a no-op)*/ +/** Free the memory of an mbuf and its data. + * If passing in NULL or an mbuf with a UC_MBUF_FL_STATIC flag, + * no action is taken. + * + * @param mbuf the mbuf to free. + */ void uc_mbuf_free(struct MBuf *mbuf); /** Create a new mbuf, with a copy of the data from the given @@ -117,9 +123,7 @@ struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf); /** Initialize an mbuf. This function is mostly used internally, * but can be used to e.g. create an mbuf based on a local array * (in which case UC_MBUF_FL_STATIC must be set), or other data - * whose memory is already allocated. - * - * The whole buffer must have len + headroom available data + * whose memory is already allocated. * The whole buffer must have len + headroom available data * * @param mbuf to initialise * @param buf start of the buffer @@ -130,7 +134,7 @@ struct MBuf *uc_mbuf_copy_data(struct MBuf *mbuf); void uc_mbuf_init(struct MBuf *mbuf, uint8_t *restrict buf, uint32_t len, uint32_t headroom, uint32_t flags); -/** Zero out all the data in this mbuf, including the headroom +/** Zero out all the data in this mbuf, including the headroom and tailroom * * @param mbuf mbuf to zero out */ From e922e60849d4c65b48072cda2a5fde13e761ad43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 5 May 2015 00:05:27 +0200 Subject: [PATCH 41/49] Fix uc_tailq_empty. It did not work prior to this. --- include/ucore/tailq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ucore/tailq.h b/include/ucore/tailq.h index ae6da60..c002ed3 100644 --- a/include/ucore/tailq.h +++ b/include/ucore/tailq.h @@ -59,7 +59,7 @@ static UC_INLINE void uc_tailq_init(struct TailQ *head) */ static UC_INLINE int uc_tailq_empty(const struct TailQ *head) { - return head->next == head->prev; + return head->next == head; } /** Insert the entry between prev and next From 5e2b1e2d0d11c911b6f91142b73e0b6ae8df9bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 5 May 2015 00:06:28 +0200 Subject: [PATCH 42/49] Add mbuf enqueue/dequeue functions --- include/ucore/mbuf.h | 14 +++++++++++++- src/mbuf.c | 18 ++++++++++++++++++ test/test_mbuf.c | 41 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/include/ucore/mbuf.h b/include/ucore/mbuf.h index 9272568..7939504 100644 --- a/include/ucore/mbuf.h +++ b/include/ucore/mbuf.h @@ -181,7 +181,7 @@ uint8_t *uc_mbuf_put(struct MBuf *mbuf, uint32_t size); * data in the buffer, retreating the head pointer by size butes * You need to insert the size bytes in the returned pointer. * - * @oaram size bytes to prepend to the buffer +w* @oaram size bytes to prepend to the buffer * @return NULL if the mbuf does not have enough headroom */ uint8_t *uc_mbuf_push(struct MBuf *mbuf, uint32_t size); @@ -214,4 +214,16 @@ static UC_INLINE uint8_t *uc_mbuf_head(struct MBuf* mbuf) return mbuf->head; } +/** Add the mbuf at the end of the tailq. + * This uses the tailQ entry member of the mbuf. + */ +void uc_mbuf_enqueue(struct MBuf *mbuf, struct TailQ *head); + +/** Remove and return the mbuf at the start of the tailq. + * @return the first mbuf in the queue, or NULL if ti isempty. + */ +struct MBuf *uc_mbuf_dequeue(struct TailQ *head); + + + #endif diff --git a/src/mbuf.c b/src/mbuf.c index 7fa8abc..4b729fb 100644 --- a/src/mbuf.c +++ b/src/mbuf.c @@ -203,3 +203,21 @@ int uc_mbuf_extend_tailroom(struct MBuf *mbuf, uint32_t len) return 0; } + +void uc_mbuf_enqueue(struct MBuf *mbuf, struct TailQ *head) +{ + uc_tailq_insert_tail(head, &mbuf->entry); +} + +struct MBuf *uc_mbuf_dequeue(struct TailQ *head) +{ + struct TailQ *q; + + if (uc_tailq_empty(head)) { + return NULL; + } + q = UC_TAILQ_FIRST(head); + uc_tailq_remove(q); + + return UC_TAILQ_CONTAINER(q, struct MBuf, entry); +} diff --git a/test/test_mbuf.c b/test/test_mbuf.c index be2df35..9b7464f 100644 --- a/test/test_mbuf.c +++ b/test/test_mbuf.c @@ -297,11 +297,49 @@ START_TEST (test_mbuf_extend_tailroom_wrong_type) END_TEST +START_TEST (test_mbuf_queue) + struct MBuf *m1; + struct MBuf *m2; + struct MBuf *q; + uint8_t *data1; + UC_TAILQ_HEAD(head); + + m1 = uc_mbuf_new_inline(10); + fail_if(m1 == NULL); + + data1 = uc_mbuf_put(m1, 10); + fail_if(data1 == NULL); + + strcpy((char*)data1, "123456789"); + + m2 = uc_mbuf_new_inline(10); + fail_if(m2 == NULL); + + data1 = uc_mbuf_put(m2, 10); + fail_if(data1 == NULL); + + strcpy((char*)data1, "987654321"); + + uc_mbuf_enqueue(m1, &head); + uc_mbuf_enqueue(m2, &head); + + q = uc_mbuf_dequeue(&head); + fail_if(strcmp((char*)uc_mbuf_head(q), "123456789") != 0); + + q = uc_mbuf_dequeue(&head); + fail_if(strcmp((char*)uc_mbuf_head(q), "987654321") != 0); + + fail_if(!uc_tailq_empty(&head)); + + uc_mbuf_free(m1); + uc_mbuf_free(m2); + +END_TEST Suite *mbuf_suite(void) { Suite *s = suite_create("mbuf"); - TCase *tc = tcase_create("mbuf tests"); + TCase *tc = tcase_create("mbuf tests"); tcase_add_test(tc, test_mbuf_new); tcase_add_test(tc, test_mbuf_new_inline); tcase_add_test(tc, test_mbuf_new_headroom); @@ -316,6 +354,7 @@ Suite *mbuf_suite(void) tcase_add_test(tc, test_mbuf_static); tcase_add_test(tc, test_mbuf_extend_tailroom); tcase_add_test(tc, test_mbuf_extend_tailroom_wrong_type); + tcase_add_test(tc, test_mbuf_queue); suite_add_tcase(s, tc); From 70d5c2b60066674a03d78683ce3afed8c4705d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 5 May 2015 00:08:47 +0200 Subject: [PATCH 43/49] Extend the mbuf queue test --- test/test_mbuf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test_mbuf.c b/test/test_mbuf.c index 9b7464f..fc37e43 100644 --- a/test/test_mbuf.c +++ b/test/test_mbuf.c @@ -331,6 +331,9 @@ START_TEST (test_mbuf_queue) fail_if(!uc_tailq_empty(&head)); + q = uc_mbuf_dequeue(&head); + fail_if(q != NULL); + uc_mbuf_free(m1); uc_mbuf_free(m2); From 99297b153c1f9b6db7096fbb58f5524b375ab4a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Tue, 5 May 2015 18:19:54 +0200 Subject: [PATCH 44/49] add usage() to the test_runner --- test/test_runner.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/test_runner.c b/test/test_runner.c index 264b135..b5a3691 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -61,6 +61,15 @@ static suite_func suites[] = { restart_counter_suite }; +void +usage(const char *progname) +{ + printf("Usage: %s [-h] [-k testcase] [-x]\n", progname); + puts("\t-h This help"); + puts("\t-k testcase Run the given testcase"); + puts("\t-x Ouput results in XML to the file result.xml"); +} + int main (int argc, char *argv[]) { @@ -68,7 +77,7 @@ main (int argc, char *argv[]) int c; const char *test_case = NULL; - while ((c = getopt(argc, argv, "xk:")) != -1) { + while ((c = getopt(argc, argv, "xk:h")) != -1) { switch (c) { case 'x': xml_output = 1; @@ -77,8 +86,11 @@ main (int argc, char *argv[]) test_case = optarg; break; default: - printf("Ignoring unknown option %c\n", c); - break; + printf("Unknown option %c\n", c); + /*fallthrough*/ + case 'h': + usage(argv[0]); + return 1; } } From bb426bfecd59fc2bb337da96b6b8a29cbe2a967b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 6 May 2015 18:28:05 +0200 Subject: [PATCH 45/49] Don't undef UC_INLINE in pack.h --- include/ucore/pack.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/ucore/pack.h b/include/ucore/pack.h index 889adcc..7c02a41 100644 --- a/include/ucore/pack.h +++ b/include/ucore/pack.h @@ -245,10 +245,5 @@ static UC_INLINE uint64_t uc_unpack_64_be(const uint8_t *r) return v; } - - -#undef UC_INLINE - - #endif From a7516141dd6ac29889d9ce32e4b36b3045bebf04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 6 May 2015 21:33:23 +0200 Subject: [PATCH 46/49] Fix dstr_own() when the dstr already holds a string. --- src/dstr.c | 2 +- test/test_dstr.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/dstr.c b/src/dstr.c index 90e49bc..a5ae33f 100644 --- a/src/dstr.c +++ b/src/dstr.c @@ -176,7 +176,7 @@ void uc_dstr_own(struct DStr *str, char *restrict s) size_t len = strlen(s); if (str->str) { - free(str); + free(str->str); } str->len = len; diff --git a/test/test_dstr.c b/test/test_dstr.c index f30a0a4..1c5e1a1 100644 --- a/test/test_dstr.c +++ b/test/test_dstr.c @@ -63,9 +63,20 @@ START_TEST (test_dstr_init) ck_assert_int_eq(rc, 0); ck_assert_int_eq(str.len, 2); ck_assert_str_eq(uc_dstr_str(&str), "He"); + uc_dstr_destroy(&str); END_TEST +START_TEST (test_dstr_own) + struct DStr str; + + uc_dstr_init_str(&str, "init"); + uc_dstr_own(&str, strdup("Hello !")); + ck_assert_int_eq(str.len, 7); + ck_assert_str_eq(uc_dstr_str(&str), "Hello !"); + + uc_dstr_destroy(&str); +END_TEST START_TEST (test_dstr_own_steal) struct DStr str; char *s; @@ -192,6 +203,7 @@ Suite *dstr_suite(void) TCase *tc = tcase_create("dstr tests"); tcase_add_test(tc, test_dstr_basics); tcase_add_test(tc, test_dstr_init); + tcase_add_test(tc, test_dstr_own); tcase_add_test(tc, test_dstr_own_steal); tcase_add_test(tc, test_dstr_trim); tcase_add_test(tc, test_dstr_replace); From a87558047bb3e187a6533680b9251bc9f3416883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 11 May 2015 23:09:40 +0200 Subject: [PATCH 47/49] Fix iomux_select_recalc_max, it went to an infinite loop. --- src/iomux_select.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/iomux_select.c b/src/iomux_select.c index fb1517a..bdf0029 100644 --- a/src/iomux_select.c +++ b/src/iomux_select.c @@ -27,15 +27,14 @@ static int iomux_select_update_events(struct IOMux *mux_, struct IOMuxFD *fd); static void iomux_select_recalc_max(struct IOMuxSelect *mux) { size_t i; + size_t n; mux->max_fd = -1; - for (i = 0; i < mux->num_descriptors; ) { + for (i = 0, n = 0; i < FD_SETSIZE && n < mux->num_descriptors; i++) { if (mux->descriptors[i] != NULL) { mux->max_fd = UC_MAX(mux->descriptors[i]->fd, mux->max_fd); - i++; + n++; } - - assert(i < FD_SETSIZE); } } From 4134482fdbf376848c5b8f6092f2e25282123d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 11 May 2015 23:17:30 +0200 Subject: [PATCH 48/49] Add iomux tests --- test/test_iomux.c | 127 +++++++++++++++++++++++++++++++++++++++++++++ test/test_runner.c | 4 +- 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 test/test_iomux.c diff --git a/test/test_iomux.c b/test/test_iomux.c new file mode 100644 index 0000000..ed4f10b --- /dev/null +++ b/test/test_iomux.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include "ucore/timers.h" +#include "ucore/iomux.h" +#include "ucore/clock.h" + + +static enum IOMUX_TYPE g_iomux_type = IOMUX_TYPE_DEFAULT; + +void set_iomux_type_select(void) +{ + g_iomux_type = IOMUX_TYPE_SELECT; +} + +void set_iomux_type_epoll(void) +{ + g_iomux_type = IOMUX_TYPE_EPOLL; +} + +static void simple_rcb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) +{ + char buf[64]; + ssize_t r; + + /** we should get here 2 times. first for reading the string, + * then for reading that the pipe has closed */ + + ck_assert_int_le(fd->cookie_int, 2); + fd->cookie_int++; + + r = read(fd->fd, buf, sizeof buf); + ck_assert(r >= 0); + + if (r > 0) { + ck_assert_int_eq(r, 5); + ck_assert(strncmp(buf, "Hello", 5) == 0); + } + + if (r == 0) { + int rc; + rc = iomux_unregister_fd(mux, fd); + ck_assert_int_eq(rc, 0); + close(fd->fd); + } +} + +static void simple_wcb(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event) +{ + ssize_t written; + int rc; + + ck_assert_int_eq(fd->cookie_int, 0); + fd->cookie_int = 1; + + written = write(fd->fd, "Hello", 5); + ck_assert_int_eq(written, 5); + + rc = iomux_unregister_fd(mux, fd); + ck_assert_int_eq(rc, 0); + + close(fd->fd); +} + + +START_TEST (test_iomux_pipe_simple) + struct IOMux *mux; + struct IOMuxFD rfd; + struct IOMuxFD wfd; + /** + * Simple test that writes a small string to a pipe + * and reads it back. This assumes the small write/read + * can be done with just 1 write/read call. + */ + + int pipefd[2]; + int rc; + + mux = iomux_create(g_iomux_type); + + rc = pipe(pipefd); + ck_assert_int_eq(rc, 0); + + memset(&rfd, 0, sizeof rfd); + memset(&wfd, 0, sizeof wfd); + + rfd.fd = pipefd[0]; + rfd.what = MUX_EV_READ; + rfd.callback = simple_rcb; + + wfd.fd = pipefd[1]; + wfd.what = MUX_EV_WRITE; + wfd.callback = simple_wcb; + + rc = iomux_register_fd(mux, &rfd); + ck_assert_int_eq(rc, 0); + + rc = iomux_register_fd(mux, &wfd); + ck_assert_int_eq(rc, 0); + + rc = iomux_run(mux); + ck_assert_int_eq(rc, 0); + + iomux_delete(mux); + +END_TEST + + +Suite *iomux_suite(void) +{ + Suite *s = suite_create("iomux"); + TCase *select_tc = tcase_create("iomux select tests"); + TCase *epoll_tc = tcase_create("iomux epoll tests"); + + tcase_add_test(select_tc, test_iomux_pipe_simple); + tcase_add_test(epoll_tc, test_iomux_pipe_simple); + + tcase_add_checked_fixture(select_tc, set_iomux_type_select, NULL); + + tcase_add_checked_fixture(epoll_tc, set_iomux_type_epoll, NULL); + + suite_add_tcase(s, select_tc); + suite_add_tcase(s, epoll_tc); + + return s; +} + diff --git a/test/test_runner.c b/test/test_runner.c index b5a3691..f95502c 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -32,6 +32,7 @@ extern Suite *dstr_suite(void); extern Suite *val_str_suite(void); extern Suite *ticket_lock_suite(void); extern Suite *restart_counter_suite(void); +extern Suite *iomux_suite(void); static suite_func suites[] = { bitvec_suite, @@ -58,7 +59,8 @@ static suite_func suites[] = { dstr_suite, val_str_suite, ticket_lock_suite, - restart_counter_suite + restart_counter_suite, + iomux_suite }; void From 7dd159aa6a23c1de6ebfe2d5bf48c16547b599ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 11 May 2015 23:36:23 +0200 Subject: [PATCH 49/49] Add TODO comment to iomux impl --- src/iomux_impl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/iomux_impl.h b/src/iomux_impl.h index ea51873..83dfeb5 100644 --- a/src/iomux_impl.h +++ b/src/iomux_impl.h @@ -43,6 +43,8 @@ struct IOMux { /* Used by mux implementations to hold their own data/instance */ void *instance; }; +//TODO - have iomux_xx_init embed struct IOMux and get rid of IOMux.instance +//for better cache friendiness int iomux_select_init(struct IOMux *mux); int iomux_epoll_init(struct IOMux *mux);