Skip to content

Instantly share code, notes, and snippets.

@dutc
Last active April 3, 2020 01:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dutc/2866d969d5e9209d501a to your computer and use it in GitHub Desktop.
Save dutc/2866d969d5e9209d501a to your computer and use it in GitHub Desktop.
py₃.so₂ example
#!/usr/bin/env python3
from cffi import FFI
from textwrap import dedent
from os import getpid
from sys import version_info
if __name__ == '__main__':
from sys import argv
print('Host is: %s (%s)' % (version_info, getpid()))
print("Running in host:")
exec(argv[1], locals(), globals())
ffi1, ffi2, ffi3 = FFI(), FFI(), FFI()
# Python 1.5.0
#DL_IMPORT(void) Py_Initialize Py_PROTO((void));
#DL_IMPORT(int) PyRun_SimpleString Py_PROTO((char *));
#DL_IMPORT(void) Py_Finalize Py_PROTO((void));
#int Py_NoSiteFlag;
ffi1.cdef('''
void Py_Initialize(void);
int PyRun_SimpleString(const char *);
void Py_Finalize(void);
int Py_NoSiteFlag;''')
# Python 2.7.4
#PyAPI_FUNC(void) Py_Initialize(void);
#PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *);
#PyAPI_FUNC(void) Py_Finalize(void);
#int Py_NoSiteFlag;
ffi2.cdef('''
void Py_Initialize(void);
int PyRun_SimpleStringFlags(const char *, void *);
void Py_Finalize(void);
int Py_NoSiteFlag;''')
# Python 3.4.1
#PyAPI_FUNC(void) Py_Initialize(void);
#PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *);
#PyAPI_FUNC(void) Py_Finalize(void);
#int Py_NoSiteFlag;
ffi3.cdef('''
void Py_Initialize(void);
int PyRun_SimpleStringFlags(const char *, void *);
void Py_Finalize(void);
int Py_NoSiteFlag;''')
flags1 = ffi1.RTLD_DEEPBIND | ffi1.RTLD_LOCAL | ffi1.RTLD_LAZY
flags2 = ffi2.RTLD_DEEPBIND | ffi2.RTLD_LOCAL | ffi2.RTLD_LAZY
flags3 = ffi3.RTLD_DEEPBIND | ffi3.RTLD_LOCAL | ffi3.RTLD_LAZY
pythons = {
(1,5,0): (ffi1.dlopen("./libpython1.5.so", flags1),
lambda s, py: py.PyRun_SimpleString(s)),
(2,7,4): (ffi2.dlopen("./libpython2.7.so", flags2),
lambda s, py: py.PyRun_SimpleStringFlags(s, ffi2.NULL)),
(3,4,1): (ffi3.dlopen("./libpython3.4dm.so", flags3),
lambda s, py: py.PyRun_SimpleStringFlags(s, ffi3.NULL)),
}
# don't run site nonsense
for py, _ in pythons.values():
py.Py_NoSiteFlag = 1
# start each interpreter
for py, _ in pythons.values():
py.Py_Initialize()
# check version & run code
for py, run in pythons.values():
run(str.encode(dedent('''
try:
from sys import version_info
ver = version_info
except ImportError:
from sys import version # Python 1.5
ver = version
from os import getpid
print('Slave is: %s (%s)' % (ver, getpid()))
''')), py)
run(b'print("Running in slave:")', py)
run(str.encode(argv[1]), py)
# shut it down
for py, run in pythons.values():
py.Py_Finalize()
@dutc
Copy link
Author

dutc commented Oct 16, 2014

Try running with:

    python py3so2.py 'from random import choice; choice([True,True,False]) and execfile("py3so2.py")'
    python3 py3so2.py 'from random import choice; choice([True,True,False]) and execfile("py3so2.py")'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment