1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* lib/krad/t_daemon.h - Daemonization helper for RADIUS test programs */ 3 /* 4 * Copyright 2013 Red Hat, Inc. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #ifndef T_DAEMON_H_ 31 #define T_DAEMON_H_ 32 33 #include "t_test.h" 34 #include <libgen.h> 35 #include <sys/types.h> 36 #include <sys/stat.h> 37 #include <fcntl.h> 38 39 static pid_t daemon_pid; 40 41 static void 42 daemon_stop(void) 43 { 44 if (daemon_pid == 0) 45 return; 46 kill(daemon_pid, SIGTERM); 47 waitpid(daemon_pid, NULL, 0); 48 daemon_pid = 0; 49 } 50 51 static krb5_boolean 52 daemon_start(int argc, const char **argv) 53 { 54 int fds[2]; 55 char buf[1]; 56 57 if (argc != 3 || argv == NULL) 58 return FALSE; 59 60 if (daemon_pid != 0) 61 return TRUE; 62 63 if (pipe(fds) != 0) 64 return FALSE; 65 66 /* Start the child process with the write end of the pipe as stdout. */ 67 daemon_pid = fork(); 68 if (daemon_pid == 0) { 69 dup2(fds[1], STDOUT_FILENO); 70 close(fds[0]); 71 close(fds[1]); 72 exit(execlp(argv[1], argv[1], argv[2], NULL)); 73 } 74 close(fds[1]); 75 76 /* The child will write a sentinel character when it is listening. */ 77 if (read(fds[0], buf, 1) != 1 || *buf != '~') 78 return FALSE; 79 close(fds[0]); 80 81 atexit(daemon_stop); 82 return TRUE; 83 } 84 85 #endif /* T_DAEMON_H_ */ 86