blob: ed608ae691bc520d91bbebfb56800f8c0b16ab33 [file] [log] [blame]
#!/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
# 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)
with os.fdopen(new_fd, 'r') as handle:
data =
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)
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:
arg = next(lines)
if arg == '--setenv':
key = next(lines)
value = next(lines)
environ[key] = value
except StopIteration:
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__":