void env_universal_init(wchar_t * p, wchar_t *u, void (*sf)(), void (*cb)(fish_message_type_t type, const wchar_t *name, const wchar_t *val)) { if (! synchronizes_via_fishd()) { external_callback = cb; env_universal_common_init(&callback); s_env_univeral_inited = true; } else { path=p; user=u; start_fishd=sf; external_callback = cb; env_universal_server.fd = get_socket(); env_universal_common_init(&callback); env_universal_read_all(); s_env_univeral_inited = true; if (env_universal_server.fd >= 0) { env_universal_barrier(); } } }
/** Make sure the connection is healthy. If not, close it, and try to establish a new connection. */ static void check_connection() { if( !init ) return; if( env_universal_server.killme ) { debug( 3, L"Lost connection to universal variable server." ); if( close( env_universal_server.fd ) ) { wperror( L"close" ); } env_universal_server.fd = -1; env_universal_server.killme=0; env_universal_server.input.clear(); env_universal_read_all(); } }
void env_universal_init( wchar_t * p, wchar_t *u, void (*sf)(), void (*cb)( int type, const wchar_t *name, const wchar_t *val )) { path=p; user=u; start_fishd=sf; external_callback = cb; connection_init( &env_universal_server, -1 ); env_universal_server.fd = get_socket(1); env_universal_common_init( &callback ); env_universal_read_all(); init = 1; if( env_universal_server.fd >= 0 ) { env_universal_barrier(); } }
void env_universal_barrier() { ASSERT_IS_MAIN_THREAD(); message_t *msg; fd_set fds; if( !init || is_dead() ) return; barrier_reply = 0; /* Create barrier request */ msg= create_message( BARRIER, 0, 0); msg->count=1; env_universal_server.unsent->push(msg); /* Wait until barrier request has been sent */ debug( 3, L"Create barrier" ); while( 1 ) { try_send_all( &env_universal_server ); check_connection(); if( env_universal_server.unsent->empty() ) break; if( env_universal_server.fd == -1 ) { reconnect(); debug( 2, L"barrier interrupted, exiting" ); return; } FD_ZERO( &fds ); FD_SET( env_universal_server.fd, &fds ); select( env_universal_server.fd+1, 0, &fds, 0, 0 ); } /* Wait for barrier reply */ debug( 3, L"Sent barrier request" ); while( !barrier_reply ) { if( env_universal_server.fd == -1 ) { reconnect(); debug( 2, L"barrier interrupted, exiting (2)" ); return; } FD_ZERO( &fds ); FD_SET( env_universal_server.fd, &fds ); select( env_universal_server.fd+1, &fds, 0, 0, 0 ); env_universal_read_all(); } debug( 3, L"End barrier" ); }
/** Internal function used by input_common_readch to read one byte from fd 1. This function should only be called by input_common_readch(). */ static wint_t readb() { unsigned char arr[1]; int do_loop = 0; do { fd_set fd; int fd_max=1; int res; FD_ZERO( &fd ); FD_SET( 0, &fd ); if( env_universal_server.fd > 0 ) { FD_SET( env_universal_server.fd, &fd ); fd_max = env_universal_server.fd+1; } do_loop = 0; res = select( fd_max, &fd, 0, 0, 0 ); if( res==-1 ) { switch( errno ) { case EINTR: case EAGAIN: { if( interrupt_handler ) { int res = interrupt_handler(); if( res ) { return res; } if( lookahead_count ) { return lookahead_arr[--lookahead_count]; } } do_loop = 1; break; } default: { /* The terminal has been closed. Save and exit. */ return R_EOF; } } } else { if( env_universal_server.fd > 0 ) { if( FD_ISSET( env_universal_server.fd, &fd ) ) { debug( 3, L"Wake up on universal variable event" ); env_universal_read_all(); do_loop = 1; if( lookahead_count ) { return lookahead_arr[--lookahead_count]; } } } if( FD_ISSET( 0, &fd ) ) { if( read_blocked( 0, arr, 1 ) != 1 ) { /* The teminal has been closed. Save and exit. */ return R_EOF; } do_loop = 0; } } } while( do_loop ); return arr[0]; }