]> mj.ucw.cz Git - libucw.git/blob - lib/log-file.c
Merged extended mempool from the dev-playground branch.
[libucw.git] / lib / 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 "lib/lib.h"
11 #include "lib/lfs.h"
12 #include "lib/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 volatile 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       close(2);
47       dup(fd);
48       close(fd);
49       close(1);
50       dup(2);
51       switched = 1;
52     }
53   log_switch_nest--;
54   ucwlib_unlock();
55   return switched;
56 }
57
58 int
59 log_switch(void)
60 {
61   time_t tim = time(NULL);
62   return do_log_switch(localtime(&tim));
63 }
64
65 static void
66 internal_log_switch(struct tm *tm)
67 {
68   if (!log_switch_nest)
69     do_log_switch(tm);
70 }
71
72 void
73 log_file(byte *name)
74 {
75   if (name)
76     {
77       if (log_name_patt)
78         xfree(log_name_patt);
79       if (log_filename)
80         {
81           xfree(log_filename);
82           log_filename = NULL;
83         }
84       log_name_patt = xstrdup(name);
85       log_params = !!strchr(name, '%');
86       log_filename_size = strlen(name) + 64;    /* 63 is an upper bound on expansion of % escapes */
87       log_filename = xmalloc(log_filename_size);
88       log_filename[0] = 0;
89       log_switch();
90       log_switch_hook = internal_log_switch;
91     }
92 }
93
94 void
95 log_fork(void)
96 {
97   log_pid = getpid();
98 }
99
100 #ifdef TEST
101
102 int main(int argc, char **argv)
103 {
104   log_init(argv[0]);
105   log_file("/proc/self/fd/1");
106   for (int i=1; i<argc; i++)
107     log(L_INFO, argv[i]);
108   return 0;
109 }
110
111 #endif