-/* $Id: pazpar2.c,v 1.89 2007-06-12 13:02:38 adam Exp $
+/* $Id: pazpar2.c,v 1.90 2007-06-18 11:10:20 adam Exp $
Copyright (c) 2006-2007, Index Data.
This file is part of Pazpar2.
int main(int argc, char **argv)
{
+ int daemon = 0;
int ret;
+ int log_file_in_use = 0;
char *arg;
const char *pidfile = "pazpar2.pid";
const char *uid = 0;
yaz_log_init_prefix("pazpar2");
- while ((ret = options("f:h:p:t:u:l:dX", argv, argc, &arg)) != -2)
+ while ((ret = options("f:h:p:t:u:l:dDX", argv, argc, &arg)) != -2)
{
switch (ret)
{
break;
case 'l':
yaz_log_init_file(arg);
+ log_file_in_use = 1;
+ break;
+ case 'D':
+ daemon = 1;
break;
case 'X':
global_parameters.debug_mode = 1;
" -t settings\n"
" -u uid\n"
" -d (show internal records)\n"
+ " -D Daemon mode (background)\n"
" -l file log to file\n"
" -X debug mode\n"
);
}
}
+ yaz_log(YLOG_LOG, "Pazpar2 %s started", VERSION);
+ if (daemon && !log_file_in_use)
+ {
+ yaz_log(YLOG_FATAL, "Logfile must be given (option -l) for daemon "
+ "mode");
+ exit(1);
+ }
if (!config)
{
yaz_log(YLOG_FATAL, "Load config with -f");
global_parameters.server = config->servers;
start_http_listener();
- pazpar2_process(global_parameters.debug_mode,
+ pazpar2_process(global_parameters.debug_mode, daemon,
child_handler, 0 /* child_data */,
pidfile, uid);
return 0;
-/* $Id: pazpar2.h,v 1.42 2007-06-15 19:35:17 adam Exp $
+/* $Id: pazpar2.h,v 1.43 2007-06-18 11:10:20 adam Exp $
Copyright (c) 2006-2007, Index Data.
This file is part of Pazpar2.
void session_alert_watch(struct session *s, int what);
void pull_terms(NMEM nmem, struct ccl_rpn_node *n, char **termlist, int *num);
-int pazpar2_process(int debug,
+int pazpar2_process(int debug, int daemon,
void (*work)(void *data), void *data,
const char *pidfile, const char *uid);
-/* $Id: process.c,v 1.2 2007-06-12 13:02:38 adam Exp $
+/* $Id: process.c,v 1.3 2007-06-18 11:10:20 adam Exp $
Copyright (c) 2006-2007, Index Data.
This file is part of Pazpar2.
#endif
#include <signal.h>
+#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <pwd.h>
#include <yaz/log.h>
kill(child_pid, num);
}
-int pazpar2_process(int debug,
+int pazpar2_process(int debug, int daemon,
void (*work)(void *data), void *data,
const char *pidfile, const char *uid /* not yet used */)
{
- struct passwd *pw = 0;
int run = 1;
int cont = 1;
void (*old_sighup)(int);
void (*old_sigterm)(int);
-
if (debug)
{
/* in debug mode.. it's quite simple */
exit(0);
}
+ write_pidfile(pidfile);
/* running in production mode. */
if (uid)
{
- yaz_log(YLOG_LOG, "getpwnam");
- // OK to use the non-thread version here
- if (!(pw = getpwnam(uid)))
+ /* OK to use the non-thread version here */
+ struct passwd *pw = getpwnam(uid);
+ if (!pw)
{
yaz_log(YLOG_FATAL, "%s: Unknown user", uid);
exit(1);
}
+ if (setuid(pw->pw_uid) < 0)
+ {
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "setuid");
+ exit(1);
+ }
}
-
+ if (daemon)
+ {
+ /* create pipe so that parent waits until child has created
+ PID (or failed) */
+ static int hand[2]; /* hand shake for child */
+ if (pipe(hand) < 0)
+ {
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "pipe");
+ return 1;
+ }
+ switch (fork())
+ {
+ case 0:
+ break;
+ case -1:
+ return 1;
+ default:
+ close(hand[1]);
+ while(1)
+ {
+ char dummy[1];
+ int res = read(hand[0], dummy, 1);
+ if (res < 0 && errno != EINTR)
+ {
+ yaz_log(YLOG_FATAL|YLOG_ERRNO, "read fork handshake");
+ break;
+ }
+ else if (res >= 0)
+ break;
+ }
+ close(hand[0]);
+ _exit(0);
+ }
+ /* child */
+ close(hand[0]);
+ if (setsid() < 0)
+ return 1;
+
+ close(0);
+ close(1);
+ close(2);
+ open("/dev/null", O_RDWR);
+ dup(0); dup(0);
+ close(hand[1]);
+ }
/* keep signals in their original state and make sure that some signals
- to parent process also gets sent to the child.. Normally this
- should not happen. We want the _child_ process to be terminated
- normally. However, if the parent process is terminated, we
- kill the child too */
+ to parent process also gets sent to the child..
+ */
old_sighup = signal(SIGHUP, kill_child_handler);
old_sigterm = signal(SIGTERM, kill_child_handler);
while (cont)
signal(SIGHUP, old_sighup); /* restore */
signal(SIGTERM, old_sigterm);/* restore */
- write_pidfile(pidfile);
-
- if (pw)
- {
- if (setuid(pw->pw_uid) < 0)
- {
- yaz_log(YLOG_FATAL|YLOG_ERRNO, "setuid");
- exit(1);
- }
- }
-
work(data);
exit(0);
}
child_pid = p;
p1 = wait(&status);
- yaz_log_reopen();
/* disable signalling in kill_child_handler */
child_pid = 0;