Changes in / [9d6b229:277674c]


Ignore:
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    r9d6b229 r277674c  
    3333#include <errno.h>
    3434
    35 struct bitlbee_child
    36 {
    37         pid_t pid;
    38         int ipc_fd;
    39         gint ipc_inpa;
    40 };
    41 
    42 static GSList *child_list = NULL;
    43 
    44 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data );
     35gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )
     36{
     37        size_t size = sizeof( struct sockaddr_in );
     38        struct sockaddr_in conn_info;
     39        int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
     40        pid_t client_pid = 0;
     41       
     42        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     43                client_pid = fork();
     44       
     45        if( client_pid == 0 )
     46        {
     47                log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );
     48                irc_new( new_socket );
     49               
     50                if( global.conf->runmode == RUNMODE_FORKDAEMON )
     51                {
     52                        /* Close the listening socket, we're a client. */
     53                        close( global.listen_socket );
     54                        g_source_remove( global.listen_watch_source_id );
     55                }
     56        }
     57        else
     58        {
     59                /* We don't need this one, only the client does. */
     60                close( new_socket );
     61               
     62                /* Or maybe we didn't even get a child process... */
     63                if( client_pid == -1 )
     64                        log_message( LOGLVL_ERROR, "Failed to fork() subprocess for client: %s", strerror( errno ) );
     65        }
     66       
     67        return TRUE;
     68}
    4569 
     70
     71
    4672int bitlbee_daemon_init()
    4773{
     
    232258}
    233259
    234 gboolean bitlbee_io_master_ipc_read( gpointer data, gint source, GaimInputCondition cond );
    235 gboolean bitlbee_io_child_ipc_read( gpointer data, gint source, GaimInputCondition cond );
    236 
    237 gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )
    238 {
    239         size_t size = sizeof( struct sockaddr_in );
    240         struct sockaddr_in conn_info;
    241         int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
    242         pid_t client_pid = 0;
    243        
    244         if( global.conf->runmode == RUNMODE_FORKDAEMON )
    245         {
    246                 int fds[2];
    247                
    248                 if( socketpair( AF_UNIX, SOCK_STREAM, 0, fds ) == -1 )
    249                 {
    250                         log_message( LOGLVL_WARNING, "Could not create IPC socket for client: %s", strerror( errno ) );
    251                         fds[0] = fds[1] = -1;
    252                 }
    253                
    254                 sock_make_nonblocking( fds[0] );
    255                 sock_make_nonblocking( fds[1] );
    256                
    257                 client_pid = fork();
    258                
    259                 if( client_pid > 0 && fds[0] != -1 )
    260                 {
    261                         struct bitlbee_child *child;
    262                        
    263                         child = g_new0( struct bitlbee_child, 1 );
    264                         child->pid = client_pid;
    265                         child->ipc_fd = fds[0];
    266                         child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, bitlbee_io_master_ipc_read, child );
    267                         child_list = g_slist_append( child_list, child );
    268                        
    269                         close( fds[1] );
    270                 }
    271                 else if( client_pid == 0 )
    272                 {
    273                         /* Close the listening socket, we're a client. */
    274                         close( global.listen_socket );
    275                         g_source_remove( global.listen_watch_source_id );
    276                        
    277                         /* We can store the IPC fd there now. */
    278                         global.listen_socket = fds[1];
    279                         global.listen_watch_source_id = gaim_input_add( fds[1], GAIM_INPUT_READ, bitlbee_io_child_ipc_read, NULL );
    280                        
    281                         close( fds[0] );
    282                 }
    283         }
    284        
    285         if( client_pid == 0 )
    286         {
    287                 log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );
    288                 irc_new( new_socket );
    289         }
    290         else
    291         {
    292                 /* We don't need this one, only the client does. */
    293                 close( new_socket );
    294         }
    295        
    296         return TRUE;
    297 }
    298 
    299260void bitlbee_shutdown( gpointer data )
    300261{
     
    306267        g_main_quit( global.loop );
    307268}
    308 
    309 gboolean bitlbee_io_master_ipc_read( gpointer data, gint source, GaimInputCondition cond )
    310 {
    311         struct bitlbee_child *child = data;
    312         char buf[513], *eol;
    313         int size;
    314        
    315         size = recv( child->ipc_fd, buf, sizeof( buf ) - 1, MSG_PEEK );
    316        
    317         if( size < 0 || ( size < 0 && !sockerr_again() ) )
    318                 goto error_abort;
    319         else
    320                 buf[size] = 0;
    321        
    322         eol = strstr( buf, "\r\n" );
    323         if( eol == NULL )
    324                 goto error_abort;
    325        
    326         size = recv( child->ipc_fd, buf, eol - buf + 2, 0 );
    327         buf[size] = 0;
    328        
    329         if( strcmp( buf, "DIE\r\n" ) == 0 )
    330         {
    331                 printf( "Bye...\n" );
    332                 exit( 0 );
    333         }
    334        
    335         return TRUE;
    336        
    337 error_abort:
    338         {
    339                 GSList *l;
    340                 struct bitlbee_child *c;
    341                
    342                 for( l = child_list; l; l = l->next )
    343                 {
    344                         c = l->data;
    345                         if( c->ipc_fd == source )
    346                         {
    347                                 close( c->ipc_fd );
    348                                 gaim_input_remove( c->ipc_inpa );
    349                                 g_free( c );
    350                                
    351                                 child_list = g_slist_remove( child_list, l );
    352                                
    353                                 break;
    354                         }
    355                 }
    356                
    357                 return FALSE;
    358         }
    359 }
    360 
    361 gboolean bitlbee_io_child_ipc_read( gpointer data, gint source, GaimInputCondition cond )
    362 {
    363         return TRUE;
    364 }
  • bitlbee.h

    r9d6b229 r277674c  
    112112#include "sock.h"
    113113
    114 typedef struct global {
    115         /* In forked mode, child processes store the fd of the IPC socket here. */
     114typedef struct global_t {
    116115        int listen_socket;
    117116        gint listen_watch_source_id;
  • irc.c

    r9d6b229 r277674c  
    874874                irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" );
    875875        }
    876         else if( g_strcasecmp( cmd[0], "DIE" ) == 0 )
    877         {
    878                 printf( "%d %d\n", global.listen_socket, write( global.listen_socket, "DIE\r\n", 5 ) );
    879         }
    880876        else if( set_getint( irc, "debug" ) )
    881877        {
Note: See TracChangeset for help on using the changeset viewer.