Changes in / [277674c:9d6b229]
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
bitlbee.c
r277674c r9d6b229 33 33 #include <errno.h> 34 34 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 } 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 ); 69 45 70 71 72 46 int bitlbee_daemon_init() 73 47 { … … 258 232 } 259 233 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 260 299 void bitlbee_shutdown( gpointer data ) 261 300 { … … 267 306 g_main_quit( global.loop ); 268 307 } 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
r277674c r9d6b229 112 112 #include "sock.h" 113 113 114 typedef struct global_t { 114 typedef struct global { 115 /* In forked mode, child processes store the fd of the IPC socket here. */ 115 116 int listen_socket; 116 117 gint listen_watch_source_id; -
irc.c
r277674c r9d6b229 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 } 876 880 else if( set_getint( irc, "debug" ) ) 877 881 {
Note: See TracChangeset
for help on using the changeset viewer.