]> mj.ucw.cz Git - libucw.git/blob - ucw/log-file.c
The big move. Step #1: Move whole lib/ to ucw/.
[libucw.git] / ucw / log-file.c
1 /*
2  *      UCW Library -- Keeping of Log Files
3  *
4  *      (c) 1997--2006 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "ucw/lib.h"
11 #include "ucw/lfs.h"
12 #include "ucw/threads.h"
13
14 #include <stdio.h>
15 #include <string.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <time.h>
19
20 static char *log_name_patt;
21 static int log_params;
22 static int log_filename_size;
23 static int log_switch_nest;
24
25 static int
26 do_log_switch(struct tm *tm)
27 {
28   int fd, l;
29   char name[log_filename_size];
30   int switched = 0;
31
32   if (!log_name_patt ||
33       log_filename[0] && !log_params)
34     return 0;
35   ucwlib_lock();
36   log_switch_nest++;
37   l = strftime(name, log_filename_size, log_name_patt, tm);
38   if (l < 0 || l >= log_filename_size)
39     die("Error formatting log file name: %m");
40   if (strcmp(name, log_filename))
41     {
42       strcpy(log_filename, name);
43       fd = sh_open(name, O_WRONLY | O_CREAT | O_APPEND, 0666);
44       if (fd < 0)
45         die("Unable to open log file %s: %m", name);
46       dup2(fd, 2);
47       close(fd);
48       switched = 1;
49     }
50   log_switch_nest--;
51   ucwlib_unlock();
52   return switched;
53 }
54
55 int
56 log_switch(void)
57 {
58   time_t tim = time(NULL);
59   return do_log_switch(localtime(&tim));
60 }
61
62 static void
63 internal_log_switch(struct tm *tm)
64 {
65   if (!log_switch_nest)
66     do_log_switch(tm);
67 }
68
69 void
70 log_file(const char *name)
71 {
72   if (name)
73     {
74       if (log_name_patt)
75         xfree(log_name_patt);
76       if (log_filename)
77         {
78           xfree(log_filename);
79           log_filename = NULL;
80         }
81       log_name_patt = xstrdup(name);
82       log_params = !!strchr(name, '%');
83       log_filename_size = strlen(name) + 64;    /* 63 is an upper bound on expansion of % escapes */
84       log_filename = xmalloc(log_filename_size);
85       log_filename[0] = 0;
86       log_switch();
87       log_switch_hook = internal_log_switch;
88     }
89 }
90
91 void
92 log_fork(void)
93 {
94   log_pid = getpid();
95 }
96
97 void
98 log_switch_disable(void)
99 {
100   log_switch_nest++;
101 }
102
103 void
104 log_switch_enable(void)
105 {
106   ASSERT(log_switch_nest);
107   log_switch_nest--;
108 }
109
110 #ifdef TEST
111
112 int main(int argc, char **argv)
113 {
114   log_init(argv[0]);
115   log_file("/proc/self/fd/1");
116   for (int i=1; i<argc; i++)
117     log(L_INFO, argv[i]);
118   return 0;
119 }
120
121 #endif