1 /*
2  * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *	i4b daemon - process handling routines
28  *	--------------------------------------
29  *
30  *	$Id: process.c,v 1.3 2003/10/06 09:43:27 itojun Exp $
31  *
32  * $FreeBSD$
33  *
34  *      last edit-date: [Mon Dec 13 21:48:19 1999]
35  *
36  *---------------------------------------------------------------------------*/
37 
38 #include "isdnd.h"
39 
40 /*---------------------------------------------------------------------------*
41  *	check if another instance of us is already running
42  *---------------------------------------------------------------------------*/
43 void
check_pid(void)44 check_pid(void)
45 {
46 	FILE *fp;
47 
48 	/* check if another lock-file already exists */
49 
50 	if ((fp = fopen(PIDFILE, "r")) != NULL)
51 	{
52 		/* lockfile found, check */
53 
54 		int oldpid;
55 
56 		/* read pid from file */
57 
58 		if ((fscanf(fp, "%d", &oldpid)) != 1)
59 		{
60 			logit(LL_ERR, "ERROR, reading pid from lockfile failed, terminating!");
61 			exit(1);
62 		}
63 
64 		/* check if process got from file is still alive */
65 
66 		if ((kill(oldpid, 0)) != 0)
67 		{
68 			/* process does not exist */
69 
70 			/* close file */
71 
72 			fclose(fp);
73 
74 			DBGL(DL_PROC, (logit(LL_DBG, "removing old lock-file %s", PIDFILE)));
75 
76 			/* remove file */
77 
78 			unlink(PIDFILE);
79 		}
80 		else
81 		{
82 			/* process is still alive */
83 
84 			logit(LL_ERR, "ERROR, another daemon is already running, pid = %d, terminating!", oldpid);
85 			exit(1);
86 		}
87 	}
88 }
89 
90 /*---------------------------------------------------------------------------*
91  *	establish and init process lock file
92  *---------------------------------------------------------------------------*/
93 void
write_pid(void)94 write_pid(void)
95 {
96 	FILE *fp;
97 
98 	/* write my pid into lock-file */
99 
100 	if ((fp = fopen(PIDFILE, "w")) == NULL)
101 	{
102 		logit(LL_ERR, "ERROR, can't open lockfile for writing, terminating");
103 		do_exit(1);
104 	}
105 
106 	if ((fprintf(fp, "%d", (int)getpid())) == EOF)
107 	{
108 		logit(LL_ERR, "ERROR, can't write pid to lockfile, terminating");
109 		do_exit(1);
110 	}
111 
112 	fsync(fileno(fp));
113 
114 	fclose(fp);
115 }
116 
117 /*---------------------------------------------------------------------------*
118  *	become a daemon
119  *---------------------------------------------------------------------------*/
120 void
daemonize(void)121 daemonize(void)
122 {
123 	int fd;
124 
125 	switch (fork())
126 	{
127 		case -1:		/* error */
128 			logit(LL_ERR, "ERROR, daemonize/fork: %s", strerror(errno));
129 			exit(1);
130 		case 0:			/* child */
131 			break;
132 		default:		/* parent */
133 			exit(0);
134 	}
135 
136 	/* new session / no control tty */
137 
138 	if (setsid() == -1)
139 	{
140 		logit(LL_ERR, "ERROR, setsid returns: %s", strerror(errno));
141 		exit(1);
142 	}
143 
144 	/* go away from mounted dir */
145 
146 	chdir("/");
147 
148 	/* move i/o to another device ? */
149 
150 	if (do_fullscreen && do_rdev)
151 	{
152 		char *tp;
153 
154 		if ((fd = open(rdev, O_RDWR, 0)) != -1)
155 		{
156 			if (!isatty(fd))
157 			{
158 				logit(LL_ERR, "ERROR, device %s is not a tty!", rdev);
159 				exit(1);
160 			}
161 			if ((dup2(fd, STDIN_FILENO)) == -1)
162 			{
163 				logit(LL_ERR, "ERROR, dup2 stdin: %s", strerror(errno));
164 				exit(1);
165 			}
166 			if ((dup2(fd, STDOUT_FILENO)) == -1)
167 			{
168 				logit(LL_ERR, "ERROR, dup2 stdout: %s", strerror(errno));
169 				exit(1);
170 			}
171 			if ((dup2(fd, STDERR_FILENO)) == -1)
172 			{
173 				logit(LL_ERR, "ERROR, dup2 stderr: %s", strerror(errno));
174 				exit(1);
175 			}
176 		}
177 		else
178 		{
179 			logit(LL_ERR, "ERROR, cannot open redirected device: %s", strerror(errno));
180 			exit(1);
181 		}
182 
183 		if (fd > 2)
184 		{
185 			if ((close(fd)) == -1)
186 			{
187 				logit(LL_ERR, "ERROR, close in daemonize: %s", strerror(errno));
188 				exit(1);
189 			}
190 		}
191 
192 		/* curses output && fork NEEDS controlling tty */
193 
194 		if ((ioctl(STDIN_FILENO, TIOCSCTTY, (char *)NULL)) < 0)
195 		{
196 			logit(LL_ERR, "ERROR, cannot setup tty as controlling terminal: %s", strerror(errno));
197 			exit(1);
198 		}
199 
200 		/* in case there is no environment ... */
201 
202 		if (((tp = getenv("TERM")) == NULL) || (*tp == '\0'))
203 		{
204 			if (do_ttytype == 0)
205 			{
206 				logit(LL_ERR, "ERROR, no environment variable TERM found and -t not specified!");
207 				exit(1);
208 			}
209 
210 			if ((setenv("TERM", ttype, 1)) != 0)
211 			{
212 				logit(LL_ERR, "ERROR, setenv TERM=%s failed: %s", ttype, strerror(errno));
213 				exit(1);
214 			}
215 		}
216 	}
217 }
218 
219 /* EOF */
220