#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2020 Igalia S.L. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this program; if not, write to the # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301, USA. import os import itertools import shlex import stat import sys import tempfile import json scriptdir = os.path.abspath(os.path.dirname(__file__)) def read_lines(fd: int): new_fd = os.dup(fd) pos = os.lseek(fd, 0, os.SEEK_CUR) try: with os.fdopen(new_fd, 'r') as handle: data = handle.read() lines = data.split('\x00') for line in lines: yield line except Exception as e: print("Error reading brwap arguments", file=sys.stderr) print(e, file=sys.stderr) finally: os.lseek(fd, pos, os.SEEK_SET) def main(args: list) -> int: tmpdir = tempfile.gettempdir() source_root = os.path.normpath(os.path.abspath(os.path.join(scriptdir, '../../'))) build_root = os.path.join(source_root, 'WebKitBuild') bind_mounts = { "/app/webkit": source_root, # Access to /run/host is required by the crash log reporter. f"/run/host{tmpdir}": f"{tmpdir}", "/run/shm": "/dev/shm", } args_idx = args.index('--args') arg_fd = int(args[args_idx + 1]) lines = read_lines(arg_fd) environ = os.environ.copy() while True: try: arg = next(lines) if arg == '--setenv': key = next(lines) value = next(lines) environ[key] = value except StopIteration: break flatpak_user_dir = environ.get("WEBKIT_FLATPAK_USER_DIR") if flatpak_user_dir: bind_mounts["/var/tmp"] = os.path.join(flatpak_user_dir, "var", "tmp") try_bind_mounts = { "/run/icecc": "/var/run/icecc" } build_path = environ.get("WEBKIT_BUILD_DIR_BIND_MOUNT") if build_path: dest, src = build_path.split(":") try_bind_mounts[dest] = src coredumps_dir = environ.get("WEBKIT_CORE_DUMPS_DIRECTORY") if coredumps_dir: try_bind_mounts[coredumps_dir] = coredumps_dir xdg_runtime_dir = environ.get("XDG_RUNTIME_DIR") if xdg_runtime_dir: pw_socket = os.path.join(xdg_runtime_dir, "pipewire-0") try_bind_mounts[pw_socket] = pw_socket bwrap_args = ["bwrap", ] for dst, src in bind_mounts.items(): bwrap_args.extend(("--bind", src, dst)) for dst, src in try_bind_mounts.items(): bwrap_args.extend(("--bind-try", src, dst)) display = environ.get("WEBKIT_FLATPAK_DISPLAY") if display: bwrap_args.extend(("--setenv", "DISPLAY", display)) for env in environ.keys(): if env.startswith("LC_") or env == "LANGUAGE": bwrap_args.extend(("--unsetenv", env)) if environ.get("WEBKIT_FLATPAK_LD_PRELOAD"): os.environ["LD_PRELOAD"] = environ["WEBKIT_FLATPAK_LD_PRELOAD"] command_line = ' '.join(map(shlex.quote, itertools.chain(bwrap_args, args))) # os.system return code behaves like os.wait. A 16 bit number with the # signal in the lower byte and, if the signal is zero, the exit code in # the high byte. return os.system(command_line) >> 8 if __name__ == "__main__": sys.exit(main(sys.argv[1:]))