From: Sam Moore Date: Thu, 15 Aug 2013 05:27:12 +0000 (+0800) Subject: Merge branch 'master' of https://github.com/jtanx/MCTX3420 into jtanx-master X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=43c1519cb60f8fef09043b9af6f43d319db12e3d;p=matches%2FMCTX3420.git Merge branch 'master' of https://github.com/jtanx/MCTX3420 into jtanx-master Conflicts: server/log.c server/main.c Merged in Jeremy's changes to log functions with my changes to the documentation. --- 43c1519cb60f8fef09043b9af6f43d319db12e3d diff --cc server/log.c index 62fe890,0000000..6f44bb0 mode 100644,000000..100644 --- a/server/log.c +++ b/server/log.c @@@ -1,105 -1,0 +1,110 @@@ +/** + * @file log.c + * @purpose Implement logging and error handling functions + */ + + +#include + +// --- Custom headers --- // +#include "log.h" +#include "options.h" + +// --- Static variables --- // - static char * unspecified_funct = (char*)"???"; ++static const char * unspecified_funct = "???"; + +// --- Function implementations --- // + +/** + * Print a message to stderr + * @param level - Specify how severe the message is. + If level is higher (less urgent) than the program's verbosity (see options.h) no message will be printed + * @param funct - String indicating the function name from which this function was called. + If this is NULL, Log will show the unspecified_funct string instead + * @param fmt - A format string + * @param ... - Arguments to be printed according to the format string + */ - void Log(int level, char * funct, char * fmt, ...) ++void LogEx(int level, const char * funct, ...) +{ ++ const char *fmt; ++ va_list va; ++ va_start(va, funct); ++ fmt = va_arg(va, const char*); ++ + if (fmt == NULL) // sanity check - Fatal("Log", "Format string is NULL"); ++ FatalEx("Log", "Format string is NULL"); + + // Don't print the message unless we need to - if (level > g_options.verbosity) ++ if (level > g_options.verbosity) + return; + + if (funct == NULL) + funct = unspecified_funct; + + // Make a human readable severity string - char severity[BUFSIZ]; ++ const char *severity; + switch (level) + { + case LOGERR: - sprintf(severity, "ERROR"); ++ severity = "ERROR"; + break; + case LOGWARN: - sprintf(severity, "WARNING"); ++ severity = "WARNING"; + break; + case LOGNOTE: - sprintf(severity, "NOTICE"); ++ severity = "NOTICE"; + break; + case LOGINFO: - sprintf(severity, "INFO"); ++ severity = "INFO"; + break; + default: - sprintf(severity, "DEBUG"); ++ severity = "DEBUG"; + break; + } + + // Print: Program name, PID, severity string, function name first + fprintf(stderr, "%s [%d] : %s : %s - ", g_options.program, getpid(), severity, funct); + + // Then pass additional arguments with the format string to vfprintf for printing - va_list va; - va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); + + // End log messages with a newline + fprintf(stderr, "\n"); +} + +/** + * Handle a Fatal error in the program by printing a message and exiting the program - CALLING THIS FUNCTION WILL CAUSE THE PROGAM TO EXIT ++ * CALLING THIS FUNCTION WILL CAUSE THE PROGAM TO EXIT + * @param funct - Name of the calling function + * @param fmt - A format string + * @param ... - Arguments to be printed according to the format string + */ - void Fatal(char * funct, char * fmt, ...) ++void FatalEx(const char * funct, ...) +{ ++ const char *fmt; ++ va_list va; ++ va_start(va, funct); ++ fmt = va_arg(va, const char*); + + if (fmt == NULL) + { + // Fatal error in the Fatal function. + // (This really shouldn't happen unless someone does something insanely stupid) - Fatal("Fatal", "Format string is NULL"); ++ FatalEx("Fatal", "Format string is NULL"); + return; // Should never get here + } + + if (funct == NULL) + funct = unspecified_funct; + + fprintf(stderr, "%s [%d] : %s : FATAL - ", g_options.program, getpid(), funct); + - va_list va; - va_start(va, fmt); + vfprintf(stderr, fmt, va); + va_end(va); + fprintf(stderr, "\n"); + + exit(EXIT_FAILURE); +} + + diff --cc server/log.h index 99d54d0,0000000..6db52f6 mode 100644,000000..100644 --- a/server/log.h +++ b/server/log.h @@@ -1,23 -1,0 +1,26 @@@ +/** + * @file log.h + * @purpose Declaration of functions for printing log messages and/or terminating program after a fatal error + */ + +#ifndef _LOG_H +#define _LOG_H + +#include +#include +#include +#include + ++//To get around a 'pedantic' C99 rule that you must have at least 1 variadic arg, combine fmt into that. ++#define Log(level, ...) LogEx(level, __func__, __VA_ARGS__) ++#define Fatal(...) FatalEx(__func__, __VA_ARGS__) + +// An enum to make the severity of log messages human readable in code +enum {LOGERR=0, LOGWARN=1, LOGNOTE=2, LOGINFO=3,LOGDEBUG=4}; + - extern void Log(int level, char * funct, char * fmt,...); // General function for printing log messages to stderr - extern void Fatal(char * funct, char * fmt, ...); // Function that deals with a fatal error (prints a message, then exits the program). ++extern void LogEx(int level, const char * funct, ...); // General function for printing log messages to stderr ++extern void FatalEx(const char * funct, ...); // Function that deals with a fatal error (prints a message, then exits the program). + +#endif //_LOG_H + +//EOF diff --cc server/main.c index 56794f2,0000000..61ba76d mode 100644,000000..100644 --- a/server/main.c +++ b/server/main.c @@@ -1,69 -1,0 +1,70 @@@ +/** + * @file main.c + * @purpose main and its helper functions, signal handling and cleanup functions + */ + +#define _POSIX_C_SOURCE 200809L // For strsignal to work + +// --- Standard headers --- // +#include +#include +#include // for signal handling +#include // string functions +#include + +// --- Custom headers --- // +#include "log.h" +#include "options.h" + +// --- Variable definitions --- // +Options g_options; // options passed to program through command line arguments + +// --- Function definitions --- // + +/** + * Parse command line arguments, initialise g_options + * @param argc - Number of arguments + * @param argv - Array of argument strings + */ +void ParseArguments(int argc, char ** argv) +{ + g_options.program = argv[0]; // program name + g_options.verbosity = LOGDEBUG; // default log level - Log(LOGDEBUG, "ParseArguments", "Called as %s with %d arguments.", g_options.program, argc); ++ Log(LOGDEBUG, "Called as %s with %d arguments.", g_options.program, argc); +} + +/** + * Handle a signal + * @param signal - The signal number + */ +void SignalHandler(int signal) +{ + // At the moment just always exit. + // Call `exit` so that Cleanup will be called to... clean up. - Log(LOGWARN, "SignalHandler", "Got signal %d (%s). Exiting.", signal, strsignal(signal)); ++ Log(LOGWARN, "Got signal %d (%s). Exiting.", sig, strsignal(sig)); + exit(sig); +} + +/** + * Cleanup before the program exits + */ +void Cleanup() +{ - Log(LOGDEBUG, "Cleanup", "Begin cleanup."); - Log(LOGDEBUG, "Cleanup", "Finish cleanup."); ++ Log(LOGDEBUG, "Begin cleanup."); ++ Log(LOGDEBUG, "Finish cleanup."); + +} + +/** + * Main entry point; start worker threads, setup signal handling, wait for threads to exit, exit + * @param argc - Num args + * @param argv - Args + * @returns 0 on success, error code on failure + */ +int main(int argc, char ** argv) +{ ++ ParseArguments(argc, argv, &g_options); + return 0; +} + +