/* * Embed rtnetlink socket into ni_socket_t and set ifevent handler */ int ni_server_listen_interface_events(void (*ifevent_handler)(ni_netdev_t *, ni_event_t)) { ni_rtevent_handle_t *handle; unsigned int family; if (__ni_rtevent_sock || ni_global.interface_event) { ni_error("Interface event handler is already set"); return -1; } if (!(__ni_rtevent_sock = __ni_rtevent_sock_open())) return -1; family = ni_netconfig_get_family_filter(ni_global_state_handle(0)); handle = __ni_rtevent_sock->user_data; /* TODO: Move IPv6 info to separate function, dhcp4 does not need it */ if (!__ni_rtevent_join_group(handle, RTNLGRP_LINK) || (family != AF_INET && !__ni_rtevent_join_group(handle, RTNLGRP_IPV6_IFINFO))) { ni_socket_release(__ni_rtevent_sock); __ni_rtevent_sock = NULL; return -1; } ni_global.interface_event = ifevent_handler; ni_socket_activate(__ni_rtevent_sock); return 0; }
/* * Run a subprocess. */ int ni_process_run(ni_process_t *pi) { int pfd[2], rv; /* Our code in socket.c is only able to deal with sockets for now; */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pfd) < 0) { ni_error("%s: unable to create pipe: %m", __func__); return -1; } rv = __ni_process_run(pi, pfd); if (rv >= 0) { /* Set up a socket to receive the redirected output of the * subprocess. */ pi->socket = __ni_process_get_output(pi, pfd[0]); ni_socket_activate(pi->socket); close(pfd[1]); } else { if (pfd[0] >= 0) close(pfd[0]); if (pfd[1] >= 0) close(pfd[1]); } return rv; }
static ni_bool_t __ni_rtevent_restart(ni_socket_t *sock) { ni_rtevent_handle_t *handle = sock->user_data; if (handle) { if ((__ni_rtevent_sock = __ni_rtevent_sock_open())) { const ni_uint_array_t *groups = &handle->groups; unsigned int i; handle = __ni_rtevent_sock->user_data; for (i = 0; i < groups->count; ++i) { __ni_rtevent_join_group(handle, groups->data[i]); } ni_socket_activate(__ni_rtevent_sock); return TRUE; } ni_socket_release(sock); } return FALSE; }