1 /* $NetBSD: master_monitor.c,v 1.1.1.1 2013/09/25 19:06:32 tron Exp $ */ 2 3 /*++ 4 /* NAME 5 /* master_monitor 3 6 /* SUMMARY 7 /* Postfix master - start-up monitoring 8 /* SYNOPSIS 9 /* #include "master.h" 10 /* 11 /* int master_monitor(time_limit) 12 /* int time_limit; 13 /* DESCRIPTION 14 /* master_monitor() forks off a background child process, and 15 /* returns in the child. The result value is the file descriptor 16 /* on which the child process must write one byte after it 17 /* completes successful initialization as a daemon process. 18 /* 19 /* The foreground process waits for the child's completion for 20 /* a limited amount of time. It terminates with exit status 0 21 /* in case of success, non-zero otherwise. 22 /* DIAGNOSTICS 23 /* Fatal errors: system call failure. 24 /* BUGS 25 /* SEE ALSO 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 <signal.h> 41 #include <unistd.h> 42 #include <stdlib.h> 43 44 /* Utility library. */ 45 46 #include <msg.h> 47 #include <iostuff.h> 48 49 /* Application-specific. */ 50 51 #include <master.h> 52 53 /* master_monitor - fork off a foreground monitor process */ 54 55 int master_monitor(int time_limit) 56 { 57 pid_t pid; 58 int pipes[2]; 59 char buf[1]; 60 61 /* 62 * Sanity check. 63 */ 64 if (time_limit <= 0) 65 msg_panic("master_monitor: bad time limit: %d", time_limit); 66 67 /* 68 * Set up the plumbing for child-to-parent communication. 69 */ 70 if (pipe(pipes) < 0) 71 msg_fatal("pipe: %m"); 72 close_on_exec(pipes[0], CLOSE_ON_EXEC); 73 close_on_exec(pipes[1], CLOSE_ON_EXEC); 74 75 /* 76 * Fork the child, and wait for it to report successful initialization. 77 */ 78 switch (pid = fork()) { 79 case -1: 80 /* Error. */ 81 msg_fatal("fork: %m"); 82 case 0: 83 /* Child. Initialize as daemon in the background. */ 84 close(pipes[0]); 85 return (pipes[1]); 86 default: 87 /* Parent. Monitor the child in the foreground. */ 88 close(pipes[1]); 89 switch (timed_read(pipes[0], buf, 1, time_limit, (char *) 0)) { 90 default: 91 /* The child process still runs, but something is wrong. */ 92 (void) kill(pid, SIGKILL); 93 /* FALLTHROUGH */ 94 case 0: 95 /* The child process exited prematurely. */ 96 msg_fatal("daemon initialization failure"); 97 case 1: 98 /* The child process initialized successfully. */ 99 exit(0); 100 } 101 } 102 } 103