Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
Archivo: server.py Proyecto: twd2/dhop
 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
Ejemplo n.º 6
0
 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
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
	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
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
Archivo: apt.py Proyecto: lockefox/nuka
    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
Ejemplo n.º 13
0
  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])
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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' ')
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
Archivo: boon.py Proyecto: xi/boon
    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)
Ejemplo n.º 20
0
 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
Ejemplo n.º 21
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
Ejemplo n.º 22
0
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
Ejemplo n.º 23
0
    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
Ejemplo n.º 24
0
 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
Ejemplo n.º 25
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
Ejemplo n.º 26
0
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
Ejemplo n.º 27
0
    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)
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
    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
Ejemplo n.º 30
0
    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)
Ejemplo n.º 31
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))
Ejemplo n.º 32
0
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
Ejemplo n.º 33
0
    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)
Ejemplo n.º 34
0
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
Ejemplo n.º 35
0
 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
Ejemplo n.º 36
0
 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
Ejemplo n.º 37
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
Ejemplo n.º 38
0
 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)
Ejemplo n.º 39
0
 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()
Ejemplo n.º 40
0
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)
Ejemplo n.º 41
0
    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)
Ejemplo n.º 42
0
    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)
Ejemplo n.º 43
0
 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)
Ejemplo n.º 44
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)
Ejemplo n.º 45
0
    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)
Ejemplo n.º 46
0
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())
Ejemplo n.º 47
0
 def __enter__(self):
   self.r, self.w = os.pipe2(self.flags)
   return self.r, self.w