httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject aplogger
Date Mon, 03 Nov 1997 21:50:59 GMT
Ok, I admit there were gotchas in my cat and grep suggestions. 
Specifically, they don't deal gracefully with termination signals, a few
log entries may be lost on rotation.

Included, find aplogger.c, which doesn't have these problems.  It's only
the beginning of a solution -- because a full solution requires the logger
to be in its own process group.  Otherwise the killpg()s that apache does
will send signals to all the logging processes.  But at any rate ... 

Oh yeah, this should build on any POSIX system, when we have a libap it
would be easy to make it use our portability stuff.

Dean

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>

static int deferred_exit;
static const char *progname;

#define BLOCK_SIZE	4096

static void sig_handler(int sig)
{
    deferred_exit = 1;
}

static void install_signal_handlers(void)
{
    struct sigaction sa;
    int i;

    static const int sigs[] = {
#ifdef SIGHUP
	SIGHUP,
#endif
#ifdef SIGINT
	SIGINT,
#endif
#ifdef SIGQUIT
	SIGQUIT,
#endif
#ifdef SIGPIPE
	SIGPIPE,
#endif
#ifdef SIGUSR1
	SIGUSR1,
#endif
#ifdef SIGTERM
	SIGTERM,
#endif
#ifdef SIGPWR
	SIGPWR,
#endif
	0
    };

    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sa.sa_handler = sig_handler;
    for (i = 0; sigs[i]; ++i) {
	if (sigaction(sigs[i], &sa, NULL) < 0) {
	    fprintf(stderr,
		"%s: error installing signal handler for signal %d: %s\n",
		progname, sigs[i], strerror(errno));
	    exit(1);
	}
    }
}


static inline void safe_write(int f, const void *b, size_t l)
{
    int rc;

    while (l) {
        rc = write(f, b, l);
        if (rc == -1) {
            if (errno != EINTR) {
                fprintf(stderr, "%s: write error: %s\n", progname,
                    strerror(errno));
                exit(1);
            }
        }
        if (rc > 0) {
            l -= rc;
            b = (void *)((char *)b + rc);
        }
    }
}


void main(int argc, char **argv)
{
    char buf[BLOCK_SIZE];
    int rc;
    FILE *pid;

    progname = argv[0];
    if (argc != 2) {
	fprintf(stderr, "usage: %s pidfilename >> logfile\n", progname);
	exit(1);
    }

    install_signal_handlers();

    if ((pid = fopen(argv[1], "w")) == NULL) {
	fprintf(stderr, "%s: unable to open %s for writing: %s\n",
	    progname, argv[1], strerror(errno));
	exit(1);
    }
    fprintf(pid, "%u\n", getpid());
    fclose(pid);

    for(;;) {
	if (deferred_exit) {
	    exit(0);
	}
	rc = read(STDIN_FILENO, buf, sizeof(buf));
	if (rc <= 0) {
	    if (rc == -1 && errno != EINTR) {
		fprintf(stderr, "%s: error reading stdin: %s\n",
		    progname, strerror(errno));
		exit(1);
	    }
	    if (rc == 0) {
		exit(0);
	    }
	    /* otherwise it's an EINTR, and we'll catch it at the top of
	     * the loop
	     */
	} else {
	    safe_write(STDOUT_FILENO, buf, rc);
	}
    }
}




Mime
View raw message