diff --git a/README.rst b/README.rst index 8229225..4f28a44 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ Vanilla Squad :Author: Daniel Walker -Version 4.1.0 was released on May 16, 2021. +Version 4.2.0 was released on May 24, 2021. Overview ======== @@ -20,9 +20,9 @@ size of the destination is zero, they return -1. Otherwise, they return the num written to the destination (NOT counting the terminator). If a -1 is not returned, then a terminator is guaranteed to be written to the destination. -**vasqIncSnprintf** and **vasqIncVsnprintf** function similarly except that they take pointers to the destination as -well as the size of the destination. Upon success, they adjust the destination and size so that subsequent -calls to these functions will pick up where the previous call left off. +**vasqIncSnprintf** and **vasqIncVsnprintf** function similarly except that they take pointers to the +destination as well as the size of the destination. Upon success, they adjust the destination and size so +that subsequent calls to these functions will pick up where the previous call left off. The % tokens recognized by these functions are @@ -53,13 +53,13 @@ Logging The provided logging levels (which are of type **vasqLogLevel_t**) are -* VASQ_LL_NONE -* VASQ_LL_ALWAYS -* VASQ_LL_CRITICAL -* VASQ_LL_ERROR -* VASQ_LL_WARNING -* VASQ_LL_INFO -* VASQ_LL_DEBUG +* **VASQ_LL_NONE** +* **VASQ_LL_ALWAYS** +* **VASQ_LL_CRITICAL** +* **VASQ_LL_ERROR** +* **VASQ_LL_WARNING** +* **VASQ_LL_INFO** +* **VASQ_LL_DEBUG** A logger handle is created by the **vasqLoggerCreate** function. Its signature is @@ -75,8 +75,11 @@ A logger handle is created by the **vasqLoggerCreate** function. Its signature vasqLogger **logger, // A pointer to the logger handle to be populated. ); -This function returns **VASQ_RET_OK** when successful and an error code otherwise (see include/vasq/definitions.h -for the values). +This function returns **VASQ_RET_OK** when successful and an error code otherwise (see +include/vasq/definitions.h for the values). + +**vasqLoggerCreate** calls **dup** on the provided file descriptor so that you may call **close** while still +maintaining logging. The new descriptor has **FD_CLOEXEC** set on it. The format string looks like a **printf** string and accepts the following % tokens: diff --git a/changelog b/changelog index 8711e19..7c37b36 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,6 @@ +4.2.0: + - vasqLoggerCreate now dups the file descriptor and sets FD_CLOEXEC on it. + 4.1.0: - Various logging limits are now configurable via config.h. - Added vasqExit. diff --git a/include/vasq/definitions.h b/include/vasq/definitions.h index 8e5f279..ba0d740 100644 --- a/include/vasq/definitions.h +++ b/include/vasq/definitions.h @@ -16,11 +16,14 @@ enum vasqRetValue { VASQ_RET_OK = 0, VASQ_RET_USAGE, + VASQ_RET_BAD_FORMAT, VASQ_RET_OUT_OF_MEMORY, + VASQ_RET_DUP_FAIL, + VASQ_RET_FCNTL_FAIL, VASQ_RET_UNUSED, }; -#define VASQ_VERSION "4.1.0" +#define VASQ_VERSION "4.2.0" #endif // VANILLA_SQUAD_DEFINITIONS_H diff --git a/source/logger.c b/source/logger.c index f2aa002..0687a41 100644 --- a/source/logger.c +++ b/source/logger.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -93,21 +94,56 @@ int vasqLoggerCreate(int fd, vasqLogLevel_t level, const char *format, vasqLoggerDataProcessor processor, void *user_data, vasqLogger **logger) { - if (fd < 0 || !logger || !format || !validLogFormat(format)) { + int new_fd, flags; + + if (fd < 0 || !logger || !format) { return VASQ_RET_USAGE; } + if (!validLogFormat(format)) { + return VASQ_RET_BAD_FORMAT; + } + *logger = malloc(sizeof(**logger)); if (!*logger) { return VASQ_RET_OUT_OF_MEMORY; } - (*logger)->fd = fd; + while (true) { + new_fd = dup(fd); + if (new_fd == -1) { + int local_errno = errno; + + switch (local_errno) { +#ifdef EBUSY + case EBUSY: +#endif + case EINTR: continue; + + default: + fprintf(stderr, "dup: %s", strerror(local_errno)); + free(*logger); + return VASQ_RET_DUP_FAIL; + } + } + else { + break; + } + } + + (*logger)->fd = new_fd; (*logger)->level = level; (*logger)->format = format; (*logger)->processor = processor; (*logger)->user_data = user_data; + flags = fcntl(new_fd, F_GETFD); + if (flags == -1 || fcntl(new_fd, F_SETFD, flags | FD_CLOEXEC) == -1) { + perror("fcntl"); + vasqLoggerFree(*logger); + return VASQ_RET_FCNTL_FAIL; + } + return VASQ_RET_OK; } @@ -115,6 +151,7 @@ void vasqLoggerFree(vasqLogger *logger) { if (logger) { + close(logger->fd); free(logger); } }