Postfix3.3.1
master_monitor.c
[詳解]
1 /*++
2 /* NAME
3 /* master_monitor 3
4 /* SUMMARY
5 /* Postfix master - start-up monitoring
6 /* SYNOPSIS
7 /* #include "master.h"
8 /*
9 /* int master_monitor(time_limit)
10 /* int time_limit;
11 /* DESCRIPTION
12 /* master_monitor() forks off a background child process, and
13 /* returns in the child. The result value is the file descriptor
14 /* on which the child process must write one byte after it
15 /* completes successful initialization as a daemon process.
16 /*
17 /* The foreground process waits for the child's completion for
18 /* a limited amount of time. It terminates with exit status 0
19 /* in case of success, non-zero otherwise.
20 /* DIAGNOSTICS
21 /* Fatal errors: system call failure.
22 /* BUGS
23 /* SEE ALSO
24 /* LICENSE
25 /* .ad
26 /* .fi
27 /* The Secure Mailer license must be distributed with this software.
28 /* AUTHOR(S)
29 /* Wietse Venema
30 /* IBM T.J. Watson Research
31 /* P.O. Box 704
32 /* Yorktown Heights, NY 10598, USA
33 /*--*/
34 
35 /* System library. */
36 
37 #include <sys_defs.h>
38 #include <signal.h>
39 #include <unistd.h>
40 #include <stdlib.h>
41 
42 /* Utility library. */
43 
44 #include <msg.h>
45 #include <iostuff.h>
46 
47 /* Application-specific. */
48 
49 #include <master.h>
50 
51 /* master_monitor - fork off a foreground monitor process */
52 
53 int master_monitor(int time_limit)
54 {
55  pid_t pid;
56  int pipes[2];
57  char buf[1];
58 
59  /*
60  * Sanity check.
61  */
62  if (time_limit <= 0)
63  msg_panic("master_monitor: bad time limit: %d", time_limit);
64 
65  /*
66  * Set up the plumbing for child-to-parent communication.
67  */
68  if (pipe(pipes) < 0)
69  msg_fatal("pipe: %m");
70  close_on_exec(pipes[0], CLOSE_ON_EXEC);
71  close_on_exec(pipes[1], CLOSE_ON_EXEC);
72 
73  /*
74  * Fork the child, and wait for it to report successful initialization.
75  */
76  switch (pid = fork()) {
77  case -1:
78  /* Error. */
79  msg_fatal("fork: %m");
80  case 0:
81  /* Child. Initialize as daemon in the background. */
82  close(pipes[0]);
83  return (pipes[1]);
84  default:
85  /* Parent. Monitor the child in the foreground. */
86  close(pipes[1]);
87  switch (timed_read(pipes[0], buf, 1, time_limit, (void *) 0)) {
88  default:
89  /* The child process still runs, but something is wrong. */
90  (void) kill(pid, SIGKILL);
91  /* FALLTHROUGH */
92  case 0:
93  /* The child process exited prematurely. */
94  msg_fatal("daemon initialization failure");
95  case 1:
96  /* The child process initialized successfully. */
97  exit(0);
98  }
99  }
100 }
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
ssize_t timed_read(int, void *, size_t, int, void *)
Definition: timed_read.c:60
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int master_monitor(int time_limit)
#define CLOSE_ON_EXEC
Definition: iostuff.h:51
int close_on_exec(int fd, int on)
Definition: close_on_exec.c:49