Postfix3.3.1
load_file.c
[詳解]
1 /*++
2 /* NAME
3 /* load_file 3
4 /* SUMMARY
5 /* load file with some prejudice
6 /* SYNOPSIS
7 /* #include <load_file.h>
8 /*
9 /* void load_file(path, action, context)
10 /* const char *path;
11 /* void (*action)(VSTREAM, void *);
12 /* void *context;
13 /* DESCRIPTION
14 /* This routine reads a file and reads it again when the
15 /* file changed recently.
16 /*
17 /* Arguments:
18 /* .IP path
19 /* The file to be opened, read-only.
20 /* .IP action
21 /* The function that presumably reads the file.
22 /* .IP context
23 /* Application-specific context for the action routine.
24 /* DIAGNOSTICS
25 /* Fatal errors: out of memory, cannot open file.
26 /* LICENSE
27 /* .ad
28 /* .fi
29 /* The Secure Mailer license must be distributed with this software.
30 /* AUTHOR(S)
31 /* Wietse Venema
32 /* IBM T.J. Watson Research
33 /* P.O. Box 704
34 /* Yorktown Heights, NY 10598, USA
35 /*--*/
36 
37 /* System library. */
38 
39 #include <sys_defs.h>
40 #include <sys/stat.h>
41 #include <time.h>
42 
43 /* Utility library. */
44 
45 #include <msg.h>
46 #include <vstream.h>
47 #include <iostuff.h>
48 #include <load_file.h>
49 #include <warn_stat.h>
50 
51 /* load_file - load file with some prejudice */
52 
53 void load_file(const char *path, LOAD_FILE_FN action, void *context)
54 {
55  VSTREAM *fp;
56  struct stat st;
57  time_t before;
58  time_t after;
59 
60  /*
61  * Read the file again if it is hot. This may result in reading a partial
62  * parameter name or missing end marker when a file changes in the middle
63  * of a read.
64  */
65  for (before = time((time_t *) 0); /* see below */ ; before = after) {
66  if ((fp = vstream_fopen(path, O_RDONLY, 0)) == 0)
67  msg_fatal("open %s: %m", path);
68  action(fp, context);
69  if (fstat(vstream_fileno(fp), &st) < 0)
70  msg_fatal("fstat %s: %m", path);
71  if (vstream_ferror(fp) || vstream_fclose(fp))
72  msg_fatal("read %s: %m", path);
73  after = time((time_t *) 0);
74  if (st.st_mtime < before - 1 || st.st_mtime > after)
75  break;
76  if (msg_verbose)
77  msg_info("pausing to let %s cool down", path);
78  doze(300000);
79  }
80 }
int msg_verbose
Definition: msg.c:177
#define stat(p, s)
Definition: warn_stat.h:18
VSTREAM * vstream_fopen(const char *path, int flags, mode_t mode)
Definition: vstream.c:1241
int vstream_fclose(VSTREAM *stream)
Definition: vstream.c:1268
void(* LOAD_FILE_FN)(VSTREAM *, void *)
Definition: load_file.h:17
void doze(unsigned delay)
Definition: doze.c:44
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
#define vstream_fileno(vp)
Definition: vstream.h:115
void load_file(const char *path, LOAD_FILE_FN action, void *context)
Definition: load_file.c:53
#define vstream_ferror(vp)
Definition: vstream.h:120
#define fstat(f, s)
Definition: warn_stat.h:20
void msg_info(const char *fmt,...)
Definition: msg.c:199