| #!/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 |
| |
| bwrap_args = ["bwrap", ] |
| |
| xdg_runtime_dir = environ.get("XDG_RUNTIME_DIR") |
| if xdg_runtime_dir: |
| pipewire_runtime_dir = "/host/xdg-runtime" |
| bwrap_args.extend(("--ro-bind-try", xdg_runtime_dir, pipewire_runtime_dir, |
| "--setenv", "PIPEWIRE_RUNTIME_DIR", pipewire_runtime_dir)) |
| |
| 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:])) |