dbus_service.c

来自「非常好的dns解析软件」· C语言 代码 · 共 1,156 行 · 第 1/2 页

C
1,156
字号
	    to->tv.tv_usec = 0 ;	}	        }    return( to );}static dbus_bool_tadd_timeout( DBusTimeout *timeout, void *csp ){    DBusConnectionState   *cs = csp;    DBusConnectionTimeout *to = timeout_new(timeout);    if( cs->dh != 0L ) (*(cs->dh))("add_timeout: %d", dbus_timeout_get_interval(timeout));    to->cs = cs;    if ( to )    {	if( tsearch((void*)to, &(cs->timeouts), ptr_key_comparator) != 0L )	    return TRUE;    }    if( cs->eh != 0L ) (*(cs->eh))("add_timeout: out of memory");    return FALSE;}static voidremove_timeout( DBusTimeout *timeout, void *csp ){    DBusConnectionState   *cs = csp;    DBusConnectionTimeout *to = dbus_timeout_get_data(timeout);    if( (to != 0L) && (to->to == timeout) )    {	if( cs->dh != 0L ) (*(cs->dh))("remove_timeout: %d", dbus_timeout_get_interval(to->to));	if( tdelete((const void*)to, &(cs->timeouts), ptr_key_comparator) != 0L )	{	    free(to);	}else	    if( cs->eh != 0L ) (*(cs->eh))("remove_timeout: can't happen?!?: timeout data %p not found", to);   	    }else	if( cs->eh != 0L ) (*(cs->eh))("remove_timeout: can't happen?!?: timeout %p did not record data %p %p", 		    timeout, to, ((to != 0L) ? to->to : 0L)	           );}static voidtoggle_timeout( DBusTimeout *timeout, void *csp ){    DBusConnectionState   *cs = csp;    DBusConnectionTimeout **top = tfind( (const void*) dbus_timeout_get_data(timeout), 				         &(cs->timeouts),				         ptr_key_comparator	                               ),	                   *to=0L;    if( (top != 0L) && ((to=*top) != 0L) && (to->to == timeout) )    {	if( cs->dh != 0L ) (*(cs->dh))("toggle_timeout: %d", dbus_timeout_get_interval(to->to));	if(  dbus_timeout_get_enabled(timeout) )	    gettimeofday(&(to->tv),0L);	else	{	    to->tv.tv_sec = 0 ;	    to->tv.tv_usec = 0 ;	}    }else	if( cs->eh != 0L ) (*(cs->eh))("toggle_timeout: can't happen?!?: timeout %p %s %p %p", timeout, 		    ((to==0L) ? "did not record data" : "not found"),		    to, ((to != 0L) ? to->to : 0L)	           );	}static voidprocess_timeout( const void *p, const VISIT which, const int level){    DBusConnectionState   *cs;    void * const *tpp = p;    DBusConnectionTimeout *to;    struct timeval tv;    float now, then, interval;    int l = level ? 1 : 0;    l=l;    gettimeofday(&tv,0L);        if( (tpp != 0L) && (*tpp != 0L) && ((which == postorder) || (which == leaf)) )     {	to = (DBusConnectionTimeout*)*tpp;	cs = to->cs;	if ( !dbus_timeout_get_enabled(to->to) )	    return;	cs = dbus_timeout_get_data(to->to);	then = ((float)to->tv.tv_sec) + (((float)to->tv.tv_usec)  / 1000000.0);	if( then != 0.0 )	{	    interval = ((float)dbus_timeout_get_interval(to->to)) / 1000.0;	    now = ((float)tv.tv_sec) + (( (float)tv.tv_usec) /   1000000.0);	    if( (now - then) >= interval )	    {		if( cs->dh != 0L ) (*(cs->dh))("handle_timeout: %d - %f %f %f",  dbus_timeout_get_interval(to->to), then, now, interval);		dbus_timeout_handle( to->to );		to->tv=tv;	    }	}else	{	    to->tv = tv;	}    }}static voidprocess_timeouts ( DBusConnectionState *cs ){    twalk( cs->timeouts, process_timeout );}static void set_watch_fds( DBusWatch *watch, DBusConnectionState *cs ){    uint8_t flags = dbus_watch_get_flags(watch);    int fd = dbus_watch_get_fd(watch);    if ( cs->n <= fd )	cs->n = fd + 1;    if ( dbus_watch_get_enabled(watch) )    {	if ( flags & DBUS_WATCH_READABLE )	{	    FD_SET(fd , &(cs->r_fds));	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_ENABLE | WATCH_READ, cs->wh_arg ); 	}else	    	{	    FD_CLR(fd , &(cs->r_fds));	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_READ, cs->wh_arg ); 	}	if ( flags & DBUS_WATCH_WRITABLE )	{	    FD_SET(fd , &(cs->w_fds));	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_ENABLE | WATCH_WRITE, cs->wh_arg ); 	 	}else	    	{	    FD_CLR(fd , &(cs->w_fds));	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_WRITE, cs->wh_arg ); 	 	}	if ( flags & DBUS_WATCH_ERROR )	{	    FD_SET(fd , &(cs->e_fds));	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_ENABLE | WATCH_ERROR, cs->wh_arg ); 		}else	    	{	    FD_CLR(fd , &(cs->e_fds));	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_ERROR, cs->wh_arg ); 		}	    }else    {	if( FD_ISSET( fd, &(cs->r_fds)) )	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_READ, cs->wh_arg );	FD_CLR(fd , &(cs->r_fds));	if( FD_ISSET( fd, &(cs->w_fds)) )	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_WRITE, cs->wh_arg );		FD_CLR(fd , &(cs->w_fds));		if( FD_ISSET( fd, &(cs->e_fds)) )	    if( cs->wh != 0L )		(*(cs->wh))( fd, WATCH_ERROR, cs->wh_arg );	FD_CLR(fd , &(cs->e_fds));    }	}static dbus_bool_tadd_watch ( DBusWatch *watch, void *csp ){        DBusConnectionState *cs = csp;    dbus_watch_set_data(watch, cs, no_free );    if( cs->dh != 0L ) (*(cs->dh))("add_watch: %d", dbus_watch_get_fd(watch));    if( tsearch((const void*)watch,&(cs->watches),ptr_key_comparator) == 0L )    {	if( cs->eh != 0L ) (*(cs->eh))("add_watch: out of memory");	return FALSE;    }        set_watch_fds(watch,cs);    return TRUE;}static voidremove_watch ( DBusWatch *watch, void *csp ){    DBusConnectionState *cs = csp;    int  fd = dbus_watch_get_fd(watch);    if( tdelete((const void*)watch, &(cs->watches), ptr_key_comparator) == 0L )	if( cs->eh != 0L ) (*(cs->eh))("remove_watch: can't happen?!?: watch not found");    if( cs->dh != 0L ) (*(cs->dh))("remove_watch: %d", dbus_watch_get_fd(watch));    FD_CLR(fd , &(cs->r_fds));    FD_CLR(fd , &(cs->w_fds));    FD_CLR(fd , &(cs->e_fds));    if( cs->wh != 0L )	(*(cs->wh))(dbus_watch_get_fd(watch), WATCH_READ | WATCH_WRITE | WATCH_ERROR, cs->wh_arg );}static voidtoggle_watch ( DBusWatch *watch, void *csp ){    DBusConnectionState *cs = csp;        if( cs->dh != 0L ) (*(cs->dh))("toggle_watch: %d", dbus_watch_get_fd(watch));    set_watch_fds(watch,cs);}static voidprocess_watch( const void *p, const VISIT which, const int level){    void * const *wpp=p;    DBusWatch *w;    int fd;    uint8_t flags;    DBusConnectionState *cs;    int l = level ? 1 : 0;    l=l;    if((wpp != 0L) && (*wpp != 0L) && ( (which == postorder) || (which == leaf) ) )    {	w = (DBusWatch*)*wpp;	cs = dbus_watch_get_data( w );	if( cs == 0 )	    return;	if( ! dbus_watch_get_enabled(w) )	    return;	fd = dbus_watch_get_fd( w );	flags = dbus_watch_get_flags( w );	if( cs->dh != 0L ) (*(cs->dh))("handle_watch: %d", dbus_watch_get_fd( w ));	if ( (flags & DBUS_WATCH_READABLE) && (FD_ISSET(fd, &(cs->s_r_fds))) )	    dbus_watch_handle(w, DBUS_WATCH_READABLE);	if ( (flags & DBUS_WATCH_WRITABLE) && (FD_ISSET(fd, &(cs->s_w_fds))) )	    dbus_watch_handle(w, DBUS_WATCH_READABLE);	if ( (flags & DBUS_WATCH_ERROR) && (FD_ISSET(fd, &(cs->s_e_fds))) )	    dbus_watch_handle(w, DBUS_WATCH_ERROR);    }} static voidprocess_watches ( DBusConnectionState *cs ){    twalk( cs->watches, process_watch );}void dbus_svc_handle_watch(  DBusConnectionState *cs, int fd, dbus_svc_WatchFlags action ){    switch( action & 7 )    {    case WATCH_READ:	FD_SET(fd, &(cs->s_r_fds));	break;    case WATCH_WRITE:	FD_SET(fd, &(cs->s_w_fds));	break;	    case WATCH_ERROR:	FD_SET(fd, &(cs->s_e_fds));	break;    }}static voiddispatch_status(   DBusConnection *connection,     DBusDispatchStatus new_status,    void *csp ){    connection=connection;    DBusConnectionState *cs = csp;    cs->dispatchStatus = new_status;}voiddbus_svc_main_loop( DBusConnectionState *cs, void (*idle_handler)(DBusConnectionState *) ){    struct timeval timeout={0,200000};    int n_fds;    while( cs->status != SHUTDOWN )    {	cs->s_r_fds = cs->r_fds;	cs->s_w_fds = cs->w_fds;	cs->s_e_fds = cs->e_fds;		timeout.tv_sec = 0;	timeout.tv_usec= 200000;	if ( (n_fds = select(cs->n, &(cs->s_r_fds), &(cs->s_w_fds), &(cs->s_e_fds), &timeout)) < 0 )	{	    	    if (errno != EINTR) 	    {		if( cs->eh != 0L ) (*(cs->eh))( "select failed: %d : %s", errno, strerror(errno));	        return;	    }	}	if( n_fds > 0 )	    process_watches(cs);	process_timeouts(cs);	if ( cs->dispatchStatus != DBUS_DISPATCH_COMPLETE )	    dbus_connection_dispatch( cs->connection );	if( idle_handler != 0L )	    (*idle_handler)(cs);    }}void dbus_svc_dispatch(DBusConnectionState *cs){    process_watches(cs);        FD_ZERO(&(cs->s_r_fds));    FD_ZERO(&(cs->s_w_fds));    FD_ZERO(&(cs->s_e_fds));    process_timeouts(cs);    while ( cs->dispatchStatus != DBUS_DISPATCH_COMPLETE )	dbus_connection_dispatch( cs->connection );}void dbus_svc_quit( DBusConnectionState *cs ){    cs->status = SHUTDOWN;}static DBusConnectionState *connection_setup (   DBusConnection *connection,      dbus_svc_WatchHandler wh,     dbus_svc_ErrorHandler eh,     dbus_svc_ErrorHandler dh,    void *wh_arg){    DBusConnectionState *cs = dbcs_new( connection );        if ( cs == 0L )    {	if(eh)(*(eh))("connection_setup: out of memory");	goto fail;    }    cs->wh = wh;    cs->wh_arg = wh_arg;    cs->eh = eh;    cs->dh = dh;    if (!dbus_connection_set_watch_functions 	 (    cs->connection,	      add_watch,	      remove_watch,	      toggle_watch,	      cs,	      no_free	  )       )    {	if( cs->eh != 0L ) (*(cs->eh))("connection_setup: dbus_connection_set_watch_functions failed");	goto fail;     }          if (!dbus_connection_set_timeout_functions 	 (    connection,	      add_timeout,	      remove_timeout,	      toggle_timeout,	      cs, 	      no_free	 )       )    {	if( cs->eh != 0L ) (*(cs->eh))("connection_setup: dbus_connection_set_timeout_functions failed");	goto fail;    }    dbus_connection_set_dispatch_status_function     (   connection, 	dispatch_status, 	cs, 	no_free    );     if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)	dbus_connection_ref(connection);            return cs;   fail:    if( cs != 0L )	free(cs);      dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);    dbus_connection_set_watch_functions (connection, NULL, NULL, NULL, NULL, NULL);    dbus_connection_set_timeout_functions (connection, NULL, NULL, NULL, NULL, NULL);      return 0L;}DBusConnectionState *dbus_svc_init(    dbus_svc_DBUS_TYPE    bus,    char                  *name,     dbus_svc_WatchHandler wh ,    dbus_svc_ErrorHandler eh ,    dbus_svc_ErrorHandler dh ,    void *wh_arg){    DBusConnection       *connection;    DBusError            error;    DBusConnectionState  *cs;    char *session_bus_address=0L;    memset(&error,'\0',sizeof(DBusError));    dbus_error_init(&error);    switch( bus )    {	/* DBUS_PRIVATE_* bus types are the only type which allow reconnection if the dbus-daemon is restarted         */    case DBUS_PRIVATE_SYSTEM:       	if ( (connection = dbus_connection_open_private("unix:path=/var/run/dbus/system_bus_socket", &error)) == 0L )	{	    if(eh)(*eh)("dbus_svc_init failed: %s %s",error.name, error.message);	    return ( 0L );	}	if ( ! dbus_bus_register(connection,&error) )	{	    if(eh)(*eh)("dbus_bus_register failed: %s %s", error.name, error.message);	    dbus_connection_close(connection);	    free(connection);	    return ( 0L );	}	break;    case DBUS_PRIVATE_SESSION:		session_bus_address = getenv("DBUS_SESSION_BUS_ADDRESS");	if ( session_bus_address == 0L )	{	    if(eh)(*eh)("dbus_svc_init failed: DBUS_SESSION_BUS_ADDRESS environment variable not set");	    return ( 0L );	}	if ( (connection = dbus_connection_open_private(session_bus_address, &error)) == 0L )	{	    if(eh)(*eh)("dbus_svc_init failed: %s %s",error.name, error.message);	    return ( 0L );	}	if ( ! dbus_bus_register(connection,&error) )	{	    if(eh)(*eh)("dbus_bus_register failed: %s %s", error.name, error.message);	    dbus_connection_close(connection);	    free(connection);	    return ( 0L );	}	break;    case DBUS_SYSTEM:    case DBUS_SESSION:	if ( (connection = dbus_bus_get (bus, &error)) == 0L )	{	    if(eh)(*eh)("dbus_svc_init failed: %s %s",error.name, error.message);	    return ( 0L );	}	break;    default:	if(eh)(*eh)("dbus_svc_init failed: unknown bus type %d", bus);	return ( 0L );    }        dbus_connection_set_exit_on_disconnect(connection, FALSE);    if ( (cs = connection_setup(connection, wh, eh, dh, wh_arg)) == 0L )    {	if(eh)(*eh)("dbus_svc_init failed: connection_setup failed");	return( 0L );    }    if( name == 0L )	return( cs );        cs->unique_name = dbus_bus_get_unique_name(connection);    switch	(   dbus_bus_request_name 	    (   connection, name, #ifdef DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT		DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT ,#else		0 ,#endif		&error	    ) 	)    {       case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:		break;    case DBUS_REQUEST_NAME_REPLY_EXISTS:    case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:    case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:	if(eh)(*eh)("dbus_svc_init: dbus_bus_request_name failed:  Name already registered");	goto give_up;    default:	if(eh)(*eh)("dbus_svc_init: dbus_bus_request_name failed: %s %s", error.name, error.message);	goto give_up;    }    return ( cs ); give_up:    dbus_connection_close( connection );    dbus_connection_unref( connection );    if( cs )    {	dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);	dbus_connection_set_watch_functions (connection, NULL, NULL, NULL, NULL, NULL);	dbus_connection_set_timeout_functions (connection, NULL, NULL, NULL, NULL, NULL);	free(cs);        }    return ( 0L );}const char *dbus_svc_unique_name(DBusConnectionState *cs){    return cs->unique_name;}voiddbus_svc_shutdown ( DBusConnectionState *cs )                          {    if (!dbus_connection_set_watch_functions 	 (   cs->connection,	     NULL, NULL, NULL, NULL, NULL	 )       ) if( cs->eh != 0L ) (*(cs->eh))("connection_shutdown: dbus_connection_set_watch_functions: No Memory."                     "Setting watch functions to NULL failed."	            );      if (!dbus_connection_set_timeout_functions 	 (   cs->connection,	     NULL, NULL, NULL, NULL, NULL	 )       ) if( cs->eh != 0L ) (*(cs->eh))("connection_shutdown: dbus_connection_set_timeout_functions: No Memory."		     "Setting timeout functions to NULL failed."	            );    dbus_connection_set_dispatch_status_function (cs->connection, NULL, NULL, NULL);        tdestroy( cs->timeouts, free);    cs->timeouts=0L;    tdestroy( cs->watches, no_free);    cs->watches=0L;        dbus_connection_close( cs->connection );    dbus_connection_unref( cs->connection );    free( cs );}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?