Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 98 lines (76 sloc) 2.69 KB
#!/usr/bin/python3.3 -S
import argparse
import os
import shutil
import sys
import urllib.parse
def path_resolve(cmd):
cmd0 = cmd
if '/' not in cmd:
cmd = shutil.which(cmd)
assert cmd, cmd0
cmd = os.path.abspath(cmd)
assert os.path.exists(cmd), cmd0
return cmd
script = path_resolve(sys.argv[0])
assert script.endswith('/enter-uml')
runner = os.path.dirname(script) + '/uml-stub'
assert os.path.exists(runner)
def kopt_safe(st):
# The kernel cmdline doesn't support any kind of quoting
# XXX Check tabs and newlines as well?
return ' ' not in st
assert kopt_safe(runner)
quote = urllib.parse.quote
parser = argparse.ArgumentParser()
# HOME and TERM seem to be set by the kernel (as well as root and the kernel
# cmdline), the rest would be set by a shell
preserve_default = 'HOME TERM PWD PATH SHELL'.split()
parser.add_argument(
'--preserve-envvars', dest='preserve_envvars', nargs='*', default=[], metavar='ENVVAR')
parser.add_argument('--rw-dirs', dest='rw_dirs', nargs='*', metavar='DIR')
parser.add_argument('--clear-dirs', dest='clear_dirs', nargs='*', metavar='DIR')
parser.add_argument('--kopts', dest='kopts', nargs='*', metavar='KOPT')
parser.add_argument('--kernel', default='/usr/bin/linux.uml', metavar='EXECUTABLE')
parser.add_argument('--mem', default='128M')
parser.add_argument('--gdb', action='store_true')
parser.add_argument('cmd', nargs='*')
args = parser.parse_args()
# Require that all vars in preserve_default be defined
preserve_envvars = preserve_default + [
var for var in args.preserve_envvars if var in os.environ]
cmd = args.cmd or [os.environ['SHELL']]
cmd[0] = path_resolve(cmd[0])
kcmd = (
[args.kernel]
+ 'rootfstype=hostfs rw quiet'.split()
+ [
'mem=' + args.mem,
'init=' + runner,
'UML_ENV=' + ';'.join(
quote(var) + '=' + quote(os.environ[var])
for var in preserve_envvars),
'UML_CMD=' + '+'.join(map(quote, cmd))])
if args.rw_dirs is not None:
for dn in args.rw_dirs:
assert os.path.exists(dn), dn
kcmd.append('UML_RWDIRS=' + ':'.join(
quote(dn) for dn in args.rw_dirs))
if args.clear_dirs is not None:
for dn in args.clear_dirs:
assert os.path.exists(dn), dn
kcmd.append('UML_CLEARDIRS=' + ':'.join(
quote(dn) for dn in args.clear_dirs))
if args.kopts is not None:
assert all('=' in kopt for kopt in args.kopts), args.kopts
assert all(map(kopt_safe, args.kopts))
kcmd.extend(args.kopts)
gdb_cmd = [
'gdb',
'-ex', 'handle SIGSEGV pass nostop noprint',
'-ex', 'handle SIGUSR1 pass nopass stop print',
'--args']
if args.gdb:
os.execvp('gdb', gdb_cmd + kcmd)
else:
os.execvp(args.kernel, kcmd)