From ff1f6fb73432ae05e9dcc7c134c1cafe0c1c8b01 Mon Sep 17 00:00:00 2001 From: Laurence Withers Date: Sat, 26 Jul 2008 15:19:13 +0000 Subject: [PATCH] Add basic daemonitor build framework and logging infrastructure --- config | 2 + src/daemonitor/.params | 1 + src/daemonitor/000_TopSource.c | 20 ++++ src/daemonitor/100_io.c | 60 ++++++++++++ src/daemonitor/101_log.c | 163 +++++++++++++++++++++++++++++++ src/daemonitor/999_main.c | 20 ++++ src/daemonitor/build.app | 41 ++++++++ src/daemonitor/build.default | 1 + src/daemonitor/build.install | 1 + src/daemonitor/build.install-app | 12 +++ src/daemonitor/build.monolithic | 18 ++++ 11 files changed, 339 insertions(+) create mode 100644 src/daemonitor/.params create mode 100644 src/daemonitor/000_TopSource.c create mode 100644 src/daemonitor/100_io.c create mode 100644 src/daemonitor/101_log.c create mode 100644 src/daemonitor/999_main.c create mode 100644 src/daemonitor/build.app create mode 100644 src/daemonitor/build.default create mode 100644 src/daemonitor/build.install create mode 100644 src/daemonitor/build.install-app create mode 100644 src/daemonitor/build.monolithic diff --git a/config b/config index b185a64..ca23c9e 100644 --- a/config +++ b/config @@ -32,3 +32,5 @@ source "scripts/paths" # Project-specific variables below. +[ -z "${CC}" ] && CC="gcc" +[ -z "${CFLAGS}" ] && CFLAGS="-g -O2 -W -Wall" diff --git a/src/daemonitor/.params b/src/daemonitor/.params new file mode 100644 index 0000000..a05952c --- /dev/null +++ b/src/daemonitor/.params @@ -0,0 +1 @@ +app c daemonitor sbin diff --git a/src/daemonitor/000_TopSource.c b/src/daemonitor/000_TopSource.c new file mode 100644 index 0000000..b771594 --- /dev/null +++ b/src/daemonitor/000_TopSource.c @@ -0,0 +1,20 @@ +/* daemonitor/src/daemonitor/000_TopSource.c + * + * (c)2007, Laurence Withers, . + * Released under the GNU GPLv3. See file COPYING or + * http://www.gnu.org/copyleft/gpl.html for details. +*/ + +/* Below are all the includes used throughout the application. */ +#include +#include +#include +#include +#include +#include +#include + +/* options for text editors +kate: replace-trailing-space-save true; space-indent true; tab-width 4; +vim: expandtab:ts=4:sw=4 +*/ diff --git a/src/daemonitor/100_io.c b/src/daemonitor/100_io.c new file mode 100644 index 0000000..35a89b6 --- /dev/null +++ b/src/daemonitor/100_io.c @@ -0,0 +1,60 @@ +/* daemonitor/src/daemonitor/100_io.c + * + * (c)2007, Laurence Withers, . + * Released under the GNU GPLv3. See file COPYING or + * http://www.gnu.org/copyleft/gpl.html for details. +*/ + + + +/* I/O ROUTINES *********************************************************************************** + * + * This file provides a small set of I/O wrapper routines, for doing things like safely dealing + * with interrupted writes. + */ + + + +/* PUBLIC API ************************************************************************************/ + + + +/* safe_write_fixed() + * As write(2), except that it tries again in the face of partial writes or signal delivery. + */ +ssize_t safe_write_fixed(int fd, const char* buf, size_t amt); + + + +/* IMPLEMENTATION ********************************************************************************/ + + + +/* safe_write_fixed() + */ +ssize_t safe_write_fixed(int fd, const char* buf, size_t amt) __attribute__((nonnull)); +ssize_t safe_write_fixed(int fd, const char* buf, size_t amt) +{ + ssize_t ret, total = 0; + + while(amt) { + ret = write(fd, buf, amt); + if(ret == -1) { + if(errno == EINTR) continue; + return -1; + } + + total += ret; + buf += ret; + amt -= ret; + } + + return total; +} + + + +/* options for text editors +kate: replace-trailing-space-save true; space-indent true; tab-width 4; +vim: expandtab:ts=4:sw=4 +*/ diff --git a/src/daemonitor/101_log.c b/src/daemonitor/101_log.c new file mode 100644 index 0000000..cfe184b --- /dev/null +++ b/src/daemonitor/101_log.c @@ -0,0 +1,163 @@ +/* daemonitor/src/daemonitor/101_log.c + * + * (c)2007, Laurence Withers, . + * Released under the GNU GPLv3. See file COPYING or + * http://www.gnu.org/copyleft/gpl.html for details. +*/ + + + +/* LOGGING ROUTINES ******************************************************************************* + * + * This file provides a set of routines for performing logging. Messages are logged whenever + * actions are taken, such as setting up or shutting down. Messages can be logged to syslog, + * stdout, stderr or a file. + * + * Errors that occur before logging is set up (e.g. invalid commandline options, or opening a log + * file) will be reported to both stderr and syslog (see LOG_ANYWHERE()). + */ + + + +/* PUBLIC API ************************************************************************************/ + + + +/* enum log_destination_t + * The possible log destinations. These are passed to log_destination_set(), below. + */ +enum log_destination_t { + log_destination_stdout, + log_destination_stderr, + log_destination_syslog, + log_destination_file +}; + + + +/* log_destination_set() + * Chooses a specific log destination. If the destination is a file, log_destination_set_file() + * must also be called. + */ +void log_destination_set(enum log_destination_t dest); + + + +/* log_destination_set_file() + * Sets the output file for logging. Returns 0 on success, or -1 on error (i.e. if the file cannot + * be opened for writing), with errno set to whatever error caused the open to fail. + */ +int log_destination_set_file(const char* filename); + + + +/* LOG() + * The standard logging function. This sends the logging output to whatever destination has been + * chosen. It can only be called after logging has been set up; for other errors, LOG_ANYWHERE + * must be called. + */ +#define LOG(level, fmt, ...) \ + log_func(level, "%s:%d: " fmt, __FUNCTION__, __LINE__ , ## __VA_ARGS__ ) + + + +/* LOG_ANYWHERE() + * Try to log a problem, anywhere. Try stderr and syslog. + */ +#define LOG_ANYWHERE(fmt, ...) \ + log_anywhere("%s:%d: " fmt, __FUNCTION__, __LINE__ , ## __VA_ARGS__ ) + + + +/* IMPLEMENTATION ********************************************************************************/ + + + +/* log_anywhere() + * Logs to both stderr and syslog. Used by LOG_ANYWHERE() macro. + */ +void log_anywhere(const char* fmt, ...) __attribute__((format(printf,1,2),nonnull)); +void log_anywhere(const char* fmt, ...) +{ + va_list va, va2; + + /* get two copies of argument list */ + va_start(va, fmt); + va_copy(va2, va); + + /* print to stderr */ + vdprintf(STDERR_FILENO, fmt, va); + safe_write_fixed(STDERR_FILENO, "\n", 1); + va_end(va); + + /* send to syslog */ + vsyslog(LOG_CRIT, fmt, va2); + va_end(va2); +} + + + +/* log_func + * This is a pointer to the actual logging function. The pointer is set by log_destination_set(). + */ +void (*log_func)(int level, const char* fmt, ...) __attribute__((nonnull,format(printf,2,3))); + + + +/* log_func_fd, log_func_file() + * Logs to a file descriptor. + */ +int log_func_fd; +void log_func_file(int level, const char* fmt, ...) +{ + va_list va; + int ret; + const char* level_str; + + /* choose appropriate line description */ + switch(level) { + case LOG_EMERG: level_str = "EMERG"; break; + case LOG_ALERT: level_str = "ALERT"; break; + case LOG_CRIT: level_str = "CRIT "; break; + case LOG_ERR: level_str = "ERROR"; break; + case LOG_WARNING: level_str = "WARN "; break; + case LOG_NOTICE: level_str = "NOTE "; break; + case LOG_INFO: level_str = "INFO "; break; + case LOG_DEBUG: level_str = "DEBUG"; break; + default: level_str = "?BUG?"; break; + } + + /* print to file descriptor */ + va_start(va, fmt); + if(safe_write_fixed(STDERR_FILENO, level_str, 5) != 5) ret = -1; + ret = vdprintf(log_func_fd, fmt, va); + if(safe_write_fixed(STDERR_FILENO, "\n", 1) != 1) ret = -1; + va_end(va); + + /* report errors */ + if(ret < 0) { + log_anywhere("error writing to log file descriptor %d (%m)", log_func_fd); + } +} + + + +/* log_func_syslog() + * Logs to syslog. + */ +void log_func_syslog(int level, const char* fmt, ...) +{ + va_list va; + + /* log to syslog */ + va_start(va, fmt); + syslog(level, fmt, va); + va_end(va); +} + + + +/* options for text editors +kate: replace-trailing-space-save true; space-indent true; tab-width 4; +vim: expandtab:ts=4:sw=4 +*/ diff --git a/src/daemonitor/999_main.c b/src/daemonitor/999_main.c new file mode 100644 index 0000000..7d00a07 --- /dev/null +++ b/src/daemonitor/999_main.c @@ -0,0 +1,20 @@ +/* daemonitor/src/daemonitor/999_main.c + * + * (c)2007, Laurence Withers, . + * Released under the GNU GPLv3. See file COPYING or + * http://www.gnu.org/copyleft/gpl.html for details. +*/ + + + +int main(void) +{ + return 0; +} + + + +/* options for text editors +kate: replace-trailing-space-save true; space-indent true; tab-width 4; +vim: expandtab:ts=4:sw=4 +*/ diff --git a/src/daemonitor/build.app b/src/daemonitor/build.app new file mode 100644 index 0000000..41d452e --- /dev/null +++ b/src/daemonitor/build.app @@ -0,0 +1,41 @@ +# These are external variables, and shouldn't clash with anything else +# daemonitor +# daemonitor_BUILT +# + +if [ -z ${daemonitor_BUILT} ] +then + daemonitor="obj/daemonitor" + EXTRAS="-D_GNU_SOURCE" + + echo "Building application ${daemonitor}..." + + do_cmd source src/daemonitor/build.monolithic || return 1 + + MODIFIED=0 + for test in ${MONOLITHIC_TESTS} ${SRC} + do + if [ ${test} -nt ${daemonitor} ] + then + MODIFIED=1 + break + fi + done + + if [ ${MODIFIED} -ne 0 ] + then + echo " Compiling..." + + do_cmd ${CC} ${CFLAGS} -I obj -o "${daemonitor}" ${SRC} ${EXTRAS} || return 1 + + print_success "Application built" + else + print_success "Application up to date" + fi + + daemonitor_BUILT=1 + +fi + +# kate: replace-trailing-space-save true; space-indent true; tab-width 4; +# vim: syntax=sh:expandtab:ts=4:sw=4 diff --git a/src/daemonitor/build.default b/src/daemonitor/build.default new file mode 100644 index 0000000..b7a6ea8 --- /dev/null +++ b/src/daemonitor/build.default @@ -0,0 +1 @@ +source src/daemonitor/build.app diff --git a/src/daemonitor/build.install b/src/daemonitor/build.install new file mode 100644 index 0000000..fcc4969 --- /dev/null +++ b/src/daemonitor/build.install @@ -0,0 +1 @@ +source src/daemonitor/build.install-app diff --git a/src/daemonitor/build.install-app b/src/daemonitor/build.install-app new file mode 100644 index 0000000..c4a44be --- /dev/null +++ b/src/daemonitor/build.install-app @@ -0,0 +1,12 @@ +build_target daemonitor + +# make paths (this is for Gentoo in particular) +build_dir_tree "${SBINDIR}" || return 1 + +# install binary +echo "Installing binaries into '${SBINDIR}'" +install_file "${daemonitor}" "${SBINDIR}" 0755 || return 1 +print_success "Done" + +# kate: replace-trailing-space-save true; space-indent true; tab-width 4; +# vim: syntax=sh:expandtab:ts=4:sw=4 diff --git a/src/daemonitor/build.monolithic b/src/daemonitor/build.monolithic new file mode 100644 index 0000000..8db384e --- /dev/null +++ b/src/daemonitor/build.monolithic @@ -0,0 +1,18 @@ +# These are external variables, and shouldn't clash with anything else +# daemonitor_MONOLITHIC +# + +SRC="obj/daemonitor.c" +MONOLITHIC_TESTS="src/daemonitor/build.app src/daemonitor/build.monolithic" + +if [ -z "${daemonitor_MONOLITHIC}" ] +then + MONOLITHIC_SOURCE="$(find src/daemonitor/ -name '*.c' | sort)" + make_monolithic ${SRC} C || return 1 + + daemonitor_MONOLITHIC=1 + MONOLITHIC_DOC="${MONOLITHIC_DOC} ${SRC}" +fi + +# kate: replace-trailing-space-save true; space-indent true; tab-width 4; +# vim: syntax=sh:expandtab:ts=4:sw=4