2

通常の (サンドボックス化されていない) cPython または PyPy スクリプト内から、サンドボックス化された PyPy インタープリターと対話する方法を作成しようとしています。

これらの指示に従って、サンドボックス化された PyPy インタープリターをコンパイルすることができましたhttp://doc.pypy.org/en/latest/sandbox.htmlと、pypy_interact.py と連携して作成する pypy-c-sandbox ファイルがありますインタラクティブなサンドボックス インタープリター。

今、私は非常に似たようなことをしたいのですが、stdin/stdout を io として使用するのではなく、python スクリプトを使用して pypy-sandbox プロセスとやり取りしたいと考えています。私はこれで大部分が機能するようになりました。cStringIO オブジェクトを入力、出力、エラーとして .communicate() 関数を使用して、通常の Python からこのデータにアクセスできます。

ただし、これは私の問題です。同じインスタンス化された PyPy サンドボックス オブジェクトで .communicate() をもう一度呼び出すと、何も返されません。最初の .communicate だけが機能します。なぜこれが当てはまるのか、どうすれば回避できるのか、私はかなり混乱しています。

私の問題を示すために、醜いハックをまとめました:

import sys, os
import autopath
from pypy.translator.sandbox.sandlib import SimpleIOSandboxedProc
from pypy.translator.sandbox.sandlib import VirtualizedSandboxedProc
from pypy.translator.sandbox.vfs import Dir, RealDir, RealFile
import pypy


LIB_ROOT = os.path.dirname(os.path.dirname(pypy.__file__))

class PyPySandboxedProc(VirtualizedSandboxedProc, SimpleIOSandboxedProc):
    argv0 = '/bin/pypy-c'
    virtual_cwd = '/tmp'
    virtual_env = {}
    virtual_console_isatty = True
    arguments = ['../goal/pypy-c', '-u']

    def __init__(self, executable, arguments, tmpdir=None, debug=True):
        self.executable = executable = os.path.abspath(executable)
        self.tmpdir = tmpdir
        self.debug = debug
        super(PyPySandboxedProc, self).__init__([self.argv0] + arguments,
                                                executable=executable)

    def build_virtual_root(self):
        # build a virtual file system:
        # * can access its own executable
        # * can access the pure Python libraries
        # * can access the temporary usession directory as /tmp
        exclude = ['.pyc', '.pyo']
        if self.tmpdir is None:
            tmpdirnode = Dir({})
        else:
            tmpdirnode = RealDir(self.tmpdir, exclude=exclude)
        libroot = str(LIB_ROOT)

        return Dir({
            'bin': Dir({
                'pypy-c': RealFile(self.executable),
                'lib-python': RealDir(os.path.join(libroot, 'lib-python'),
                                      exclude=exclude),
                'lib_pypy': RealDir(os.path.join(libroot, 'lib_pypy'),
                                      exclude=exclude),
                }),
             'tmp': tmpdirnode,
             })

# run test
arguments = ['../goal/pypy-c', '-u']

sandproc = PyPySandboxedProc(arguments[0], arguments[1:],
                             tmpdir=None, debug=True)

#start the proc
code1 = "print 'started'\na = 5\nprint a"
code2 = "b = a\nprint b\nprint 'code 2 was run'"

output, error = sandproc.communicate(code1)
print "output: %s\n error: %s\n" % (output, error)

output, error = sandproc.communicate(code2)
print "output: %s\n error: %s\n" % (output, error)

code2同じ Sandproc インスタンスで実行できるが、その入力/出力が別々に返されるようにする方法が本当に欲しいです。すべてのコードを連結して一度に実行すると機能しますが、特定の入力の出力を解析するのは少し面倒です。

4

1 に答える 1