Changes in / [9d6b229:277674c]
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
bitlbee.c
r9d6b229 r277674c 33 33 #include <errno.h> 34 34 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 ); 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 /* 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 } 45 69 70 71 46 72 int bitlbee_daemon_init() 47 73 { … … 232 258 } 233 259 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 else291 {292 /* We don't need this one, only the client does. */293 close( new_socket );294 }295 296 return TRUE;297 }298 299 260 void bitlbee_shutdown( gpointer data ) 300 261 { … … 306 267 g_main_quit( global.loop ); 307 268 } 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 else320 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 112 112 #include "sock.h" 113 113 114 typedef struct global { 115 /* In forked mode, child processes store the fd of the IPC socket here. */ 114 typedef struct global_t { 116 115 int listen_socket; 117 116 gint listen_watch_source_id; -
irc.c
r9d6b229 r277674c 874 874 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" ); 875 875 } 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 }880 876 else if( set_getint( irc, "debug" ) ) 881 877 {
Note: See TracChangeset
for help on using the changeset viewer.