1 /* $Id: process.c,v 1.2 2007-06-12 13:02:38 adam Exp $
2 Copyright (c) 2006-2007, Index Data.
4 This file is part of Pazpar2.
6 Pazpar2 is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
11 Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with Pazpar2; see the file LICENSE. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
32 #include <sys/types.h>
39 static void write_pidfile(const char *pidfile)
43 FILE *f = fopen(pidfile, "w");
46 yaz_log(YLOG_ERRNO|YLOG_FATAL, "Couldn't create %s", pidfile);
49 fprintf(f, "%ld", (long) getpid());
55 void kill_child_handler(int num)
61 int pazpar2_process(int debug,
62 void (*work)(void *data), void *data,
63 const char *pidfile, const char *uid /* not yet used */)
65 struct passwd *pw = 0;
68 void (*old_sighup)(int);
69 void (*old_sigterm)(int);
74 /* in debug mode.. it's quite simple */
75 write_pidfile(pidfile);
80 /* running in production mode. */
83 yaz_log(YLOG_LOG, "getpwnam");
84 // OK to use the non-thread version here
85 if (!(pw = getpwnam(uid)))
87 yaz_log(YLOG_FATAL, "%s: Unknown user", uid);
93 /* keep signals in their original state and make sure that some signals
94 to parent process also gets sent to the child.. Normally this
95 should not happen. We want the _child_ process to be terminated
96 normally. However, if the parent process is terminated, we
98 old_sighup = signal(SIGHUP, kill_child_handler);
99 old_sigterm = signal(SIGTERM, kill_child_handler);
105 if (p == (pid_t) (-1))
108 yaz_log(YLOG_FATAL|YLOG_ERRNO, "fork");
114 signal(SIGHUP, old_sighup); /* restore */
115 signal(SIGTERM, old_sigterm);/* restore */
117 write_pidfile(pidfile);
121 if (setuid(pw->pw_uid) < 0)
123 yaz_log(YLOG_FATAL|YLOG_ERRNO, "setuid");
132 /* enable signalling in kill_child_handler */
138 /* disable signalling in kill_child_handler */
143 yaz_log(YLOG_FATAL, "p1=%d != p=%d", p1, p);
147 if (WIFSIGNALED(status))
149 /* keep the child alive in case of errors, but _log_ */
150 switch(WTERMSIG(status)) {
152 yaz_log(YLOG_WARN, "Received SIGILL from child %ld", (long) p);
156 yaz_log(YLOG_WARN, "Received SIGABRT from child %ld", (long) p);
160 yaz_log(YLOG_WARN, "Received SIGSEGV from child %ld", (long) p);
164 yaz_log(YLOG_WARN, "Received SIGBUS from child %ld", (long) p);
168 yaz_log(YLOG_LOG, "Received SIGTERM from child %ld",
173 yaz_log(YLOG_WARN, "Received SIG %d from child %ld",
174 WTERMSIG(status), (long) p);
178 else if (status == 0)
179 cont = 0; /* child exited normally */
181 { /* child exited with error */
182 yaz_log(YLOG_LOG, "Exit %d from child %ld", status, (long) p);
185 if (cont) /* respawn slower as we get more errors */
195 * indent-tabs-mode: nil
197 * vim: shiftwidth=4 tabstop=8 expandtab