Add basic daemonitor build framework and logging infrastructure
This commit is contained in:
parent
e2fc9d8088
commit
ff1f6fb734
2
config
2
config
|
@ -32,3 +32,5 @@
|
||||||
source "scripts/paths"
|
source "scripts/paths"
|
||||||
|
|
||||||
# Project-specific variables below.
|
# Project-specific variables below.
|
||||||
|
[ -z "${CC}" ] && CC="gcc"
|
||||||
|
[ -z "${CFLAGS}" ] && CFLAGS="-g -O2 -W -Wall"
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
app c daemonitor sbin
|
|
@ -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
|
||||||
|
*/
|
|
@ -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
|
||||||
|
*/
|
|
@ -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
|
||||||
|
*/
|
|
@ -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
|
||||||
|
*/
|
|
@ -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
|
|
@ -0,0 +1 @@
|
||||||
|
source src/daemonitor/build.app
|
|
@ -0,0 +1 @@
|
||||||
|
source 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
|
|
@ -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
|
Loading…
Reference in New Issue