1 /*
2 * Copyright (c) 1997, 2001 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 * nifmon - background process handling
28 * ------------------------------------
29 *
30 * last edit-date: [Wed May 2 16:29:24 2001]
31 *
32 *---------------------------------------------------------------------------*/
33
34 #include "nifmon.h"
35
36 /*---------------------------------------------------------------------------*
37 * check if another instance of us is already running
38 *---------------------------------------------------------------------------*/
39 void
check_pid(char * pidfn)40 check_pid(char *pidfn)
41 {
42 FILE *fp;
43
44 /* check if another lock-file already exists */
45
46 if ((fp = fopen(pidfn, "r")) != NULL)
47 {
48 /* lockfile found, check */
49
50 int oldpid;
51
52 /* read pid from file */
53
54 if ((fscanf(fp, "%d", &oldpid)) != 1)
55 {
56 perror
57 ("ERROR, reading pid from lockfile failed, terminating!");
58 exit(1);
59 }
60
61 /* check if process got from file is still alive */
62
63 if ((kill(oldpid, 0)) != 0)
64 {
65 /* process does not exist */
66
67 /* close file */
68
69 fclose(fp);
70
71 /* remove file */
72
73 unlink(pidfn);
74 }
75 else
76 {
77 /* process is still alive */
78
79 fprintf(stderr,
80 "ERROR, another daemon is already running, pid = %d, terminating!",
81 oldpid);
82 exit(1);
83 }
84 }
85 }
86
87 /*---------------------------------------------------------------------------*
88 * establish and init process lock file
89 *---------------------------------------------------------------------------*/
90 void
write_pid(char * pidfn)91 write_pid(char *pidfn)
92 {
93 FILE *fp;
94
95 /* write my pid into lock-file */
96
97 if ((fp = fopen(pidfn, "w")) == NULL)
98 {
99 perror("ERROR, can't open lockfile for writing, terminating");
100 do_exit(1);
101 }
102
103 if ((fprintf(fp, "%d", (int) getpid())) == EOF)
104 {
105 perror("ERROR, can't write pid to lockfile, terminating");
106 do_exit(1);
107 }
108
109 fsync(fileno(fp));
110
111 fclose(fp);
112 }
113
114 /*---------------------------------------------------------------------------*
115 * become a daemon
116 *---------------------------------------------------------------------------*/
117 void
daemonize(void)118 daemonize(void)
119 {
120 int fd;
121 char *tp;
122
123 switch (fork())
124 {
125 case -1: /* error */
126 perror("ERROR, daemonize/fork");
127 exit(1);
128 case 0: /* child */
129 break;
130 default: /* parent */
131 exit(0);
132 }
133
134 chdir("/"); /* go away from mounted dir */
135
136 /* new session / no control tty */
137
138 if (setsid() == -1)
139 {
140 perror("ERROR, setsid");
141 exit(1);
142 }
143
144 if ((fd = open(rdev, O_RDWR, 0)) != -1)
145 {
146 if (!isatty(fd))
147 {
148 perror("ERROR, device is not a tty!");
149 exit(1);
150 }
151 if ((dup2(fd, STDIN_FILENO)) == -1)
152 {
153 perror("ERROR, dup2 stdin");
154 exit(1);
155 }
156 if ((dup2(fd, STDOUT_FILENO)) == -1)
157 {
158 perror("ERROR, dup2 stdout");
159 exit(1);
160 }
161 if ((dup2(fd, STDERR_FILENO)) == -1)
162 {
163 perror("ERROR, dup2 stderr");
164 exit(1);
165 }
166 }
167 else
168 {
169 perror("ERROR, cannot open redirected device");
170 exit(1);
171 }
172
173 if (fd > 2)
174 {
175 if ((close(fd)) == -1)
176 {
177 perror("ERROR, close in daemonize");
178 exit(1);
179 }
180 }
181
182 /* curses output && fork NEEDS controlling tty */
183
184 if ((ioctl(STDIN_FILENO, TIOCSCTTY, (char *) NULL)) < 0)
185 {
186 perror
187 ("ERROR, cannot setup tty as controlling terminal");
188 exit(1);
189 }
190
191 /* in case there is no environment ... */
192
193 if (((tp = getenv("TERM")) == NULL) || (*tp == '\0'))
194 {
195 if (has_term == 0)
196 {
197 perror
198 ("ERROR, no environment variable TERM found and -t not specified!");
199 exit(1);
200 }
201
202 if ((setenv("TERM", term, 1)) != 0)
203 {
204 perror("ERROR, setenv TERM failed");
205 exit(1);
206 }
207 }
208 }
209
210 /* EOF */
211