def start(self): """Start RPD initialization process (Section 6.1 or R-PHY specification) Whole process is described by state machine (constructor of this class) :return: """ # Get fd for terminate signals sfd = glibc.signalfd(-1, self.signal_mask, 0) # Always reset after boot os.environ['PC_REBOOT_HOLD'] = "FALSE" # Register manager's signalfd to dispatcher self.disp.fd_register(sfd, self.disp.EV_FD_IN, self.fd_event_handler) # Init RCP self.processes['rcp'].start(ipc_cb=self.rcp_msg_cb, sock_type=zmq.PAIR) call(["ifconfig", self.INTF, "up"]) self.fsm.init_done() # FIXME: delete below codes to skip dhcp procedure # Wait up to IF_UP_TIMEOUT for network interface to go up # if not self.wait_for_eth_up(Manager.IF_UP_TIMEOUT): # self.fsm.fatal_failure() # self.fsm.if_is_up() self._onlog_done('')
def main(): # Block signals so that they aren't handled # according to their default dispositions mask = sigset_t() fdsi = signalfd_siginfo() sigemptyset(mask) sigaddset(mask, SIGINT) sigaddset(mask, SIGQUIT) sigprocmask(SIG_BLOCK, mask, None) # Get a signalfd descriptor sfd = signalfd(-1, mask, SFD_CLOEXEC) # Get a epoll descriptor epollfd = epoll_create1(EPOLL_CLOEXEC) ev = epoll_event() ev.events = EPOLLIN ev.data.fd = sfd epoll_ctl(epollfd, EPOLL_CTL_ADD, sfd, byref(ev)) MAX_EVENTS = 10 events = (epoll_event * MAX_EVENTS)() with fdopen(sfd, 'rb', 0) as sfd_stream: while True: nfds = epoll_wait( epollfd, cast(byref(events), POINTER(epoll_event)), MAX_EVENTS, -1) for event_id in range(nfds): if events[event_id].data.fd == sfd: # Read the next delivered signal sfd_stream.readinto(fdsi) if fdsi.ssi_signo == SIGINT: print("Got SIGINT") elif fdsi.ssi_signo == SIGQUIT: print("Got SIGQUIT") return else: print("Read unexpected signal") else: raise Exception("unexpected fd?") close(sfd) close(epollfd)
def main(): # Block signals so that they aren't handled # according to their default dispositions mask = sigset_t() fdsi = signalfd_siginfo() sigemptyset(mask) sigaddset(mask, SIGINT) sigaddset(mask, SIGQUIT) sigprocmask(SIG_BLOCK, mask, None) # Get a signalfd descriptor sfd = signalfd(-1, mask, 0) with fdopen(sfd, 'rb', 0) as sfd_stream: while True: # Read the next delivered signal sfd_stream.readinto(fdsi) if fdsi.ssi_signo == SIGINT: print("Got SIGINT") elif fdsi.ssi_signo == SIGQUIT: print("Got SIGQUIT") return else: print("Read unexpected signal")
def main(): # Block signals so that they aren't handled # according to their default dispositions mask = sigset_t() fdsi = signalfd_siginfo() sigemptyset(mask) sigaddset(mask, SIGINT) sigaddset(mask, SIGQUIT) sigaddset(mask, SIGCHLD) sigaddset(mask, SIGPIPE) print("Blocking signals") sigprocmask(SIG_BLOCK, mask, None) # Get a signalfd descriptor sfd = signalfd(-1, mask, SFD_CLOEXEC | SFD_NONBLOCK) print("Got signalfd", sfd) # Get a epoll descriptor ep = epoll() print("Got epollfd", ep.fileno()) print("Adding signalfd fd {} to epoll".format(sfd)) ep.register(sfd, EPOLLIN) # Get two pair of pipes, one for stdout and one for stderr stdout_pair = (c_int * 2)() pipe2(byref(stdout_pair), O_CLOEXEC | O_NONBLOCK) print("Got stdout pipe pair", stdout_pair[0], stdout_pair[1]) print("Adding pipe fd {} to epoll".format(stdout_pair[0])) ep.register(stdout_pair[0], EPOLLIN) stderr_pair = (c_int * 2)() pipe2(byref(stderr_pair), O_CLOEXEC | O_NONBLOCK) print("Got stderr pipe pair", stderr_pair[0], stderr_pair[1]) print("Adding pipe fd {} to epoll".format(stdout_pair[0])) ep.register(stderr_pair[0], EPOLLIN) prog = argv[1:] if not prog: prog = ['echo', 'usage: demo.py PROG [ARGS]'] print("Going to start program:", prog) # Fork :-) pid = fork() if pid == 0: # Child. # NOTE: we are not closing any of the pipe ends. Why? Because they are # all O_CLOEXEC and will thus not live across the execlp call down # below. dup3(stdout_pair[1], 1, 0) dup3(stderr_pair[1], 2, 0) execlp(prog[0], *prog) return -1 else: close(stdout_pair[1]) close(stderr_pair[1]) with fdopen(sfd, 'rb', 0) as sfd_stream: waiting_for = set(['stdout', 'stderr', 'proc']) while waiting_for: print("Waiting for events...", ' '.join(waiting_for), flush=True) event_list = ep.poll(maxevents=10) print("epoll_wait() read {} events".format(len(event_list))) for fd, events in event_list: print("[event]") event_bits = [] if events & EPOLLIN == EPOLLIN: event_bits.append('EPOLLIN') if events & EPOLLOUT == EPOLLOUT: event_bits.append('EPOLLOUT') if events & EPOLLRDHUP == EPOLLRDHUP: event_bits.append('EPOLLRDHUP') if events & EPOLLPRI == EPOLLPRI: event_bits.append('EPOLLPRI') if events & EPOLLERR == EPOLLERR: event_bits.append('EPOLLERR') if events & EPOLLHUP == EPOLLHUP: event_bits.append('EPOLLHUP') if fd == sfd: fd_name = 'signalfd()' elif fd == stdout_pair[0]: fd_name = 'stdout pipe2()' elif fd == stderr_pair[0]: fd_name = 'stderr pipe2()' else: fd_name = "???" print(" events: {} ({})".format( events, ' | '.join(event_bits))) print(" fd: {} ({})".format(fd, fd_name)) if fd == sfd: print("signalfd() descriptor ready") if events & EPOLLIN: print("Reading data from signalfd()...") # Read the next delivered signal sfd_stream.readinto(fdsi) if fdsi.ssi_signo == SIGINT: print("Got SIGINT") elif fdsi.ssi_signo == SIGQUIT: print("Got SIGQUIT") raise SystemExit("exiting prematurly") elif fdsi.ssi_signo == SIGCHLD: print("Got SIGCHLD") waitid_result = waitid( P_PID, pid, WNOHANG | WEXITED | WSTOPPED | WCONTINUED | WUNTRACED) if waitid_result is None: print("child not ready") else: print("child event") print("si_pid:", waitid_result.si_pid) print("si_uid:", waitid_result.si_uid) print("si_signo:", waitid_result.si_signo) assert waitid_result.si_signo == SIGCHLD print("si_status:", waitid_result.si_status) print("si_code:", waitid_result.si_code) if waitid_result.si_code == CLD_EXITED: # assert WIFEXITED(waitid_result.si_status) print("child exited normally") print("exit code:", WEXITSTATUS(waitid_result.si_status)) waiting_for.remove('proc') if 'stdout' in waiting_for: ep.unregister(stdout_pair[0]) close(stdout_pair[0]) waiting_for.remove('stdout') if 'stderr' in waiting_for: ep.unregister(stderr_pair[0]) close(stderr_pair[0]) waiting_for.remove('stderr') elif waitid_result.si_code == CLD_KILLED: assert WIFSIGNALED(waitid_result.si_status) print("child was killed by signal") print("death signal:", waitid_result.si_status) waiting_for.remove('proc') elif waitid_result.si_code == CLD_DUMPED: assert WIFSIGNALED(waitid_result.si_status) print("core:", WCOREDUMP(waitid_result.si_status)) elif waitid_result.si_code == CLD_STOPPED: print("child was stopped") print("stop signal:", waitid_result.si_status) elif waitid_result.si_code == CLD_TRAPPED: print("child was trapped") # TODO: we could explore trap stuff here elif waitid_result.si_code == CLD_CONTINUED: print("child was continued") else: raise SystemExit( "Unknown CLD_ code: {}".format( waitid_result.si_code)) elif fdsi.ssi_signo == SIGPIPE: print("Got SIGPIPE") else: print("Read unexpected signal: {}".format( fdsi.ssi_signo)) elif fd == stdout_pair[0]: print("pipe() (stdout) descriptor ready") if events & EPOLLIN: print("Reading data from stdout...") data = read(stdout_pair[0], PIPE_BUF) print("Read {} bytes from stdout".format(len(data))) print(data) if events & EPOLLHUP: print("Removing stdout pipe from epoll") ep.unregister(stdout_pair[0]) print("Closing stdout pipe") close(stdout_pair[0]) waiting_for.remove('stdout') elif fd == stderr_pair[0]: print("pipe() (stderr) descriptor ready") if events & EPOLLIN: print("Reading data from stdout...") data = read(stderr_pair[0], PIPE_BUF) print("Read {} bytes from stderr".format(len(data))) print(data) if events & EPOLLHUP: print("Removing stderr pipe from epoll") ep.unregister(stderr_pair[0]) print("Closing stderr pipe") close(stderr_pair[0]) waiting_for.remove('stderr') else: # FIXME: we are still getting weird activation events on fd # 0 (stdin) with events == 0 (nothing). I cannot explain # this yet. print("Unexpected descriptor ready:", fd) assert not waiting_for print("Closing", ep) ep.close() print("Unblocking signals") sigprocmask(SIG_UNBLOCK, mask, None) print("Exiting normally")
#!/usr/bin/env python """ signalfd(2) demo, see the manual page of signalfd(2) for the equivalent C-code """ from __future__ import print_function from __future__ import absolute_import from signal import SIGINT, SIGQUIT from os import fdopen from glibc import ( SIG_BLOCK, sigset_t, signalfd_siginfo, sigemptyset, sigaddset, sigprocmask, signalfd, ) def main(): # Block signals so that they aren't handled # according to their default dispositions mask = sigset_t() fdsi = signalfd_siginfo() sigemptyset(mask) sigaddset(mask, SIGINT) sigaddset(mask, SIGQUIT) sigprocmask(SIG_BLOCK, mask, None) # Get a signalfd descriptor sfd = signalfd(-1, mask, 0) with fdopen(sfd, 'rb', 0) as sfd_stream: while True: # Read the next delivered signal