]> mj.ucw.cz Git - libucw.git/blob - ucw/log-file.c
Logging: Use `uns' instead of `u32' to pass flags.
[libucw.git] / ucw / log-file.c
1 /*
2  *      UCW Library -- Logging to Files
3  *
4  *      (c) 1997--2009 Martin Mares <mj@ucw.cz>
5  *      (c) 2008 Tomas Gavenciak <gavento@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #include "ucw/lib.h"
12 #include "ucw/log.h"
13 #include "ucw/lfs.h"
14 #include "ucw/threads.h"
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <time.h>
21 #include <errno.h>
22
23 #if 0 // FIXME
24
25 static char *log_name_patt;
26 static int log_params;
27 static int log_filename_size;
28 static int log_switch_nest;
29
30 static int
31 do_log_switch(struct tm *tm)
32 {
33   int fd, l;
34   char name[log_filename_size];
35   int switched = 0;
36
37   if (!log_name_patt ||
38       log_filename[0] && !log_params)
39     return 0;
40   ucwlib_lock();
41   log_switch_nest++;
42   l = strftime(name, log_filename_size, log_name_patt, tm);
43   if (l < 0 || l >= log_filename_size)
44     die("Error formatting log file name: %m");
45   if (strcmp(name, log_filename))
46     {
47       strcpy(log_filename, name);
48       fd = ucw_open(name, O_WRONLY | O_CREAT | O_APPEND, 0666);
49       if (fd < 0)
50         die("Unable to open log file %s: %m", name);
51       dup2(fd, 2);
52       close(fd);
53       switched = 1;
54     }
55   log_switch_nest--;
56   ucwlib_unlock();
57   return switched;
58 }
59
60 int
61 log_switch(void)
62 {
63   time_t tim = time(NULL);
64   return do_log_switch(localtime(&tim));
65 }
66
67 static void
68 internal_log_switch(struct tm *tm)
69 {
70   if (!log_switch_nest)
71     do_log_switch(tm);
72 }
73
74 void
75 log_file(const char *name)
76 {
77   if (name)
78     {
79       if (log_name_patt)
80         xfree(log_name_patt);
81       if (log_filename)
82         {
83           xfree(log_filename);
84           log_filename = NULL;
85         }
86       log_name_patt = xstrdup(name);
87       log_params = !!strchr(name, '%');
88       log_filename_size = strlen(name) + 64;    /* 63 is an upper bound on expansion of % escapes */
89       log_filename = xmalloc(log_filename_size);
90       log_filename[0] = 0;
91       log_switch();
92       log_switch_hook = internal_log_switch;
93     }
94 }
95
96 void
97 log_fork(void)
98 {
99   log_pid = getpid();
100 }
101
102 void
103 log_switch_disable(void)
104 {
105   log_switch_nest++;
106 }
107
108 void
109 log_switch_enable(void)
110 {
111   ASSERT(log_switch_nest);
112   log_switch_nest--;
113 }
114
115 #endif
116
117 /* destructor for standard files */
118 static void ls_fdfile_close(struct log_stream *ls)
119 {
120   ASSERT(ls);
121   close(ls->idata);
122   if(ls->name)
123     xfree(ls->name);
124 }
125
126 /* handler for standard files */
127 static int ls_fdfile_handler(struct log_stream* ls, const char *m, uns cat UNUSED)
128 {
129   int len = strlen(m);
130   int r = write(ls->idata, m, len);
131   /* TODO: check the errors here? */
132   if (r!=len)
133     return errno;
134   return 0;
135 }
136
137 /* assign log to a file descriptor */
138 /* initialize with the default formatting, does NOT close the descriptor */
139 struct log_stream *ls_fdfile_new(int fd)
140 {
141   struct log_stream *ls=ls_new();
142   ls->idata=fd;
143   ls->msgfmt=LSFMT_DEFAULT;
144   ls->handler=ls_fdfile_handler;
145   return ls;
146 }
147
148 /* open() a file (append mode) */
149 /* initialize with the default formatting */
150 struct log_stream *ls_file_new(const char *path)
151 {
152   struct log_stream *ls;
153   int fd = open(path, O_WRONLY | O_CREAT | O_APPEND, 0666);
154   if (fd<0)
155   {
156     ls_msg(L_ERROR, "Opening logfile '%s' failed: %m.", path);
157     return NULL;
158   }
159   ls = ls_new();
160   ls->name = xstrdup(path);
161   ls->idata = fd;
162   ls->msgfmt = LSFMT_DEFAULT;
163   ls->handler = ls_fdfile_handler;
164   ls->close = ls_fdfile_close;
165   return ls;
166 }
167
168 #ifdef TEST
169
170 int main(int argc, char **argv)
171 {
172   log_init(argv[0]);
173   log_file("/proc/self/fd/1");
174   for (int i=1; i<argc; i++)
175     msg(L_INFO, argv[i]);
176   return 0;
177 }
178
179 #endif