aboutsummaryrefslogtreecommitdiffstats
path: root/unix.c
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2006-02-12 20:26:20 +1300
committerJelmer Vernooij <jelmer@samba.org>2006-02-12 20:26:20 +1300
commit5ebe625399d5116e222d6389434f645e906265ec (patch)
tree91a48ae6564ed891a23b1f5de2f630185fd0b39d /unix.c
parenta323a22773714a19254db34156500a67e5916451 (diff)
parent58bc4e69967a8feec0a60dfab716985191c12817 (diff)
Merge
Diffstat (limited to 'unix.c')
-rw-r--r--unix.c69
1 files changed, 64 insertions, 5 deletions
diff --git a/unix.c b/unix.c
index a1f39753..89bd65bf 100644
--- a/unix.c
+++ b/unix.c
@@ -28,24 +28,27 @@
#include "crypting.h"
#include "protocols/nogaim.h"
#include "help.h"
+#include "ipc.h"
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
+#include <sys/wait.h>
global_t global; /* Against global namespace pollution */
static void sighandler( int signal );
-int main( int argc, char *argv[] )
+int main( int argc, char *argv[], char **envp )
{
int i = 0;
+ char *old_cwd = NULL;
struct sigaction sig, old;
memset( &global, 0, sizeof( global_t ) );
global.loop = g_main_new( FALSE );
- log_init( );
+ log_init();
nogaim_init();
@@ -69,11 +72,24 @@ int main( int argc, char *argv[] )
i = bitlbee_daemon_init();
log_message( LOGLVL_INFO, "Bitlbee %s starting in daemon mode.", BITLBEE_VERSION );
}
+ else if( global.conf->runmode == RUNMODE_FORKDAEMON )
+ {
+ /* In case the operator requests a restart, we need this. */
+ old_cwd = g_malloc( 256 );
+ if( getcwd( old_cwd, 255 ) == NULL )
+ {
+ log_message( LOGLVL_WARNING, "Could not save current directory: %s", strerror( errno ) );
+ g_free( old_cwd );
+ old_cwd = NULL;
+ }
+
+ i = bitlbee_daemon_init();
+ log_message( LOGLVL_INFO, "Bitlbee %s starting in forking daemon mode.", BITLBEE_VERSION );
+ }
if( i != 0 )
return( i );
- global.storage = storage_init( global.conf->primary_storage,
- global.conf->migrate_storage );
+ global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage );
if ( global.storage == NULL) {
log_message( LOGLVL_ERROR, "Unable to load storage backend '%s'", global.conf->primary_storage );
return( 1 );
@@ -83,6 +99,7 @@ int main( int argc, char *argv[] )
/* Catch some signals to tell the user what's happening before quitting */
memset( &sig, 0, sizeof( sig ) );
sig.sa_handler = sighandler;
+ sigaction( SIGCHLD, &sig, &old );
sigaction( SIGPIPE, &sig, &old );
sig.sa_flags = SA_RESETHAND;
sigaction( SIGINT, &sig, &old );
@@ -101,12 +118,41 @@ int main( int argc, char *argv[] )
g_main_run( global.loop );
+ if( global.restart )
+ {
+ char *fn = ipc_master_save_state();
+ char **args;
+ int n, i;
+
+ chdir( old_cwd );
+
+ n = 0;
+ args = g_new0( char *, argc + 3 );
+ args[n++] = argv[0];
+ if( fn )
+ {
+ args[n++] = "-R";
+ args[n++] = fn;
+ }
+ for( i = 1; argv[i] && i < argc; i ++ )
+ {
+ if( strcmp( argv[i], "-R" ) == 0 )
+ i += 2;
+
+ args[n++] = argv[i];
+ }
+
+ close( global.listen_socket );
+
+ execve( args[0], args, envp );
+ }
+
return( 0 );
}
static void sighandler( int signal )
{
- /* FIXME: In fact, calling log_message() here can be dangerous. But well, let's take the risk for now. */
+ /* FIXME: Calling log_message() here is not a very good idea! */
if( signal == SIGTERM )
{
@@ -132,6 +178,19 @@ static void sighandler( int signal )
raise( signal );
}
}
+ else if( signal == SIGCHLD )
+ {
+ pid_t pid;
+ int st;
+
+ while( ( pid = waitpid( 0, &st, WNOHANG ) ) > 0 )
+ {
+ if( WIFSIGNALED( st ) )
+ log_message( LOGLVL_INFO, "Client %d terminated normally. (status = %d)", pid, WEXITSTATUS( st ) );
+ else if( WIFEXITED( st ) )
+ log_message( LOGLVL_INFO, "Client %d killed by signal %d.", pid, WTERMSIG( st ) );
+ }
+ }
else if( signal != SIGPIPE )
{
log_message( LOGLVL_ERROR, "Fatal signal received: %d. That's probably a bug.", signal );