Changeset 5c577bd


Ignore:
Timestamp:
2006-01-13T22:10:29Z (18 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
9d6b229
Parents:
08995b0
Message:

IPC code (by no means final)

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    r08995b0 r5c577bd  
    3333#include <errno.h>
    3434
    35 gboolean 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        
    63         return TRUE;
    64 }
     35struct bitlbee_child
     36{
     37        pid_t pid;
     38        int ipc_fd;
     39        gint ipc_inpa;
     40};
     41
     42static GSList *child_list = NULL;
     43
     44gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data );
    6545 
    66 
    67 
    6846int bitlbee_daemon_init()
    6947{
     
    278256}
    279257
     258gboolean bitlbee_io_master_ipc_read( gpointer data, gint source, GaimInputCondition cond );
     259gboolean bitlbee_io_child_ipc_read( gpointer data, gint source, GaimInputCondition cond );
     260
     261gboolean bitlbee_io_new_client( GIOChannel *source, GIOCondition condition, gpointer data )
     262{
     263        size_t size = sizeof( struct sockaddr_in );
     264        struct sockaddr_in conn_info;
     265        int new_socket = accept( global.listen_socket, (struct sockaddr *) &conn_info, &size );
     266        pid_t client_pid = 0;
     267       
     268        if( global.conf->runmode == RUNMODE_FORKDAEMON )
     269        {
     270                int fds[2];
     271               
     272                if( socketpair( AF_UNIX, SOCK_STREAM, 0, fds ) == -1 )
     273                {
     274                        log_message( LOGLVL_WARNING, "Could not create IPC socket for client: %s", strerror( errno ) );
     275                        fds[0] = fds[1] = -1;
     276                }
     277               
     278                sock_make_nonblocking( fds[0] );
     279                sock_make_nonblocking( fds[1] );
     280               
     281                client_pid = fork();
     282               
     283                if( client_pid > 0 && fds[0] != -1 )
     284                {
     285                        struct bitlbee_child *child;
     286                       
     287                        child = g_new0( struct bitlbee_child, 1 );
     288                        child->pid = client_pid;
     289                        child->ipc_fd = fds[0];
     290                        child->ipc_inpa = gaim_input_add( child->ipc_fd, GAIM_INPUT_READ, bitlbee_io_master_ipc_read, child );
     291                        child_list = g_slist_append( child_list, child );
     292                       
     293                        close( fds[1] );
     294                }
     295                else if( client_pid == 0 )
     296                {
     297                        /* Close the listening socket, we're a client. */
     298                        close( global.listen_socket );
     299                        g_source_remove( global.listen_watch_source_id );
     300                       
     301                        /* We can store the IPC fd there now. */
     302                        global.listen_socket = fds[1];
     303                        global.listen_watch_source_id = gaim_input_add( fds[1], GAIM_INPUT_READ, bitlbee_io_child_ipc_read, NULL );
     304                       
     305                        close( fds[0] );
     306                }
     307        }
     308       
     309        if( client_pid == 0 )
     310        {
     311                log_message( LOGLVL_INFO, "Creating new connection with fd %d.", new_socket );
     312                irc_new( new_socket );
     313        }
     314        else
     315        {
     316                /* We don't need this one, only the client does. */
     317                close( new_socket );
     318        }
     319       
     320        return TRUE;
     321}
     322
    280323void bitlbee_shutdown( gpointer data )
    281324{
     
    287330        g_main_quit( global.loop );
    288331}
     332
     333gboolean bitlbee_io_master_ipc_read( gpointer data, gint source, GaimInputCondition cond )
     334{
     335        struct bitlbee_child *child = data;
     336        char buf[513], *eol;
     337        int size;
     338       
     339        size = recv( child->ipc_fd, buf, sizeof( buf ) - 1, MSG_PEEK );
     340       
     341        if( size < 0 || ( size < 0 && !sockerr_again() ) )
     342                goto error_abort;
     343        else
     344                buf[size] = 0;
     345       
     346        eol = strstr( buf, "\r\n" );
     347        if( eol == NULL )
     348                goto error_abort;
     349       
     350        size = recv( child->ipc_fd, buf, eol - buf + 2, 0 );
     351        buf[size] = 0;
     352       
     353        if( strcmp( buf, "DIE\r\n" ) == 0 )
     354        {
     355                printf( "Bye...\n" );
     356                exit( 0 );
     357        }
     358       
     359        return TRUE;
     360       
     361error_abort:
     362        {
     363                GSList *l;
     364                struct bitlbee_child *c;
     365               
     366                for( l = child_list; l; l = l->next )
     367                {
     368                        c = l->data;
     369                        if( c->ipc_fd == source )
     370                        {
     371                                close( c->ipc_fd );
     372                                gaim_input_remove( c->ipc_inpa );
     373                                g_free( c );
     374                               
     375                                child_list = g_slist_remove( child_list, l );
     376                               
     377                                break;
     378                        }
     379                }
     380               
     381                return FALSE;
     382        }
     383}
     384
     385gboolean bitlbee_io_child_ipc_read( gpointer data, gint source, GaimInputCondition cond )
     386{
     387        return TRUE;
     388}
  • bitlbee.h

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

    r08995b0 r5c577bd  
    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        }
    876880        else if( set_getint( irc, "debug" ) )
    877881        {
Note: See TracChangeset for help on using the changeset viewer.