diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2006-01-20 13:22:30 +0100 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2006-01-20 13:22:30 +0100 | 
| commit | 55ec2d66f04d1ea96e180c5a46e90a4294dea0b1 (patch) | |
| tree | 80b81694345d71838ded20c326e12f47423e08d9 /bitlbee.c | |
| parent | fc50d482ae5a7836fbf7c72df168b51d1cf714a5 (diff) | |
| parent | b8c2ace5985879a4c13d366756eb5e444a240ec9 (diff) | |
Merging IPC branch, it's too different from the main code to keep it
separated (and it's pretty stable now). Have fun. :-)
Diffstat (limited to 'bitlbee.c')
| -rw-r--r-- | bitlbee.c | 109 | 
1 files changed, 73 insertions, 36 deletions
| @@ -28,46 +28,12 @@  #include "commands.h"  #include "protocols/nogaim.h"  #include "help.h" +#include "ipc.h"  #include <signal.h>  #include <stdio.h>  #include <errno.h> -gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data ) -{ -	size_t size = sizeof( struct sockaddr_in ); -	struct sockaddr_in conn_info; -	int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size ); -	pid_t client_pid = 0; -	 -	if( global.conf->runmode == RUNMODE_FORKDAEMON ) -		client_pid = fork(); -	 -	if( client_pid == 0 ) -	{ -		log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket ); -		irc_new( new_socket ); -		 -		if( global.conf->runmode == RUNMODE_FORKDAEMON ) -		{ -			/* Close the listening socket, we're a client. */ -			close( global.listen_socket ); -			g_source_remove( global.listen_watch_source_id ); -		} -	} -	else -	{ -		/* We don't need this one, only the client does. */ -		close( new_socket ); -		 -		/* Or maybe we didn't even get a child process... */ -		if( client_pid == -1 ) -			log_message( LOGLVL_ERROR, "Failed to fork() subprocess for client: %s", strerror( errno ) ); -	} -	 -	return TRUE; -} -  - +gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data );  int bitlbee_daemon_init()  { @@ -89,6 +55,10 @@ int bitlbee_daemon_init()  		return( -1 );  	} +	/* TIME_WAIT (?) sucks.. */ +	i = 1; +	setsockopt( global.listen_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof( i ) ); +	  #ifdef IPV6  	listen_addr.sin6_family = AF_INETx;  	listen_addr.sin6_port = htons( global.conf->port ); @@ -256,6 +226,73 @@ gboolean bitlbee_io_current_client_write( GIOChannel *source, GIOCondition condi  	}  } +gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data ) +{ +	size_t size = sizeof( struct sockaddr_in ); +	struct sockaddr_in conn_info; +	int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size ); +	pid_t client_pid = 0; +	 +	if( global.conf->runmode == RUNMODE_FORKDAEMON ) +	{ +		int fds[2]; +		 +		if( socketpair( AF_UNIX, SOCK_STREAM, 0, fds ) == -1 ) +		{ +			log_message( LOGLVL_WARNING, "Could not create IPC socket for client: %s", strerror( errno ) ); +			fds[0] = fds[1] = -1; +		} +		 +		sock_make_nonblocking( fds[0] ); +		sock_make_nonblocking( fds[1] ); +		 +		client_pid = fork(); +		 +		if( client_pid > 0 && fds[0] != -1 ) +		{ +			struct bitlbee_child *child; +			 +			child = g_new0( struct bitlbee_child, 1 ); +			child->pid = client_pid; +			child->ipc_fd = fds[0]; +			child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child ); +			child_list = g_slist_append( child_list, child ); +			 +			log_message( LOGLVL_INFO, "Creating new subprocess with pid %d.", client_pid ); +			 +			/* Close some things we don't need in the parent process. */ +			close( new_socket ); +			close( fds[1] ); +		} +		else if( client_pid == 0 ) +		{ +			irc_t *irc; +			 +			/* Close the listening socket, we're a client. */ +			close( global.listen_socket ); +			g_source_remove( global.listen_watch_source_id ); +			 +			/* Make the connection. */ +			irc = irc_new( new_socket ); +			 +			/* We can store the IPC fd there now. */ +			global.listen_socket = fds[1]; +			global.listen_watch_source_id = gaim_input_add( fds[1], GAIM_INPUT_READ, ipc_child_read, irc ); +			 +			close( fds[0] ); +			 +			ipc_master_free_all(); +		} +	} +	else +	{ +		log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket ); +		irc_new( new_socket ); +	} +	 +	return TRUE; +} +  void bitlbee_shutdown( gpointer data )  {  	/* Try to save data for all active connections (if desired). */ | 
