def popen(self, args=(), **kwargs): bufsize = kwargs.get('bufsize', -1) stdin = kwargs.get('stdin', sys.stdin) stdin.close = close exposed_stdin = None if stdin == PIPE: (r, w) = pipe2(O_CLOEXEC) stdin = io.open(r, 'rb', bufsize) exposed_stdin = io.open(w, 'wb', bufsize) stdout = kwargs.get('stdout', sys.stdout) exposed_stdout = None if stdout == PIPE: (r, w) = pipe2(O_CLOEXEC) stdout = w exposed_stdout = io.open(r, 'rb', bufsize) else: stdout = os.dup(stdout) stdout = io.open(stdout, 'wb', bufsize) exception = [None] t = PopenedThread(target=self._wrapper, args=(self._func, stdin, stdout, exception)) t.stdin = exposed_stdin t.stdout = exposed_stdout t.stderr = None t.exception = exception t.start() return t
def test_pipe2(self): self.assertRaises(TypeError, os.pipe2, 'DEADBEEF') self.assertRaises(TypeError, os.pipe2, 0, 0) # try calling with flags = 0, like os.pipe() r, w = os.pipe2(0) os.close(r) os.close(w) # test flags r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK) self.addCleanup(os.close, r) self.addCleanup(os.close, w) self.assertFalse(os.get_inheritable(r)) self.assertFalse(os.get_inheritable(w)) self.assertTrue(fcntl.fcntl(r, fcntl.F_GETFL) & os.O_NONBLOCK) self.assertTrue(fcntl.fcntl(w, fcntl.F_GETFL) & os.O_NONBLOCK) # try reading from an empty pipe: this should fail, not block self.assertRaises(OSError, os.read, r, 1) # try a write big enough to fill-up the pipe: this should either # fail or perform a partial write, not block try: os.write(w, b'x' * support.PIPE_MAX_SIZE) except OSError: pass
def test_pipe2(self): self.assertRaises(TypeError, os.pipe2, 'DEADBEEF') self.assertRaises(TypeError, os.pipe2, 0, 0) # try calling with flags = 0, like os.pipe() r, w = os.pipe2(0) os.close(r) os.close(w) # test flags r, w = os.pipe2(os.O_CLOEXEC | os.O_NONBLOCK) self.addCleanup(os.close, r) self.addCleanup(os.close, w) self.assertFalse(os.get_inheritable(r)) self.assertFalse(os.get_inheritable(w)) self.assertTrue(fcntl.fcntl(r, fcntl.F_GETFL) & os.O_NONBLOCK) self.assertTrue(fcntl.fcntl(w, fcntl.F_GETFL) & os.O_NONBLOCK) # try reading from an empty pipe: this should fail, not block self.assertRaises(OSError, os.read, r, 1) # try a write big enough to fill-up the pipe: this should either # fail or perform a partial write, not block try: os.write(w, b'x' * support.PIPE_MAX_SIZE) except OSError: pass # Issue 15989 self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1) self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1)
def __init__(self, sock, socket_transfer_size=4096, debug=False): self.signal = wayround_i2p.utils.threading.Signal( self, [ 'start', 'stop', 'error', 'restart', 'ssl wrap error', 'ssl wrapped', 'ssl ununwrapable', 'ssl unwrap error', 'ssl unwrapped' ]) if sock.gettimeout() != 0: raise ValueError("`sock' timeout must be 0") if not isinstance(sock, (socket.socket, ssl.SSLSocket)): raise TypeError( "sock must be of type socket.socket or ssl.SSLSocket") self.socket = sock self._socket_transfer_size = socket_transfer_size self._debug = debug self._pipe_inside = os.pipe2(os.O_NONBLOCK) self._pipe_outside = os.pipe2(os.O_NONBLOCK) # From remote process to current process. # For instance internals. self._strout = open(self._pipe_outside[1], 'wb', buffering=0) # For instance user. self.strout = open(self._pipe_outside[0], 'rb', buffering=0) # From current process to remote process. # For instance internals. self._strin = open(self._pipe_inside[0], 'rb', buffering=0) # For instance user. self.strin = open(self._pipe_inside[1], 'wb', buffering=0) # from strin to socket self._in_thread = None # from socket to strout self._out_thread = None self._connection_error_signalled = False self._connection_stop_signalled = False self._wrapping = False # flag indicating stop for instance threads self._stop_flag = False self._output_availability_watcher_thread = None self.connection = False self._in_thread_stop_event = threading.Event() self._out_thread_stop_event = threading.Event() return
def __init__(self, do_hook, args, malloc_so=None): self.do_hook = do_hook self.args = args self.malloc_so = malloc_so self.executable = os.path.realpath(args[0]) self.hook_addr = None inspect_fd_r, inspect_fd_w = os.pipe2(0) server_fd_r, server_fd_w = os.pipe2(0) stdin_fd_r, stdin_fd_w = os.pipe2(0) stdout_fd_r, stdout_fd_w = os.pipe2(0) server_pid = os.fork() if not server_pid: # child if inspect_fd_w == INSPECT_FD: os.set_inheritable(inspect_fd_w, True) else: os.dup2(inspect_fd_w, INSPECT_FD) os.close(inspect_fd_w) if server_fd_r == SERVER_FD: os.set_inheritable(server_fd_r, True) else: os.dup2(server_fd_r, SERVER_FD) os.close(server_fd_r) os.dup2(stdin_fd_r, pty.STDIN_FILENO) if stdin_fd_r != pty.STDIN_FILENO: os.close(stdin_fd_r) os.dup2(stdout_fd_w, pty.STDOUT_FILENO) os.dup2(stdout_fd_w, pty.STDERR_FILENO) if stdout_fd_w != pty.STDOUT_FILENO and stdout_fd_w != pty.STDERR_FILENO: os.close(stdout_fd_w) if do_hook: preload_libraries = [ os.path.dirname(os.path.realpath(__file__)) + '/wrapper_hook.so' ] else: preload_libraries = [ os.path.dirname(os.path.realpath(__file__)) + '/wrapper.so' ] if malloc_so: preload_libraries.append(malloc_so) os.execve(args[0], args, { **os.environ, 'LD_PRELOAD': ':'.join(preload_libraries) }) assert (False) else: # parent self.server_pid = server_pid self.inspect_fd = inspect_fd_r self.server_fd = server_fd_w self.stdin_fd = stdin_fd_w self.stdout_fd = stdout_fd_r
def request(self, consumer: str, type: int, flags: int = 0, default_vals: Optional[List[int]] = None, default_val: Optional[int] = None) -> None: self.consumer_name = consumer version = self.mock_gpiod.version_tuple() if type == MockGpiod.LINE_REQ_DIR_OUT: self.is_event = False if default_vals is not None: if version > (1, 2): logging.warn("default_vals is deprecated in gpiod 1.3+") self.value = default_vals[0] elif default_val is not None: if version < (1, 3): raise GpioException( "default_val not available in gpiod < 1.3") self.value = default_val elif type == MockGpiod.LINE_REQ_EV_BOTH_EDGES: self.is_event = True if version >= (1, 5): if flags & MockGpiod.LINE_REQ_FLAG_BIAS_DISABLE: self.bias = "disabled" elif flags & MockGpiod.LINE_REQ_FLAG_BIAS_PULL_DOWN: self.bias = "pulldown" elif flags & MockGpiod.LINE_REQ_FLAG_BIAS_PULL_UP: self.bias = "pullup" self.read_pipe, self.write_pipe = os.pipe2(os.O_NONBLOCK) else: raise GpioException("Unsupported GPIO Type") if flags & MockGpiod.LINE_REQ_FLAG_ACTIVE_LOW: self.invert = True
def __call__(self, mon, thr): self.mon = mon self.thrdid = thr.ident try: self.cpipe_r, self.cpipe_w = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) self.mon.register_event_pipe(self.cpipe_w, self._INTERRUPT_W) self.poller = LineMultiplexor() # The control pipe is given _lower_ priority than the output # from the proxy client. self.poller.add_file(self.cpipe_r, priority=1) self.update_prefix() self.pending_start = False self.pending_stop = False self.pending_intr = False self.pending_fini = False while not self.method.done: try: self.proxy_supervision_cycle() except Exception: self.mon.report_exception() finally: os.close(self.cpipe_r) os.close(self.cpipe_w)
def __init__(self, srcAddr, loggerName=None): if loggerName: self.logger = logging.getLogger(loggerName + '.' + 'pymsg') else: self.logger = __pyLogger__ try: os.unlink(srcAddr) except: self.logger.exception('Unlink failed') finally: self.srcAddr = srcAddr try: self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM | socket.SOCK_NONBLOCK) self.sock.bind(self.srcAddr) except (OSError, IOError) as e: self.logger.exception("Create '{}' failed".format(self.srcAddr)) raise self.retry = 2 self.timeOut = 0.1 self.gpList = list() try: self.rLoP, self.wLoP = os.pipe2(os.O_NONBLOCK) except OSError: self.logger.exception('Create pipe failed') raise
def __init__(self, path): if type(path) != str: raise TypeError("Path must be of type string!") self.path = path self.gstreamer = GStreamerInterface("transcoder") self.gstreamerthread = None self.source = self.gstreamer.CreateElement("filesrc", "source") self.decoder = self.gstreamer.CreateElement("decodebin", "decoder") self.converter = self.gstreamer.CreateElement("audioconvert", "converter") self.encoder = self.gstreamer.CreateElement("lamemp3enc", "encoder") self.sink = self.gstreamer.CreateElement("fdsink", "sink") self.unixpipesource, self.unixpipesink = os.pipe2(os.O_NONBLOCK) self.source.set_property("location", self.path) self.encoder.set_property("target", 1) self.encoder.set_property("bitrate", 320) self.encoder.set_property("cbr", True) self.sink.set_property("fd", self.unixpipesink) self.source.link(self.decoder) self.converter.link(self.encoder) self.encoder.link(self.sink) self.decoder.connect("pad-added", self.onDecoderPadAdded)
def run(self): (parentReadPipeFileNo, childWritePipeFileNo) = os.pipe2(os.O_NONBLOCK) (childReadPipeFileNo, parentWritePipeFileNo) = os.pipe2(os.O_NONBLOCK) pid = os.fork() # parent if pid: os.close(childReadPipeFileNo) os.close(childWritePipeFileNo) self.__runParentLoop(parentReadPipeFileNo, parentWritePipeFileNo) # child else: os.close(parentReadPipeFileNo) os.close(parentWritePipeFileNo) self.__runChildLoop(childReadPipeFileNo, childWritePipeFileNo) sys.exit(0)
def __init__(self, stdin, stdout=PIPE, password=''): ior, iow = os.pipe2(0) # os.pipe() would set O_CLOEXEC super().__init__( stdin=stdin, stdout=stdout, args=[ # TODO: we'd like to avoid these: # gpg: directory '/home/osso/.gnupg' created # gpg: keybox '/home/osso/.gnupg/pubring.kbx' created self._get_bin(), '--batch', # Symmetric encryption using a password '--symmetric', '--passphrase-fd', str(ior), # Password derivation to a secret key '--s2k-mode', '3', '--s2k-digest-algo', 'SHA512', '--s2k-count', '65536', # No compression here; we do that using DEFLATE '--compress-algo', 'none', # AES-256 CFB '--cipher-algo', 'AES256', ]) os.write(iow, '{}\n'.format(password).encode('ascii')) os.close(iow) os.close(ior)
def do(self): cache = self.args['cache'] timestamp_file = self.args.get('timestamp_file', self.timestamp_file) if cache: try: mtime = os.path.getmtime(timestamp_file) except OSError: need_update = True else: need_update = time.time() > mtime + cache else: need_update = True if need_update: kwargs = {} args = ['apt-get', '--force-yes', '-y', '--fix-missing'] watch = self.args.get('watch') if watch: r, w = os.pipe2(os.O_NONBLOCK) kwargs['stdout'] = os.fdopen(w) kwargs['watcher'] = apt_watcher(watch, os.fdopen(r)) kwargs['short_args'] = ['apt-get', 'update'] args.extend(['-oAPT::Status-Fd=1', 'update']) res = self.sh(args, **kwargs) res['stdout'] = '' else: res = self.sh(args + ['update'], **kwargs) if cache: with codecs.open(timestamp_file, 'w', 'utf8') as fd: fd.write(str(time.time())) res['changed'] = True else: res = dict(rc=0, changed=False) return res
def createProcess(self, outputFd): """Create the process. @param outputFd if not None, use this as output stream descriptor.""" # Create the process file descriptor pairs manually. Otherwise # it is not possible to wait() for the process first and continue # to read from the other side of the pipe after garbage collection # of the process object. self.inputPipe = None outputPipeFds = None if outputFd is None: outputPipeFds = os.pipe2(os.O_CLOEXEC) outputFd = outputPipeFds[1] if self.upstreamProcessOutput.getOutputStreamDescriptor() is None: self.process = subprocess.Popen( self.execArgs, executable=self.executable, stdin=subprocess.PIPE, stdout=outputFd) self.inputPipe = self.process.stdin flags = fcntl.fcntl(self.inputPipe.fileno(), fcntl.F_GETFL) fcntl.fcntl(self.inputPipe.fileno(), fcntl.F_SETFL, flags|os.O_NONBLOCK) else: self.process = subprocess.Popen( self.execArgs, executable=self.executable, stdin=self.upstreamProcessOutput.getOutputStreamDescriptor(), stdout=outputFd) self.processOutput = None if outputPipeFds != None: # Close the write side now. os.close(outputPipeFds[1]) self.processOutput = TransformationProcessOutputStream( outputPipeFds[0])
def __call__(self, mon, thr): self.mon = mon self.thrdid = thr.ident try: self.cpipe_r, self.cpipe_w = os.pipe2(os.O_NONBLOCK|os.O_CLOEXEC) self.mon.register_event_pipe(self.cpipe_w, self._INTERRUPT_W) self.poller = LineMultiplexor() # The control pipe is given _lower_ priority than the output # from the proxy client. self.poller.add_file(self.cpipe_r, priority=1) self.update_prefix() self.pending_start = False self.pending_stop = False self.pending_intr = False self.pending_fini = False while not self.method.done: try: self.proxy_supervision_cycle() except Exception: self.mon.report_exception() finally: os.close(self.cpipe_r) os.close(self.cpipe_w)
def handle_unix_signals(): read_fd, write_fd = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) for sig in (signal.SIGINT, signal.SIGTERM): signal.signal(sig, lambda x, y: None) signal.siginterrupt(sig, False) signal.set_wakeup_fd(write_fd) return read_fd
def signal_input(inter_ob, inp): global signal_pipe if signal_pipe is None: signal_pipe = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) ldmud.register_socket(signal_pipe[0], receive_input, select.POLLIN) queue.append((inter_ob, inp,)) os.write(signal_pipe[1], b' ')
def test_custom_valid_script(tmpdir, valid_script): os.chdir(str(tmpdir)) piper, pipew = os.pipe2(os.O_NONBLOCK|os.O_CLOEXEC) env = dict(os.environ) env['POSTTEST_FD'] = str(pipew) commands_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'commands') command = "devparrot --option custom_commands_dir,[\\'"+commands_dir+"\\'] --option fail_on_command_error,True --configrc "+valid_script print(command) check_call(command, shell=True, cwd=str(tmpdir), pass_fds=(pipew,), env=env)
def start_server(serial_config: dict, server_config: dict, caster_config: dict, *, verbose: int = False) -> int: in_spec = '{port}:{baudrate}:{bytesize}:{parity}:{stopbits}:{flowcontrol}'.format( **serial_config) out_spec = ':{password}@{domain}:{port}/{mountpoint}:{str}'.format( **caster_config) inject = server_config['inject'] if inject: if isinstance(inject, int): inject = (str(inject), ) else: inject = tuple(str(msgid) for msgid in server_config['inject']) pipe_output, pipe_input = pipe2(O_NONBLOCK) verbose = ('-t', str(verbose)) if verbose is not False else () str2str = f'{STR2STR}', '-out', f'ntrips://{out_spec}', *verbose str2str_input = pipe_output rtcm_proxy = 'python', f'{RTCM_PROXY}', '-in', f'serial://{in_spec}', '-a', f'{server_config["anchor"]}', \ '-m', *inject, '-i', f'{server_config["interval"]}', '-l', str(RTCM_PROXY_LOG) print("Starting RTCM proxy...") print(f"Command: {' '.join(rtcm_proxy)}") Popen(rtcm_proxy, encoding='utf-8', stdout=pipe_input) else: str2str = f'{STR2STR}', '-in', f'serial://{in_spec}', '-out', f'ntrips://{out_spec}' str2str_input = DEVNULL print("Starting NTRIP server...") print(f"Command: {' '.join(str2str)}") global str2str_process PID_FILE.touch() if ACCUMULATIVE_LOGS: log_file = STR2STR_LOG.with_name(STR2STR_LOG.stem + '_' + strftime('%d-%m-%Y_%H-%M-%S') + STR2STR_LOG.suffix) else: log_file = STR2STR_LOG str2str_process = Popen(str2str, encoding='utf-8', stdin=str2str_input, stdout=log_file.open('w'), stderr=STDOUT) PID_FILE.write_text(str(str2str_process.pid)) print("NTRIP server process spawned") return 0
def __init__(self): self.old_lines = [] self.running = False self.timeout = 0.5 self.selector = selectors.DefaultSelector() # self-pipe to avoid concurrency issues with signal self.resize_in, self.resize_out = os.pipe2(os.O_NONBLOCK) signal.signal(signal.SIGWINCH, self.on_resize)
def test_pipe2(self): self.assertRaises(TypeError, os.pipe2, 'DEADBEEF') self.assertRaises(TypeError, os.pipe2, 0, 0) r, w = os.pipe2(0) os.close(r) os.close(w) r, w = os.pipe2(os.O_CLOEXEC | os.O_NONBLOCK) self.addCleanup(os.close, r) self.addCleanup(os.close, w) self.assertFalse(os.get_inheritable(r)) self.assertFalse(os.get_inheritable(w)) self.assertFalse(os.get_blocking(r)) self.assertFalse(os.get_blocking(w)) self.assertRaises(OSError, os.read, r, 1) try: os.write(w, b'x' * support.PIPE_MAX_SIZE) except OSError: pass
def __init__(self, *, check_args=True): self._check_args = check_args fdin, fdout = os.pipe2(os.O_NONBLOCK|os.O_CLOEXEC) self._wakeupfd = os.fdopen(fdin, 'rb') self._signalfd = os.fdopen(fdout, 'wb') self._soon_lock = threading.RLock() self._soon = collections.deque() self._later = [] self._timer = time.monotonic
def _pipeline(commands, env, fd_in, fd_out, fd_err): """Run a series of commands connected by their stdout/stdin.""" pids = [] first = True for i, command in enumerate(commands): last = i == len(commands) - 1 # If there are more commands upcoming then we need to set up a pipe. if not last: fd_in_new, fd_out_new = pipe2(O_CLOEXEC) pids += [fork()] child = pids[-1] == 0 if child: if not first: # Establish communication channel with previous process. dup2(fd_in_old, stdin_.fileno()) close_(fd_in_old) close_(fd_out_old) else: dup2(fd_in, stdin_.fileno()) if not last: # Establish communication channel with next process. close_(fd_in_new) dup2(fd_out_new, stdout_.fileno()) close_(fd_out_new) else: dup2(fd_out, stdout_.fileno()) # Stderr is redirected for all commands in the pipeline because each # process' output should be rerouted and stderr is not affected by # the pipe between the processes in any way. dup2(fd_err, stderr_.fileno()) _exec(*command, env=env) # This statement should never be reached: either exec fails in # which case a Python exception should be raised or the program is # started in which case this process' image is overwritten anyway. # Keep it to be absolutely safe. _exit(-1) else: if not first: close_(fd_in_old) close_(fd_out_old) else: first = False # If there are further commands then update the "old" pipe file # descriptors for future reference. if not last: fd_in_old = fd_in_new fd_out_old = fd_out_new return pids
def popen(self, args=(), **kwargs): kwargs = kwargs.copy() thread_stdout = kwargs.get('stdout', sys.stdout) kwargs['stdout'] = PIPE p = self._cmd.popen(bufsize=0, **kwargs) thread_stdin = p.stdout # Wrap self._func in order to catch its exceptions (these we will # re-raise in the main thread. We'll also close the subprocess's # stdout when the thread exits. p._thread_exception = None @functools.wraps(self._func) def func(*args, **kwargs): try: self._func(*args, **kwargs) except: e = sys.exc_info() p._thread_exception = e finally: # Let our subprocess know that nobody is reading its output # anymore. Let any downstream processes know that nobody is # producing input for it anymore. thread_stdin.close() thread_stdout.close() if thread_stdout == PIPE: (p2cread, p2cwrite) = pipe2(O_CLOEXEC) # expose the thread's stdout on the Popen object p.stdout = io.open(p2cread, 'rb') thread_stdout = p2cwrite else: thread_stdout = os.dup(thread_stdout.fileno()) # prevent caller from reading from the subprocess's stdout # that's not its job. p.stdout = None thread_stdout = io.open(thread_stdout, 'wb') t = get_thread(func, args=(thread_stdin, thread_stdout)) original_wait = p.wait def wait(*args, **kwargs): code = original_wait(*args, **kwargs) t.join() if p._thread_exception: reraise(*p._thread_exception) return code p.wait = wait t.start() return p
def __pipe_common(self, mu, files_ptr, flags): #logging.warning("skip syscall pipe files [0x%08X]"%files_ptr) ps = os.pipe2(flags) logger.info("pipe return %r" % (ps, )) self.__pcb.add_fd("[pipe_r]", "[pipe_r]", ps[0]) self.__pcb.add_fd("[pipe_w]", "[pipe_w]", ps[1]) mu.mem_write(files_ptr, int(ps[0]).to_bytes(4, byteorder='little')) mu.mem_write(files_ptr + 4, int(ps[1]).to_bytes(4, byteorder='little')) return 0
def __init__(self, *, check_args=True): self._check_args = check_args fdin, fdout = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) self._wakeupfd = os.fdopen(fdin, 'rb') self._signalfd = os.fdopen(fdout, 'wb') self._soon_lock = threading.RLock() self._soon = collections.deque() self._later = [] self._timer = time.monotonic
def _create_pipe(): """Creates a readable co-operative (gevent) file-like object and a writable non-blocking raw file descriptor.""" try: # Python 3, Linux r, w = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) except AttributeError: r, w = os.pipe() fcntl.fcntl(w, fcntl.F_SETFL, fcntl.fcntl(w, fcntl.F_GETFL) | os.O_NONBLOCK) return FileObject(r, "rb"), w
def _set_signal_handlers(self): """Set the signal handlers.""" def noopSignalHandler(*args): pass self._sigchld_handler = signal.signal(signal.SIGCHLD, noopSignalHandler) self._sigint_handler = signal.signal(signal.SIGINT, noopSignalHandler) self._sigterm_handler = signal.signal(signal.SIGTERM, noopSignalHandler) sig_r_fd, sig_w_fd = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) signal.set_wakeup_fd(sig_w_fd) self._add_read_fd_handler(sig_r_fd, self._handle_sig_fd, None)
def pipe2(): try: read_fd, write_fd = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) except AttributeError: import fcntl read_fd, write_fd = os.pipe() for fd in (read_fd, write_fd): flag = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, flag | fcntl.FD_CLOEXEC) flag = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, flag | os.O_NONBLOCK) return read_fd, write_fd
def __init__(self, sockfile, args, executable=None, use_path=True, env=None, restart=False): """ Start a new daemon. The child will be started and Unix socket will be opened. Connections are not yet accepted, call the run method to start handling connection and hand over the program execution to the SignalProxyDaemon. :param sockfile: Path to the Unix to listen on :param Sequence[str] args: Args of the process to exec :param str executable: Optional, if given this executable instead of the zeroth argument is used as executable. :param bool use_path: Use the PATH variable to find the executable, defaults to True :param dict[str,str] env: If given set the child process's environment, otherwise use the environment of the current process. :param bool restart: If True, restart the child process if it died, otherwise the SignalProxyDaemon will shut itself down, if the child dies. """ if not args: raise ValueError("Empty argument list") if executable is None: executable = args[0] self.sockfile = sockfile self.restart = restart self.args = args self.executable = executable self.use_path = use_path self.env = env self.pid = None self.last_forkexec = -1 try: options = os.O_CLOEXEC | os.O_NONBLOCK self.sig_read_fd, self.sig_write_fd = os.pipe2(options) signal.set_wakeup_fd(self.sig_write_fd) for signo in self.sigset: signal.signal(signo, self._noop_handler) logger.info('Listening on %s', sockfile) if os.path.exists(sockfile): os.unlink(sockfile) self.server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.server.bind(sockfile) self.server.setblocking(False) self.server.listen(0) self.poll = select.poll() self.connections = {} self._forkexec() self.state = DaemonState.started except: self._restore_signals() self._close_files() raise
def __init__(self, flags=0, terminal=False): """Creates a Pipe you can easily write to and read from. Default is to open up a regular pipe.""" if flags or not terminal: self._readfd, self._writefd = os.pipe2(flags) else: # terminal self._readfd, self._writefd = pty.openpty() os.set_inheritable(self._readfd, True) os.set_inheritable(self._writefd, True) self.readobj = open(self._readfd, "rb", 0) self.writeobj = open(self._writefd, "wb", 0)
def signal(self, signalnum: int, handler: Callable[[int], Any]) -> None: if self._signal_r is None: self._signal_r, self._signal_w = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) if sys.version_info >= (3, 7): self._old_wakeup_fd = signal.set_wakeup_fd( self._signal_w, warn_on_full_buffer=False) else: self._old_wakeup_fd = signal.set_wakeup_fd(self._signal_w) self.open(self._signal_r).read_cb = lambda buf: None pending = partial(handler, signalnum) signal.signal(signalnum, lambda signum, frame: self._pending_signals.add(pending))
def pipe_no_wait(): """ Generate a non-block pipe used to fetch the STDERR of ffmpeg. """ if platform == "linux" or platform == "linux2" or platform == "darwin" or platform.startswith( "openbsd"): import fcntl import os pipe_rd = 0 pipe_wd = 0 if hasattr(os, "pipe2"): pipe_rd, pipe_wd = os.pipe2(os.O_NONBLOCK) else: pipe_rd, pipe_wd = os.pipe() try: fl = fcntl.fcntl(pipe_rd, fcntl.F_GETFL) fcntl.fcntl(pipe_rd, fcntl.F_SETFL, fl | os.O_NONBLOCK) except: print(sys.exc_info()[1]) return None, None return pipe_rd, pipe_wd elif platform == "win32": # https://stackoverflow.com/questions/34504970/non-blocking-read-on-os-pipe-on-windows import msvcrt import os from ctypes import windll, byref, wintypes, WinError, POINTER from ctypes.wintypes import HANDLE, DWORD, BOOL pipe_rd, pipe_wd = os.pipe() LPDWORD = POINTER(DWORD) PIPE_NOWAIT = wintypes.DWORD(0x00000001) ERROR_NO_DATA = 232 SetNamedPipeHandleState = windll.kernel32.SetNamedPipeHandleState SetNamedPipeHandleState.argtypes = [HANDLE, LPDWORD, LPDWORD, LPDWORD] SetNamedPipeHandleState.restype = BOOL h = msvcrt.get_osfhandle(pipe_rd) res = windll.kernel32.SetNamedPipeHandleState(h, byref(PIPE_NOWAIT), None, None) if res == 0: print(WinError()) return None, None return pipe_rd, pipe_wd
async def stream_pipe(loop): r, w = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) # Wrap the read end of the pipe into a StreamReader reader_fobj = os.fdopen(r, 'rb', 0) reader = asyncio.StreamReader(loop=loop) reader_proto = asyncio.StreamReaderProtocol(reader) await loop.connect_read_pipe(lambda: reader_proto, reader_fobj) # Wrap the write end of the pipe into a StreamWriter writer_fobj = os.fdopen(w, 'wb', 0) writer_trans, writer_proto = await loop.connect_write_pipe( asyncio.streams.FlowControlMixin, writer_fobj) writer = asyncio.streams.StreamWriter(writer_trans, writer_proto, None, loop) return reader, reader_fobj, writer, writer_fobj
def do(self): """install packages""" packages = self.args['packages'] debconf = self.args['debconf'] if not packages: return dict(rc=1, stderr='no packages provided') installed = self.get_packages_list(packages) to_install = [p for p in packages if p not in installed] if to_install: watch = self.args.get('watch') update_cache = self.args.get('update_cache') if update_cache is not None: update(cache=update_cache, watch=watch).do() if debconf: for p in to_install: conf = debconf.get(p, []) for i, c in enumerate(self.debconf.get(p, [])): if isinstance(conf, list): v = conf[i] else: v = conf stdin = ' '.join([p] + c + [v]) self.sh(['debconf-set-selections'], stdin=stdin) env = {} for k in ('debian_priority', 'debian_frontend'): v = self.args.get(k) if v: env[k.upper()] = v kwargs = {'env': env} args = [ 'apt-get', 'install', '-qqy', '-oDpkg::Options::=--force-confold' ] if not self.args.get('install_recommends'): args.append('--no-install-recommends') if watch: r, w = os.pipe2(os.O_NONBLOCK) kwargs['stdout'] = os.fdopen(w) kwargs['watcher'] = apt_watcher(watch, os.fdopen(r)) kwargs['short_args'] = ['apt-get', 'install'] args.extend(['-oAPT::Status-Fd=1'] + packages) res = self.sh(args, **kwargs) res['stdout'] = '' else: res = self.sh(args + packages, **kwargs) else: res = dict(rc=0) res['changed'] = to_install return res
def __pipe_common(self, mu, files_ptr, flags): #logging.warning("skip syscall pipe files [0x%08X]"%files_ptr) if (hasattr(os, "pipe2")): ps = os.pipe2(flags) else: logging.warning("pipe2 not support use pipe") ps = os.pipe() # logging.debug("pipe return %r" % (ps, )) self.__pcb.add_fd("[pipe_r]", "[pipe_r]", ps[0]) self.__pcb.add_fd("[pipe_w]", "[pipe_w]", ps[1]) #files_ptr 无论32还是64 都是个int数组,因此写4没有问题 mu.mem_write(files_ptr, int(ps[0]).to_bytes(4, byteorder='little')) mu.mem_write(files_ptr + 4, int(ps[1]).to_bytes(4, byteorder='little')) return 0
def setUp(self): self.temporary_dir = tempfile.TemporaryDirectory() self.runtime_dir = os.path.join(self.temporary_dir.name, 'run') self.config_home = os.path.join(self.temporary_dir.name, 'config') self.dbus_dir = os.path.join(self.temporary_dir.name, 'dbus-1') os.mkdir(self.runtime_dir, mode=0o700) os.mkdir(self.config_home, mode=0o700) os.mkdir(self.dbus_dir, mode=0o700) os.mkdir(os.path.join(self.config_home, 'dconf')) os.environ['DCONF_BLAME'] = '' os.environ['XDG_RUNTIME_DIR'] = self.runtime_dir os.environ['XDG_CONFIG_HOME'] = self.config_home # Prepare dbus-daemon config. dbus_daemon_config = os.path.join(self.dbus_dir, 'session.conf') with open(dbus_daemon_config, 'w') as file: file.write(DAEMON_CONFIG.format(servicedir=self.dbus_dir)) # Prepare service config. name = 'ca.desrt.dconf' path = os.path.join(self.dbus_dir, '{}.service'.format(name)) with open(path, 'w') as file: config = SERVICE_CONFIG.format(name=name, exec=dconf_service_exe) file.write(config) # Pipe where daemon will write its address. read_fd, write_fd = os.pipe2(0) args = [ 'dbus-daemon', '--config-file={}'.format(dbus_daemon_config), '--nofork', '--print-address={}'.format(write_fd) ] # Start daemon self.dbus_daemon_process = subprocess.Popen(args, pass_fds=[write_fd]) # Close our writing end of pipe. Daemon closes its own writing end of # pipe after printing address, so subsequent reads shouldn't block. os.close(write_fd) with os.fdopen(read_fd) as f: dbus_address = f.read().rstrip() # Prepare environment os.environ['DBUS_SESSION_BUS_ADDRESS'] = dbus_address
def handle_unix_signals(self): if iswindows: # TODO: test this on windows self.signal_read_socket, self.signal_write_socket = socket.socketpair() self.signal_read_socket.setblocking(False) self.signal_write_socket.setblocking(False) read_fd, write_fd = self.signal_read_socket.fileno(), self.signal_write_socket.fileno() else: read_fd, write_fd = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) for sig in (signal.SIGINT, signal.SIGTERM): signal.signal(sig, lambda x, y: None) signal.siginterrupt(sig, False) signal.set_wakeup_fd(write_fd) self.signal_notifier = QSocketNotifier(read_fd, QSocketNotifier.Read, self) self.signal_notifier.setEnabled(True) self.signal_notifier.activated.connect(self.signal_received, type=Qt.QueuedConnection)
def __init__(self, glfw_window, opts, args): Thread.__init__(self, name='ChildMonitor') startup_session = create_session(opts, args) self.cursor_blink_zero_time = monotonic() self.cursor_blinking = True self.glfw_window_title = None self.action_queue = Queue() self.pending_resize = True self.resize_gl_viewport = False self.shutting_down = False self.screen_update_delay = opts.repaint_delay / 1000.0 self.signal_fd = handle_unix_signals() self.read_wakeup_fd, self.write_wakeup_fd = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) self.read_dispatch_map = { self.signal_fd: self.signal_received, self.read_wakeup_fd: self.on_wakeup } self.all_writers = [] self.timers = Timers() self.ui_timers = Timers() self.pending_ui_thread_calls = Queue() self.write_dispatch_map = {} set_boss(self) cell_size.width, cell_size.height = set_font_family( opts.font_family, opts.font_size) self.opts, self.args = opts, args self.glfw_window = glfw_window glfw_window.framebuffer_size_callback = self.on_window_resize glfw_window.char_mods_callback = self.on_text_input glfw_window.key_callback = self.on_key glfw_window.mouse_button_callback = self.on_mouse_button glfw_window.scroll_callback = self.on_mouse_scroll glfw_window.cursor_pos_callback = self.on_mouse_move glfw_window.window_focus_callback = self.on_focus self.tab_manager = TabManager(opts, args, startup_session) self.sprites = Sprites() self.cell_program = ShaderProgram(*cell_shader) self.cursor_program = ShaderProgram(*cursor_shader) self.borders_program = BordersProgram() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) self.sprites.do_layout(cell_size.width, cell_size.height) self.glfw_window.set_click_cursor(False) self.show_mouse_cursor() self.start_cursor_blink()
def run_as_lxc(container, command, timeout=10): """ run command within container and returns output command is a list of command and arguments, The output is limited to the buffersize of pipe (64k on linux) """ read_fd, write_fd = os.pipe2(os.O_CLOEXEC | os.O_NONBLOCK) pid = container.attach(lxc.attach_run_command, command, stdout=write_fd, stderr=write_fd) timer = Timer(timeout, os.kill, args=(pid, signal.SIGKILL), kwargs=None) if timeout: timer.start() output_list = [] os.waitpid(pid, 0) timer.cancel() try: while True: output_list.append(os.read(read_fd, 1024)) except BlockingIOError: pass return bytes().join(output_list)
def setUp(self): """Set up an even loop fixture to watch for signals from spawned tasks. """ super().setUp() self._sigchld_caught = False def noopSignalHandler(*args): pass original_sigchld_handler = signal.signal(signal.SIGCHLD, noopSignalHandler) self.addCleanup(lambda: signal.signal(signal.SIGCHLD, original_sigchld_handler)) sig_r_fd, sig_w_fd = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) signal.set_wakeup_fd(sig_w_fd) pre_loop_barrier = Barrier(2) self._post_loop_barrier = Barrier(2) def loop(): pre_loop_barrier.wait(1) selector = DefaultSelector() selector.register(sig_r_fd, EVENT_READ) with suppress(StopIteration): while True: events = selector.select(timeout=5) if len(events) == 0: raise StopIteration for key, mask in events: if key.fd == sig_r_fd: data = os.read(sig_r_fd, 4) self._sigchld_caught = True raise StopIteration self._post_loop_barrier.wait(1) test_loop = Thread(target=loop) self.addCleanup(lambda: test_loop.join(1)) test_loop.start() pre_loop_barrier.wait(1)
def __init__(self, main, *args, banner="", error_log="error-log", **kwargs): try: locale.setlocale(locale.LC_ALL, '') self._encoding = locale.getpreferredencoding() self.open_error_log(error_log) # Establish signal handling before doing anything else. for sig in self._SIGNALS: signal.signal(sig, self.dummy_signal_handler) signal.siginterrupt(sig, False) self._pid = os.getpid() try: self._sigpipe = os.pipe2(os.O_NONBLOCK|os.O_CLOEXEC) except AttributeError: self._sigpipe = os.pipe() fcntl.fcntl(self._sigpipe[0], fcntl.F_SETFL, os.O_NONBLOCK) fcntl.fcntl(self._sigpipe[1], fcntl.F_SETFL, os.O_NONBLOCK) fcntl.fcntl(self._sigpipe[0], fcntl.F_SETFD, fcntl.FD_CLOEXEC) fcntl.fcntl(self._sigpipe[1], fcntl.F_SETFD, fcntl.FD_CLOEXEC) self._old_wakeup = signal.set_wakeup_fd(self._sigpipe[1]) self._tasks = queue.PriorityQueue() self._stop_event = threading.Event() self._resume_event = threading.Event() # pause_event is active low self._resume_event.set() self._output_thread = threading.current_thread() self._input_thread = threading.Thread( target=self._input_thread_fn, daemon=True) self._mwork_thread = threading.Thread( target=self._work_thread_fn, args=(main, args, kwargs)) self._counters_lock = threading.Lock() self._n_work_threads = 0 self._active_work_threads = 0 self._worker_event_queues = {} self._worker_exceptions = {} # Terminal-related state. self._banner = banner self._addmsg = "Press ESC to stop." self._lines = [] self._line_attrs = [] self._line_indexes = {} self._line_indexes_used = 0 self._last_prefix = {} self._last_status = {} self._initscr_plus() # Release the hounds. self._input_thread.start() self._mwork_thread.start() self._output_thread_fn() # Control returns to this point only when we are tearing stuff # down. Our internal threads can't practically be terminated, # but they are daemonized, and the others should have already # terminated. finally: curses.endwin() signal.set_wakeup_fd(self._old_wakeup) os.close(self._sigpipe[0]) os.close(self._sigpipe[1]) if self._worker_exceptions: for tid in sorted(self._worker_exceptions.keys()): sys.stderr.write("Exception in thread {}:\n" .format(tid)) traceback.print_exception(*self._worker_exceptions[tid]) sys.stderr.write("\n") if sys.exc_info() == (None, None, None): raise SystemExit(1)
def __init__(self): read, write = os.pipe2(os.O_NONBLOCK | os.O_CLOEXEC) self.rfile = os.fdopen(read, 'rb', 0) self.wfile = os.fdopen(write, 'wb', 0)
def judge_diff(self, src_path, exe_path, argv, envp, in_path, ans_path, \ timelimit, memlimit, callback=None): '''Diff judge. Args: src_path (string): Executable source path. exe_path (string): Executable or interpreter path in the sandbox. argv ([string]): List of arguments. envp ([string]): List of environment variables. in_path (string): Input file path. ans_path (string): Answer file path. timelimit (int): Timelimit. memlimit (int): Memlimit. callback (function): Callback of return_future. Returns: None ''' def _started_cb(task_id): '''Started callback. Close unused file descriptors after the task is started. Args: task_id (int): Task ID. Returns: None ''' nonlocal infile_fd nonlocal outpipe_fd os.close(infile_fd) os.close(outpipe_fd[1]) IOLoop.instance().add_handler(outpipe_fd[0], _diff_out, \ IOLoop.READ | IOLoop.ERROR) def _done_cb(task_id, stat): '''Done callback. Args: task_id (int): Task ID. stat (dict): Task result. Returns: None ''' nonlocal result_stat nonlocal result_pass result_stat = (stat['utime'], stat['peakmem'], stat['detect_error']) if result_pass is not None: callback((result_pass, result_stat)) def _diff_out(evfd, events): '''Diff the output of the task. Args: evfd (int): Event file descriptor. events (int): Event flags. Returns: None ''' nonlocal outpipe_fd nonlocal ansfile nonlocal result_stat nonlocal result_pass end_flag = False if events & IOLoop.READ: while True: try: data = os.read(outpipe_fd[0], 65536) except BlockingIOError: break ansdata = ansfile.read(len(data)) if data != ansdata: result_pass = False end_flag = True break if len(ansdata) == 0: if len(ansfile.read(1)) == 0: result_pass = True else: result_pass = False end_flag = True break if (events & IOLoop.ERROR) or end_flag: if result_pass is None: if len(ansfile.read(1)) == 0: result_pass = True else: result_pass = False IOLoop.instance().remove_handler(evfd) os.close(outpipe_fd[0]) ansfile.close() if result_stat is not None: callback((result_pass, result_stat)) judge_uid, judge_gid = StdChal.get_restrict_ugid() # Prepare I/O and stat. with StackContext(Privilege.fileaccess): infile_fd = os.open(in_path, os.O_RDONLY | os.O_CLOEXEC) ansfile = open(ans_path, 'rb') outpipe_fd = os.pipe2(os.O_CLOEXEC) fcntl.fcntl(outpipe_fd[0], fcntl.F_SETFL, os.O_NONBLOCK) result_stat = None result_pass = None # Prepare judge environment. with StackContext(Privilege.fileaccess): judge_path = self.chal_path + '/run_%d'%judge_uid os.mkdir(judge_path, mode=0o771) shutil.copyfile(src_path, judge_path + '/a.out', \ follow_symlinks=False) with StackContext(Privilege.fullaccess): os.chown(judge_path + '/a.out', judge_uid, judge_gid) os.chmod(judge_path + '/a.out', 0o500) task_id = PyExt.create_task(exe_path, argv, envp, \ { 0: infile_fd, 1: outpipe_fd[1], 2: outpipe_fd[1], }, \ '/home/%d/run_%d'%(self.uniqid, judge_uid), 'container/standard', \ judge_uid, judge_gid, timelimit, memlimit, \ PyExt.RESTRICT_LEVEL_HIGH) if task_id is None: os.close(infile_fd) os.close(outpipe_fd[0]) os.close(outpipe_fd[1]) ansfile.close() callback((False, (0, 0, PyExt.DETECT_INTERNALERR))) else: PyExt.start_task(task_id, _done_cb, _started_cb)
def judge(self, src_path, exe_relpath, argv, envp, check_ugid, test_ugid, \ test_relpath, test_param, metadata, callback=None): '''I/O redirect special judge. Args: src_path (string): Executable source path. exe_relpath (string): Executable or interpreter path in the sandbox. argv ([string]): List of arguments. envp ([string]): List of environment variables. check_ugid (int, int): Check UID/GID. test_ugid (int, int): Test UID/GID. test_relpath (string): Test relative path. test_param (dict): Test parameters. metadata (dict): Metadata. callback (function): Callback of return_future. Returns: None ''' def _check_started_cb(task_id): '''Check started callback. Close unused file descriptors after the check is started. Args: task_id (int): Task ID. Returns: None ''' nonlocal inpipe_fd nonlocal outpipe_fd nonlocal ansfile_fd nonlocal check_infile_fd os.close(inpipe_fd[1]) os.close(outpipe_fd[0]) if ansfile_fd is not None: os.close(ansfile_fd) if check_infile_fd is not None: os.close(check_infile_fd) def _test_started_cb(task_id): '''Test started callback. Close unused file descriptors after the test is started. Args: task_id (int): Task ID. Returns: None ''' nonlocal inpipe_fd nonlocal outpipe_fd nonlocal outfile_fd nonlocal test_infile_fd os.close(inpipe_fd[0]) os.close(outpipe_fd[1]) os.close(outfile_fd) if test_infile_fd is not None: os.close(test_infile_fd) def _done_cb(): '''Done callback.''' nonlocal result_stat nonlocal result_pass if result_pass is not None and result_stat is not None: callback((result_pass, result_stat)) return def _check_done_cb(task_id, stat): '''Check done callback. Args: task_id (int): Task ID. stat (dict): Task result. Returns: None ''' nonlocal result_pass if stat['detect_error'] == PyExt.DETECT_NONE: result_pass = True else: result_pass = False _done_cb() def _test_done_cb(task_id, stat): '''Test done callback. Args: task_id (int): Task ID. stat (dict): Task result. Returns: None ''' nonlocal result_stat result_stat = (stat['utime'], stat['peakmem'], stat['detect_error']) _done_cb() result_stat = None result_pass = None in_path = test_param['in'] ans_path = test_param['ans'] timelimit = test_param['timelimit'] memlimit = test_param['memlimit'] check_uid, check_gid = check_ugid test_uid, test_gid = test_ugid test_path = self.container_path + test_relpath output_relpath = test_relpath + '/output.txt' output_path = self.container_path + output_relpath verdict_relpath = test_relpath + '/verdict.txt' verdict_path = self.container_path + verdict_relpath # Prepare test environment. with StackContext(Privilege.fileaccess): os.mkdir(test_path, mode=0o771) shutil.copyfile(src_path, test_path + '/a.out', \ follow_symlinks=False) with StackContext(Privilege.fullaccess): os.chown(test_path + '/a.out', test_uid, test_gid) os.chmod(test_path + '/a.out', 0o500) # Prepare I/O. with StackContext(Privilege.fileaccess): try: check_infile_fd = os.open(in_path, os.O_RDONLY | os.O_CLOEXEC) test_infile_fd = os.open(in_path, os.O_RDONLY | os.O_CLOEXEC) except FileNotFoundError: check_infile_fd = None test_infile_fd = None try: ansfile_fd = os.open(ans_path, os.O_RDONLY | os.O_CLOEXEC) except FileNotFoundError: ansfile_fd = None outfile_fd = os.open(output_path, \ os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC, mode=0o400) os.close(os.open(verdict_path, \ os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC, mode=0o400)) with StackContext(Privilege.fullaccess): os.chown(output_path, check_uid, check_gid) os.chown(verdict_path, check_uid, check_gid) inpipe_fd = os.pipe2(os.O_CLOEXEC) outpipe_fd = os.pipe2(os.O_CLOEXEC) # Set file descriptor mapping. check_fdmap = { 0: StdChal.null_fd, 1: StdChal.null_fd, 2: StdChal.null_fd, } test_fdmap = { 0: StdChal.null_fd, 1: StdChal.null_fd, 2: StdChal.null_fd, } if check_infile_fd is not None: check_fdmap[metadata['redir_check']['testin']] = check_infile_fd if ansfile_fd is not None: check_fdmap[metadata['redir_check']['ansin']] = ansfile_fd check_fdmap[metadata['redir_check']['pipein']] = inpipe_fd[1] check_fdmap[metadata['redir_check']['pipeout']] = outpipe_fd[0] try: del check_fdmap[-1] except KeyError: pass if test_infile_fd is not None: test_fdmap[metadata['redir_test']['testin']] = test_infile_fd test_fdmap[metadata['redir_test']['testout']] = outfile_fd test_fdmap[metadata['redir_test']['pipein']] = inpipe_fd[0] test_fdmap[metadata['redir_test']['pipeout']] = outpipe_fd[1] try: del test_fdmap[-1] except KeyError: pass check_task_id = PyExt.create_task(self.build_relpath + '/check', \ [], \ [ 'PATH=/usr/bin:/bin', 'HOME=%s'%self.build_relpath, 'LANG=en_US.UTF-8', 'OUTPUT=%s'%output_relpath, 'VERDICT=%s'%verdict_relpath, ], \ check_fdmap, \ self.build_relpath, self.container_path, \ check_uid, check_gid, 60000, 1024 * 1024 * 1024, \ PyExt.RESTRICT_LEVEL_LOW) if check_task_id is None: callback((False, (0, 0, PyExt.DETECT_INTERNALERR))) return PyExt.start_task(check_task_id, _check_done_cb, _check_started_cb) test_task_id = PyExt.create_task(exe_relpath, argv, envp, \ test_fdmap, \ test_relpath, self.container_path, \ test_uid, test_gid, timelimit, memlimit, \ PyExt.RESTRICT_LEVEL_HIGH) if test_task_id is None: callback((False, (0, 0, PyExt.DETECT_INTERNALERR))) return PyExt.start_task(test_task_id, _test_done_cb, _test_started_cb)
def main(): """ IDLE on certain IMAP folders Each IDLE command is only for one folder, so I need to spawn several IMAP sessions. Each session is in its own thread. Because the code is IO-bound instead of CPU-bound the limitations of the GIL don't concern me here. """ # Parse args parser = argparse.ArgumentParser(description="IDLE on certain IMAP folders") parser.add_argument('--version', action='version', version='%(prog)s version {}'.format(__version__)) args = parser.parse_args() logging.basicConfig( level=logging.INFO, #level=logging.DEBUG, format='%(levelname)s: %(message)s', #format='%(asctime)s %(levelname)s: %(message)s', #filename='/home/earl/.local/bin/idle_sync.log', ) # Read in account info cfg = configparser.ConfigParser() cfg.read('idle_mail.ini') # Create the consumer thread and its event it watches mail_queue = queue.Queue() trigger_thread = idle_actor(mail_queue, "trigger") trigger_thread.start() # Create a self pipe, it's used as a signal to the producer threads pipe_signal = os.pipe2(os.O_NONBLOCK) # Create the producer threads idle_threads = [] for acct in cfg.sections(): mail_user = cfg.get(acct, "user") mail_pass = cfg.get(acct, "pass") mail_server = cfg.get(acct, "server") mail_folders = cfg.get(acct, "folders") mail_timeout = cfg.get(acct, "timeout", fallback=10) mail_timeout = 60 * int(mail_timeout) # convert minutes to seconds for folder_i, folder in enumerate(mail_folders.split(",")): thread_name='{}_{}'.format(acct, folder.strip()) mail_idle = idle_checker(mail_queue, acct, mail_user, mail_pass, mail_server, folder.strip(), pipe_signal[0], thread_name, mail_timeout) idle_threads.append(mail_idle) mail_idle.start() # Watch for SIGINT and terminate gracefully try: while True: for thread in idle_threads: if thread.is_alive: # The timeout value here doesn't matter so long as it's # not infinite (ie, no arg) thread.join(60) else: print("HEY, LISTEN! {} is dead!".format(thread.name)) except (KeyboardInterrupt, SystemExit): logging.debug("Signaling stop_it to the threads") trigger_thread.stop() for t in idle_threads: t.stop() os.write(pipe_signal[1], "stop".encode())
def __enter__(self): self.r, self.w = os.pipe2(self.flags) return self.r, self.w