File: log.c

package info (click to toggle)
rocks 2.4-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 296 kB
  • ctags: 434
  • sloc: ansic: 5,668; makefile: 111
file content (130 lines) | stat: -rw-r--r-- 2,421 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h> 
#include <stdio.h>
#include <time.h>
#include <stdarg.h>
#include <string.h>

#include "log.h"

static FILE *logfp = NULL;
static int opt_nolog = 0;
static int opt_precise = 0;

int
rs_logfileno()
{
	if (!logfp)
		return -1;
	return fileno(logfp);
}

static
void tv_diff(const struct timeval *a,
	     const struct timeval *b,
	     struct timeval *c)
{
	c->tv_sec = a->tv_sec - b->tv_sec;
	c->tv_usec = a->tv_usec - b->tv_usec;
	if (c->tv_usec < 0) {
		c->tv_sec -= 1;
		c->tv_usec += 1000000;
	}
}

void
rs_log(char *fmt, ...)
{
	struct tm *tm;
	time_t timet;
	va_list args;
	static struct timeval tv, prev, c;

	if (opt_nolog)
		return;

	if (opt_precise) {
		gettimeofday(&tv, NULL);
		va_start(args, fmt);
		tv_diff(&tv, &prev, &c);
		fprintf(logfp, "[%d] %10ld.%06ld ",
			(int)getpid(), c.tv_sec, c.tv_usec);
		memcpy(&prev, &tv, sizeof(prev));
	} else {
		time(&timet);
		tm = localtime(&timet);
		va_start(args, fmt);
		fprintf(logfp, "[%d] %2d/%02d %2d:%02d:%02d ",
			(int)getpid(),
			tm->tm_mon+1, tm->tm_mday,
			tm->tm_hour, tm->tm_min, tm->tm_sec);
	}
	vfprintf(logfp, fmt, args);
	fprintf(logfp, "\r\n");
	fflush(logfp);
	va_end(args);
}

void
rs_tty_print(char *fmt, ...)
{
	struct tm *tm;
	time_t timet;
	va_list args;

	if (!isatty(2))
		return;

	time(&timet);
	tm = localtime(&timet);
	va_start(args, fmt);
	fprintf(stderr, "[%d] %2d/%02d %2d:%02d:%02d ",
		getpid(),
		tm->tm_mon+1, tm->tm_mday,
		tm->tm_hour, tm->tm_min, tm->tm_sec);
	vfprintf(stderr, fmt, args);
	fprintf(stderr, "\r\n");
	fflush(logfp);
	va_end(args);
}

int
rs_startlog(const char *logfilename, int flags)
{
	if (flags & RS_LOGNOLOG) {
		opt_nolog = 1;
		return 0;
	}
	if (!logfilename) {
		logfp = stderr;
		return 0;
	}
	if (flags & RS_LOGPRECISETIME)
		opt_precise = 1;
	logfp = fopen(logfilename, "a");
	if (!logfp) {
		logfp = stderr;
		rs_log("Can't open log %s", logfilename);
		return -1;
	} else if (flags & RS_LOGSTDERR
		   && fileno(logfp) != fileno(stderr)) {
		/* Redirect stderr to the log */
		/* FIXME: This is good for lazy server programmers,
                   bad for client users who rely on stderr. */
		int fd = fileno(stderr);
		close(fd);
		if (0 > dup2(fileno(logfp), fd))
			rs_log("stderr dup failed: stderr will be lost");
	}
	return 0;
}

void
rs_closelog()
{
	if (logfp)
		fclose(logfp);
}