Add basic daemonitor build framework and logging infrastructure

This commit is contained in:
Laurence Withers 2008-07-26 15:19:13 +00:00
parent e2fc9d8088
commit ff1f6fb734
11 changed files with 339 additions and 0 deletions

2
config
View File

@ -32,3 +32,5 @@
source "scripts/paths"
# Project-specific variables below.
[ -z "${CC}" ] && CC="gcc"
[ -z "${CFLAGS}" ] && CFLAGS="-g -O2 -W -Wall"

1
src/daemonitor/.params Normal file
View File

@ -0,0 +1 @@
app c daemonitor sbin

View File

@ -0,0 +1,20 @@
/* daemonitor/src/daemonitor/000_TopSource.c
*
* (c)2007, Laurence Withers, <l@lwithers.me.uk>.
* 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 <errno.h>
#include <stdio.h>
#include <getopt.h>
#include <stdarg.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/types.h>
/* options for text editors
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
vim: expandtab:ts=4:sw=4
*/

60
src/daemonitor/100_io.c Normal file
View File

@ -0,0 +1,60 @@
/* daemonitor/src/daemonitor/100_io.c
*
* (c)2007, Laurence Withers, <l@lwithers.me.uk>.
* 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
*/

163
src/daemonitor/101_log.c Normal file
View File

@ -0,0 +1,163 @@
/* daemonitor/src/daemonitor/101_log.c
*
* (c)2007, Laurence Withers, <l@lwithers.me.uk>.
* 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
*/

20
src/daemonitor/999_main.c Normal file
View File

@ -0,0 +1,20 @@
/* daemonitor/src/daemonitor/999_main.c
*
* (c)2007, Laurence Withers, <l@lwithers.me.uk>.
* 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
*/

41
src/daemonitor/build.app Normal file
View File

@ -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

View File

@ -0,0 +1 @@
source src/daemonitor/build.app

View File

@ -0,0 +1 @@
source src/daemonitor/build.install-app

View File

@ -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

View File

@ -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