Index: ipc.c
===================================================================
--- ipc.c	(revision 52744f8f65a278a59a8903d5c594e057d63c7006)
+++ ipc.c	(revision dd345753c1742905c9f81aa71d8b09109fbc5456)
@@ -258,128 +258,121 @@
 	else
 	{
+		ipc_master_free_fd( source );
+	}
+	
+	return TRUE;
+}
+
+gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )
+{
+	char *buf, **cmd;
+	
+	if( ( buf = ipc_readline( source ) ) )
+	{
+		cmd = irc_parse_line( buf );
+		if( cmd )
+			ipc_command_exec( data, cmd, ipc_child_commands );
+	}
+	else
+	{
+		ipc_child_disable();
+	}
+	
+	return TRUE;
+}
+
+void ipc_to_master( char **cmd )
+{
+	if( global.conf->runmode == RUNMODE_FORKDAEMON )
+	{
+		char *s = irc_build_line( cmd );
+		ipc_to_master_str( "%s", s );
+		g_free( s );
+	}
+	else if( global.conf->runmode == RUNMODE_DAEMON )
+	{
+		ipc_command_exec( NULL, cmd, ipc_master_commands );
+	}
+}
+
+void ipc_to_master_str( char *format, ... )
+{
+	char *msg_buf;
+	va_list params;
+
+	va_start( params, format );
+	msg_buf = g_strdup_vprintf( format, params );
+	va_end( params );
+	
+	if( strlen( msg_buf ) > 512 )
+	{
+		/* Don't send it, it's too long... */
+	}
+	else if( global.conf->runmode == RUNMODE_FORKDAEMON )
+	{
+		if( global.listen_socket >= 0 )
+			if( write( global.listen_socket, msg_buf, strlen( msg_buf ) ) <= 0 )
+				ipc_child_disable();
+	}
+	else if( global.conf->runmode == RUNMODE_DAEMON )
+	{
+		char **cmd, *s;
+		
+		if( ( s = strchr( msg_buf, '\r' ) ) )
+			*s = 0;
+		
+		cmd = irc_parse_line( msg_buf );
+		ipc_command_exec( NULL, cmd, ipc_master_commands );
+		g_free( cmd );
+	}
+	
+	g_free( msg_buf );
+}
+
+void ipc_to_children( char **cmd )
+{
+	if( global.conf->runmode == RUNMODE_FORKDAEMON )
+	{
+		char *msg_buf = irc_build_line( cmd );
+		ipc_to_children_str( "%s", msg_buf );
+		g_free( msg_buf );
+	}
+	else if( global.conf->runmode == RUNMODE_DAEMON )
+	{
 		GSList *l;
-		struct bitlbee_child *c;
-		
-		for( l = child_list; l; l = l->next )
+		
+		for( l = irc_connection_list; l; l = l->next )
+			ipc_command_exec( l->data, cmd, ipc_child_commands );
+	}
+}
+
+void ipc_to_children_str( char *format, ... )
+{
+	char *msg_buf;
+	va_list params;
+
+	va_start( params, format );
+	msg_buf = g_strdup_vprintf( format, params );
+	va_end( params );
+	
+	if( strlen( msg_buf ) > 512 )
+	{
+		/* Don't send it, it's too long... */
+	}
+	else if( global.conf->runmode == RUNMODE_FORKDAEMON )
+	{
+		int msg_len = strlen( msg_buf );
+		GSList *l, *next;
+		
+		for( l = child_list; l; l = next )
 		{
-			c = l->data;
-			if( c->ipc_fd == source )
+			struct bitlbee_child *c = l->data;
+			
+			next = l->next;
+			if( write( c->ipc_fd, msg_buf, msg_len ) <= 0 )
 			{
 				ipc_master_free_one( c );
 				child_list = g_slist_remove( child_list, c );
-				break;
 			}
-		}
-	}
-	
-	return TRUE;
-}
-
-gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )
-{
-	char *buf, **cmd;
-	
-	if( ( buf = ipc_readline( source ) ) )
-	{
-		cmd = irc_parse_line( buf );
-		if( cmd )
-			ipc_command_exec( data, cmd, ipc_child_commands );
-	}
-	else
-	{
-		b_event_remove( global.listen_watch_source_id );
-		close( global.listen_socket );
-		
-		global.listen_socket = -1;
-	}
-	
-	return TRUE;
-}
-
-void ipc_to_master( char **cmd )
-{
-	if( global.conf->runmode == RUNMODE_FORKDAEMON )
-	{
-		char *s = irc_build_line( cmd );
-		ipc_to_master_str( "%s", s );
-		g_free( s );
-	}
-	else if( global.conf->runmode == RUNMODE_DAEMON )
-	{
-		ipc_command_exec( NULL, cmd, ipc_master_commands );
-	}
-}
-
-void ipc_to_master_str( char *format, ... )
-{
-	char *msg_buf;
-	va_list params;
-
-	va_start( params, format );
-	msg_buf = g_strdup_vprintf( format, params );
-	va_end( params );
-	
-	if( strlen( msg_buf ) > 512 )
-	{
-		/* Don't send it, it's too long... */
-	}
-	else if( global.conf->runmode == RUNMODE_FORKDAEMON )
-	{
-		write( global.listen_socket, msg_buf, strlen( msg_buf ) );
-	}
-	else if( global.conf->runmode == RUNMODE_DAEMON )
-	{
-		char **cmd, *s;
-		
-		if( ( s = strchr( msg_buf, '\r' ) ) )
-			*s = 0;
-		
-		cmd = irc_parse_line( msg_buf );
-		ipc_command_exec( NULL, cmd, ipc_master_commands );
-		g_free( cmd );
-	}
-	
-	g_free( msg_buf );
-}
-
-void ipc_to_children( char **cmd )
-{
-	if( global.conf->runmode == RUNMODE_FORKDAEMON )
-	{
-		char *msg_buf = irc_build_line( cmd );
-		ipc_to_children_str( "%s", msg_buf );
-		g_free( msg_buf );
-	}
-	else if( global.conf->runmode == RUNMODE_DAEMON )
-	{
-		GSList *l;
-		
-		for( l = irc_connection_list; l; l = l->next )
-			ipc_command_exec( l->data, cmd, ipc_child_commands );
-	}
-}
-
-void ipc_to_children_str( char *format, ... )
-{
-	char *msg_buf;
-	va_list params;
-
-	va_start( params, format );
-	msg_buf = g_strdup_vprintf( format, params );
-	va_end( params );
-	
-	if( strlen( msg_buf ) > 512 )
-	{
-		/* Don't send it, it's too long... */
-	}
-	else if( global.conf->runmode == RUNMODE_FORKDAEMON )
-	{
-		int msg_len = strlen( msg_buf );
-		GSList *l;
-		
-		for( l = child_list; l; l = l->next )
-		{
-			struct bitlbee_child *c = l->data;
-			write( c->ipc_fd, msg_buf, msg_len );
 		}
 	}
@@ -410,4 +403,21 @@
 }
 
+void ipc_master_free_fd( int fd )
+{
+	GSList *l;
+	struct bitlbee_child *c;
+	
+	for( l = child_list; l; l = l->next )
+	{
+		c = l->data;
+		if( c->ipc_fd == fd )
+		{
+			ipc_master_free_one( c );
+			child_list = g_slist_remove( child_list, c );
+			break;
+		}
+	}
+}
+
 void ipc_master_free_all()
 {
@@ -419,4 +429,12 @@
 	g_slist_free( child_list );
 	child_list = NULL;
+}
+
+void ipc_child_disable()
+{
+	b_event_remove( global.listen_watch_source_id );
+	close( global.listen_socket );
+	
+	global.listen_socket = -1;
 }
 
