uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead

https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948
this can do it nicely.

Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
Anton Arapov 2021-04-03 12:58:10 +02:00 committed by Alan Daniels
commit 56de2bcd43
30691 changed files with 3076956 additions and 0 deletions

View file

@ -0,0 +1,79 @@
// This is a tiny wrapper that converts the extra arv[0] argument
// from binfmt-misc with the P flag enabled to QEMU parameters.
// It also prevents LD_* environment variables from being applied
// to QEMU itself.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef TARGET_QEMU
#error "Define TARGET_QEMU to be the path to the qemu-user binary (e.g., -DTARGET_QEMU=\"/full/path/to/qemu-riscv64\")"
#endif
extern char **environ;
int main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "%s: This should be run as the binfmt interpreter with the P flag\n", argv[0]);
fprintf(stderr, "%s: My preconfigured qemu-user binary: %s\n", argv[0], TARGET_QEMU);
return 1;
}
size_t environ_count = 0;
for (char **cur = environ; *cur != NULL; ++cur) {
environ_count++;
}
size_t new_argc = 3;
size_t new_argv_alloc = argc + 2 * environ_count + 2; // [ "-E", env ] for each LD_* env + [ "-0", argv0 ]
char **new_argv = (char**)malloc((new_argv_alloc + 1) * sizeof(char*));
if (!new_argv) {
fprintf(stderr, "FATAL: Failed to allocate new argv array\n");
abort();
}
new_argv[0] = TARGET_QEMU;
new_argv[1] = "-0";
new_argv[2] = argv[2];
// Pass all LD_ env variables as -E and strip them in `new_environ`
size_t new_environc = 0;
char **new_environ = (char**)malloc((environ_count + 1) * sizeof(char*));
if (!new_environ) {
fprintf(stderr, "FATAL: Failed to allocate new environ array\n");
abort();
}
for (char **cur = environ; *cur != NULL; ++cur) {
if (strncmp("LD_", *cur, 3) == 0) {
new_argv[new_argc++] = "-E";
new_argv[new_argc++] = *cur;
} else {
new_environ[new_environc++] = *cur;
}
}
new_environ[new_environc] = NULL;
size_t new_arg_start = new_argc;
new_argc += argc - 3 + 2; // [ "--", full_binary_path ]
if (argc > 3) {
memcpy(&new_argv[new_arg_start + 2], &argv[3], (argc - 3) * sizeof(char**));
}
new_argv[new_arg_start] = "--";
new_argv[new_arg_start + 1] = argv[1];
new_argv[new_argc] = NULL;
#ifdef DEBUG
for (size_t i = 0; i < new_argc; ++i) {
fprintf(stderr, "argv[%zu] = %s\n", i, new_argv[i]);
}
#endif
return execve(new_argv[0], new_argv, new_environ);
}
// vim: et:ts=4:sw=4

View file

@ -0,0 +1,31 @@
# binfmt preserve-argv[0] wrapper
#
# More details in binfmt-p-wrapper.c
#
# The wrapper has to be static so LD_* environment variables
# cannot affect the execution of the wrapper itself.
{ lib, stdenv, pkgsStatic, enableDebug ? false }:
name: emulator:
pkgsStatic.stdenv.mkDerivation {
inherit name;
src = ./binfmt-p-wrapper.c;
dontUnpack = true;
dontInstall = true;
buildPhase = ''
runHook preBuild
mkdir -p $out/bin
$CC -o $out/bin/${name} -static -std=c99 -O2 \
-DTARGET_QEMU=\"${emulator}\" \
${lib.optionalString enableDebug "-DDEBUG"} \
$src
runHook postBuild
'';
}

View file

@ -0,0 +1,268 @@
{ lib, stdenv, fetchurl, fetchpatch, python3, python3Packages, zlib, pkg-config, glib, buildPackages
, perl, pixman, vde2, alsa-lib, texinfo, flex
, bison, lzo, snappy, libaio, libtasn1, gnutls, nettle, curl, ninja, meson, sigtool
, makeWrapper, runtimeShell, removeReferencesTo
, attr, libcap, libcap_ng, socat
, CoreServices, Cocoa, Hypervisor, rez, setfile
, guestAgentSupport ? with stdenv.hostPlatform; isLinux || isSunOS || isWindows
, numaSupport ? stdenv.isLinux && !stdenv.isAarch32, numactl
, seccompSupport ? stdenv.isLinux, libseccomp
, alsaSupport ? lib.hasSuffix "linux" stdenv.hostPlatform.system && !nixosTestRunner
, pulseSupport ? !stdenv.isDarwin && !nixosTestRunner, libpulseaudio
, sdlSupport ? !stdenv.isDarwin && !nixosTestRunner, SDL2, SDL2_image
, jackSupport ? !stdenv.isDarwin && !nixosTestRunner, libjack2
, gtkSupport ? !stdenv.isDarwin && !xenSupport && !nixosTestRunner, gtk3, gettext, vte, wrapGAppsHook
, vncSupport ? !nixosTestRunner, libjpeg, libpng
, smartcardSupport ? !nixosTestRunner, libcacard
, spiceSupport ? !stdenv.isDarwin && !nixosTestRunner, spice, spice-protocol
, ncursesSupport ? !nixosTestRunner, ncurses
, usbredirSupport ? spiceSupport, usbredir
, xenSupport ? false, xen
, cephSupport ? false, ceph
, glusterfsSupport ? false, glusterfs, libuuid
, openGLSupport ? sdlSupport, mesa, libepoxy, libdrm
, virglSupport ? openGLSupport, virglrenderer
, libiscsiSupport ? true, libiscsi
, smbdSupport ? false, samba
, tpmSupport ? true
, uringSupport ? stdenv.isLinux, liburing
, hostCpuOnly ? false
, hostCpuTargets ? (if hostCpuOnly
then (lib.optional stdenv.isx86_64 "i386-softmmu"
++ ["${stdenv.hostPlatform.qemuArch}-softmmu"])
else null)
, nixosTestRunner ? false
, doCheck ? false
, qemu # for passthru.tests
}:
stdenv.mkDerivation rec {
pname = "qemu"
+ lib.optionalString xenSupport "-xen"
+ lib.optionalString hostCpuOnly "-host-cpu-only"
+ lib.optionalString nixosTestRunner "-for-vm-tests";
version = "7.0.0";
src = fetchurl {
url= "https://download.qemu.org/qemu-${version}.tar.xz";
sha256 = "sha256-9rN1x5UfcoQCeYsLqrsthkeMpT1Eztvvq74cRr9G+Dk=";
};
depsBuildBuild = [ buildPackages.stdenv.cc ];
nativeBuildInputs = [ makeWrapper removeReferencesTo pkg-config flex bison meson ninja perl python3 python3Packages.sphinx python3Packages.sphinx_rtd_theme ]
++ lib.optionals gtkSupport [ wrapGAppsHook ]
++ lib.optionals stdenv.isDarwin [ sigtool ];
buildInputs = [ zlib glib perl pixman
vde2 texinfo lzo snappy libtasn1
gnutls nettle curl
]
++ lib.optionals ncursesSupport [ ncurses ]
++ lib.optionals stdenv.isDarwin [ CoreServices Cocoa Hypervisor rez setfile ]
++ lib.optionals seccompSupport [ libseccomp ]
++ lib.optionals numaSupport [ numactl ]
++ lib.optionals alsaSupport [ alsa-lib ]
++ lib.optionals pulseSupport [ libpulseaudio ]
++ lib.optionals sdlSupport [ SDL2 SDL2_image ]
++ lib.optionals jackSupport [ libjack2 ]
++ lib.optionals gtkSupport [ gtk3 gettext vte ]
++ lib.optionals vncSupport [ libjpeg libpng ]
++ lib.optionals smartcardSupport [ libcacard ]
++ lib.optionals spiceSupport [ spice-protocol spice ]
++ lib.optionals usbredirSupport [ usbredir ]
++ lib.optionals stdenv.isLinux [ libaio libcap_ng libcap attr ]
++ lib.optionals xenSupport [ xen ]
++ lib.optionals cephSupport [ ceph ]
++ lib.optionals glusterfsSupport [ glusterfs libuuid ]
++ lib.optionals openGLSupport [ mesa libepoxy libdrm ]
++ lib.optionals virglSupport [ virglrenderer ]
++ lib.optionals libiscsiSupport [ libiscsi ]
++ lib.optionals smbdSupport [ samba ]
++ lib.optionals uringSupport [ liburing ];
dontUseMesonConfigure = true; # meson's configurePhase isn't compatible with qemu build
outputs = [ "out" ] ++ lib.optional guestAgentSupport "ga";
# On aarch64-linux we would shoot over the Hydra's 2G output limit.
separateDebugInfo = !(stdenv.isAarch64 && stdenv.isLinux);
patches = [
./fix-qemu-ga.patch
# QEMU upstream does not demand compatibility to pre-10.13, so 9p-darwin
# support on nix requires utimensat fallback. The patch adding this fallback
# set was removed during the process of upstreaming this functionality, and
# will still be needed in nix until the macOS SDK reaches 10.13+.
./provide-fallback-for-utimensat.patch
# Cocoa clipboard support only works on macOS 10.14+
./revert-ui-cocoa-add-clipboard-support.patch
# Standard about panel requires AppKit and macOS 10.13+
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/99eb313ddbbcf73c1adcdadceba1423b691c6d05.diff";
sha256 = "sha256-gTRf9XENAfbFB3asYCXnw4OV4Af6VE1W56K2xpYDhgM=";
revert = true;
})
# Workaround for upstream issue with nested virtualisation: https://gitlab.com/qemu-project/qemu/-/issues/1008
(fetchpatch {
url = "https://gitlab.com/qemu-project/qemu/-/commit/3e4546d5bd38a1e98d4bd2de48631abf0398a3a2.diff";
sha256 = "sha256-oC+bRjEHixv1QEFO9XAm4HHOwoiT+NkhknKGPydnZ5E=";
revert = true;
})
# make nixos tests that boot from USB more stable
# https://lists.nongnu.org/archive/html/qemu-devel/2022-05/msg01484.html
(fetchpatch {
url = "https://gitlab.com/raboof/qemu/-/commit/3fb5e8fe4434130b1167a995b2a01c077cca2cd5.patch";
sha256 = "sha256-evzrN3i4ntc/AFG0C0rezQpQbWcnx74nXO+5DLErX8o=";
})
]
++ lib.optional nixosTestRunner ./force-uid0-on-9p.patch;
postPatch = ''
# Otherwise tries to ensure /var/run exists.
sed -i "/install_subdir('run', install_dir: get_option('localstatedir'))/d" \
qga/meson.build
# glibc 2.33 compat fix: if `has_statx = true` is set, `tools/virtiofsd/passthrough_ll.c` will
# rely on `stx_mnt_id`[1] which is not part of glibc's `statx`-struct definition.
#
# `has_statx` will be set to `true` if a simple C program which uses a few `statx`
# consts & struct fields successfully compiles. It seems as this only builds on glibc-2.33
# since most likely[2] and because of that, the problematic code-path will be used.
#
# [1] https://github.com/torvalds/linux/commit/fa2fcf4f1df1559a0a4ee0f46915b496cc2ebf60#diff-64bab5a0a3fcb55e1a6ad77b1dfab89d2c9c71a770a07ecf44e6b82aae76a03a
# [2] https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=io/bits/statx-generic.h;h=c34697e3c1fd79cddd60db294302e461ed8db6e2;hp=7a09e94be2abb92d2df612090c132e686a24d764;hb=88a2cf6c4bab6e94a65e9c0db8813709372e9180;hpb=c4e4b2e149705559d28b16a9b47ba2f6142d6a6c
substituteInPlace meson.build \
--replace 'has_statx = cc.links(statx_test)' 'has_statx = false'
'';
preConfigure = ''
unset CPP # intereferes with dependency calculation
# this script isn't marked as executable b/c it's indirectly used by meson. Needed to patch its shebang
chmod +x ./scripts/shaderinclude.pl
patchShebangs .
# avoid conflicts with libc++ include for <version>
mv VERSION QEMU_VERSION
substituteInPlace configure \
--replace '$source_path/VERSION' '$source_path/QEMU_VERSION'
substituteInPlace meson.build \
--replace "'VERSION'" "'QEMU_VERSION'"
'';
configureFlags = [
"--disable-strip" # We'll strip ourselves after separating debug info.
"--enable-docs"
"--enable-tools"
"--localstatedir=/var"
"--sysconfdir=/etc"
# Always use our Meson, not the bundled version, which doesn't
# have our patches and will be subtly broken because of that.
"--meson=meson"
"--cross-prefix=${stdenv.cc.targetPrefix}"
"--cpu=${stdenv.hostPlatform.uname.processor}"
(lib.enableFeature guestAgentSupport "guest-agent")
] ++ lib.optional numaSupport "--enable-numa"
++ lib.optional seccompSupport "--enable-seccomp"
++ lib.optional smartcardSupport "--enable-smartcard"
++ lib.optional spiceSupport "--enable-spice"
++ lib.optional usbredirSupport "--enable-usb-redir"
++ lib.optional (hostCpuTargets != null) "--target-list=${lib.concatStringsSep "," hostCpuTargets}"
++ lib.optional stdenv.isDarwin "--enable-cocoa"
++ lib.optional stdenv.isDarwin "--enable-hvf"
++ lib.optional stdenv.isLinux "--enable-linux-aio"
++ lib.optional gtkSupport "--enable-gtk"
++ lib.optional xenSupport "--enable-xen"
++ lib.optional cephSupport "--enable-rbd"
++ lib.optional glusterfsSupport "--enable-glusterfs"
++ lib.optional openGLSupport "--enable-opengl"
++ lib.optional virglSupport "--enable-virglrenderer"
++ lib.optional tpmSupport "--enable-tpm"
++ lib.optional libiscsiSupport "--enable-libiscsi"
++ lib.optional smbdSupport "--smbd=${samba}/bin/smbd"
++ lib.optional uringSupport "--enable-linux-io-uring";
dontWrapGApps = true;
# QEMU attaches entitlements with codesign and strip removes those,
# voiding the entitlements and making it non-operational.
# The alternative is to re-sign with entitlements after stripping:
# * https://github.com/qemu/qemu/blob/v6.1.0/scripts/entitlement.sh#L25
dontStrip = stdenv.isDarwin;
postFixup = ''
# the .desktop is both invalid and pointless
rm -f $out/share/applications/qemu.desktop
'' + lib.optionalString guestAgentSupport ''
# move qemu-ga (guest agent) to separate output
mkdir -p $ga/bin
mv $out/bin/qemu-ga $ga/bin/
ln -s $ga/bin/qemu-ga $out/bin
remove-references-to -t $out $ga/bin/qemu-ga
'' + lib.optionalString gtkSupport ''
# wrap GTK Binaries
for f in $out/bin/qemu-system-*; do
wrapGApp $f
done
'';
preBuild = "cd build";
# tests can still timeout on slower systems
inherit doCheck;
checkInputs = [ socat ];
preCheck = ''
# time limits are a little meagre for a build machine that's
# potentially under load.
substituteInPlace ../tests/unit/meson.build \
--replace 'timeout: slow_tests' 'timeout: 50 * slow_tests'
substituteInPlace ../tests/qtest/meson.build \
--replace 'timeout: slow_qtests' 'timeout: 50 * slow_qtests'
substituteInPlace ../tests/fp/meson.build \
--replace 'timeout: 90)' 'timeout: 300)'
# point tests towards correct binaries
substituteInPlace ../tests/unit/test-qga.c \
--replace '/bin/echo' "$(type -P echo)"
substituteInPlace ../tests/unit/test-io-channel-command.c \
--replace '/bin/socat' "$(type -P socat)"
# combined with a long package name, some temp socket paths
# can end up exceeding max socket name len
substituteInPlace ../tests/qtest/bios-tables-test.c \
--replace 'qemu-test_acpi_%s_tcg_%s' '%s_%s'
# get-fsinfo attempts to access block devices, disallowed by sandbox
sed -i -e '/\/qga\/get-fsinfo/d' -e '/\/qga\/blacklist/d' \
../tests/unit/test-qga.c
'' + lib.optionalString stdenv.isDarwin ''
# skip test that stalls on darwin, perhaps due to subtle differences
# in fifo behaviour
substituteInPlace ../tests/unit/meson.build \
--replace "'test-io-channel-command'" "#'test-io-channel-command'"
'';
# Add a qemu-kvm wrapper for compatibility/convenience.
postInstall = ''
ln -s $out/libexec/virtiofsd $out/bin
ln -s $out/bin/qemu-system-${stdenv.hostPlatform.qemuArch} $out/bin/qemu-kvm
'';
passthru = {
qemu-system-i386 = "bin/qemu-system-i386";
tests = {
qemu-tests = qemu.override { doCheck = true; };
};
};
# Builds in ~3h with 2 cores, and ~20m with a big-parallel builder.
requiredSystemFeatures = [ "big-parallel" ];
meta = with lib; {
homepage = "http://www.qemu.org/";
description = "A generic and open source machine emulator and virtualizer";
license = licenses.gpl2Plus;
mainProgram = "qemu-kvm";
maintainers = with maintainers; [ eelco qyliss ];
platforms = platforms.unix;
priority = 10; # Prefer virtiofsd from the virtiofsd package.
};
}

View file

@ -0,0 +1,36 @@
diff -Naur a/qga/commands-posix.c b/qga/commands-posix.c
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -109,6 +109,8 @@
reopen_fd_to_null(1);
reopen_fd_to_null(2);
+ execle("/run/current-system/sw/bin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
+ "hypervisor initiated shutdown", (char*)NULL, environ);
execle("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0",
"hypervisor initiated shutdown", (char*)NULL, environ);
_exit(EXIT_FAILURE);
@@ -157,11 +159,13 @@
pid_t pid;
Error *local_err = NULL;
struct timeval tv;
+ static const char hwclock_path_nix[] = "/run/current-system/sw/bin/hwclock";
static const char hwclock_path[] = "/sbin/hwclock";
static int hwclock_available = -1;
if (hwclock_available < 0) {
- hwclock_available = (access(hwclock_path, X_OK) == 0);
+ hwclock_available = (access(hwclock_path_nix, X_OK) == 0) ||
+ (access(hwclock_path, X_OK) == 0);
}
if (!hwclock_available) {
@@ -207,6 +211,8 @@
/* Use '/sbin/hwclock -w' to set RTC from the system time,
* or '/sbin/hwclock -s' to set the system time from RTC. */
+ execle(hwclock_path_nix, "hwclock", has_time ? "-w" : "-s",
+ NULL, environ);
execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",
NULL, environ);
_exit(EXIT_FAILURE);

View file

@ -0,0 +1,81 @@
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 45e9a1f9b0..494ee00c66 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -84,6 +84,23 @@ static void unlinkat_preserve_errno(int dirfd, const char *path, int flags)
#define VIRTFS_META_DIR ".virtfs_metadata"
+static int is_in_store_path(const char *path)
+{
+ static char *store_path = NULL;
+ int store_path_len = -1;
+
+ if (store_path_len == -1) {
+ if ((store_path = getenv("NIX_STORE")) != NULL)
+ store_path_len = strlen(store_path);
+ else
+ store_path_len = 0;
+ }
+
+ if (store_path_len > 0)
+ return strncmp(path, store_path, strlen(store_path)) == 0;
+ return 0;
+}
+
static FILE *local_fopenat(int dirfd, const char *name, const char *mode)
{
int fd, o_mode = 0;
@@ -161,6 +178,8 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
if (err) {
goto err_out;
}
+ stbuf->st_uid = 0;
+ stbuf->st_gid = 0;
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
/* Actual credentials are part of extended attrs */
uid_t tmp_uid;
@@ -280,6 +299,9 @@ static int fchmodat_nofollow(int dirfd, const char *name, mode_t mode)
{
int fd, ret;
+ if (is_in_store_path(name))
+ return 0;
+
/* FIXME: this should be handled with fchmodat(AT_SYMLINK_NOFOLLOW).
* Unfortunately, the linux kernel doesn't implement it yet. As an
* alternative, let's open the file and use fchmod() instead. This
@@ -661,6 +683,8 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
if (err) {
return err;
}
+ stbuf->st_uid = 0;
+ stbuf->st_gid = 0;
if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
/* Actual credentials are part of extended attrs */
uid_t tmp_uid;
@@ -795,8 +819,11 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
if (err) {
goto out;
}
- err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
- AT_SYMLINK_NOFOLLOW);
+ if (is_in_store_path(name))
+ err = 0;
+ else
+ err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
+ AT_SYMLINK_NOFOLLOW);
if (err == -1) {
/*
* If we fail to change ownership and if we are
@@ -911,7 +938,9 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
goto out;
}
- if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
+ if (is_in_store_path(name)) {
+ ret = 0;
+ } else if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
(fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
(fs_ctx->export_flags & V9FS_SM_NONE)) {
ret = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,

View file

@ -0,0 +1,190 @@
From 747a741772cde6bb340eb8bdb493390280de8d16 Mon Sep 17 00:00:00 2001
From: Keno Fischer <keno@juliacomputing.com>
Date: Sat, 16 Jun 2018 20:56:54 -0400
Subject: [PATCH] 9p: darwin: Provide fallback impl for utimensat
This function is new in Mac OS 10.13. Provide a fallback implementation
when building against older SDKs. The complication in the definition comes
having to separately handle the used SDK version and the target OS version.
- If the SDK version is too low (__MAC_10_13 not defined), utimensat is not
defined in the header, so we must not try to use it (doing so would error).
- Otherwise, if the targetted OS version is at least 10.13, we know this
function is available, so we can unconditionally call it.
- Lastly, we check for the availability of the __builtin_available macro to
potentially insert a dynamic check for this OS version. However, __builtin_available
is only available with sufficiently recent versions of clang and while all
Apple clang versions that ship with Xcode versions that support the 10.13
SDK support with builtin, we want to allow building with compilers other
than Apple clang that may not support this builtin.
Signed-off-by: Keno Fischer <keno@juliacomputing.com>
Signed-off-by: Michael Roitzsch <reactorcontrol@icloud.com>
Signed-off-by: Will Cohen <wwcohen@gmail.com>
---
hw/9pfs/9p-local.c | 2 +-
hw/9pfs/9p-util-darwin.c | 96 ++++++++++++++++++++++++++++++++++++++++
hw/9pfs/9p-util-linux.c | 6 +++
hw/9pfs/9p-util.h | 8 ++++
4 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index d42ce6d8b8..b2c1fa42e1 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1085,7 +1085,7 @@ static int local_utimensat(FsContext *s, V9fsPath *fs_path,
goto out;
}
- ret = utimensat(dirfd, name, buf, AT_SYMLINK_NOFOLLOW);
+ ret = utimensat_nofollow(dirfd, name, buf);
close_preserve_errno(dirfd);
out:
g_free(dirpath);
diff --git a/hw/9pfs/9p-util-darwin.c b/hw/9pfs/9p-util-darwin.c
index bec0253474..2fc0475292 100644
--- a/hw/9pfs/9p-util-darwin.c
+++ b/hw/9pfs/9p-util-darwin.c
@@ -95,3 +95,99 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
}
#endif
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+static int update_times_from_stat(int fd, struct timespec times[2],
+ int update0, int update1)
+{
+ struct stat buf;
+ int ret = fstat(fd, &buf);
+ if (ret == -1) {
+ return ret;
+ }
+ if (update0) {
+ times[0] = buf.st_atimespec;
+ }
+ if (update1) {
+ times[1] = buf.st_mtimespec;
+ }
+ return 0;
+}
+
+int utimensat_nofollow(int dirfd, const char *filename,
+ const struct timespec times_in[2])
+{
+ int ret, fd;
+ int special0, special1;
+ struct timeval futimes_buf[2];
+ struct timespec times[2];
+ memcpy(times, times_in, 2 * sizeof(struct timespec));
+
+/* Check whether we have an SDK version that defines utimensat */
+#if defined(__MAC_10_13)
+# if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_13
+# define UTIMENSAT_AVAILABLE 1
+# elif __has_builtin(__builtin_available)
+# define UTIMENSAT_AVAILABLE __builtin_available(macos 10.13, *)
+# else
+# define UTIMENSAT_AVAILABLE 0
+# endif
+ if (UTIMENSAT_AVAILABLE) {
+ return utimensat(dirfd, filename, times, AT_SYMLINK_NOFOLLOW);
+ }
+#endif
+
+ /* utimensat not available. Use futimes. */
+ fd = openat_file(dirfd, filename, O_PATH_9P_UTIL | O_NOFOLLOW, 0);
+ if (fd == -1) {
+ return -1;
+ }
+
+ special0 = times[0].tv_nsec == UTIME_OMIT;
+ special1 = times[1].tv_nsec == UTIME_OMIT;
+ if (special0 || special1) {
+ /* If both are set, nothing to do */
+ if (special0 && special1) {
+ ret = 0;
+ goto done;
+ }
+
+ ret = update_times_from_stat(fd, times, special0, special1);
+ if (ret < 0) {
+ goto done;
+ }
+ }
+
+ special0 = times[0].tv_nsec == UTIME_NOW;
+ special1 = times[1].tv_nsec == UTIME_NOW;
+ if (special0 || special1) {
+ ret = futimes(fd, NULL);
+ if (ret < 0) {
+ goto done;
+ }
+
+ /* If both are set, we are done */
+ if (special0 && special1) {
+ ret = 0;
+ goto done;
+ }
+
+ ret = update_times_from_stat(fd, times, special0, special1);
+ if (ret < 0) {
+ goto done;
+ }
+ }
+
+ futimes_buf[0].tv_sec = times[0].tv_sec;
+ futimes_buf[0].tv_usec = times[0].tv_nsec / 1000;
+ futimes_buf[1].tv_sec = times[1].tv_sec;
+ futimes_buf[1].tv_usec = times[1].tv_nsec / 1000;
+ ret = futimes(fd, futimes_buf);
+
+done:
+ close_preserve_errno(fd);
+ return ret;
+}
diff --git a/hw/9pfs/9p-util-linux.c b/hw/9pfs/9p-util-linux.c
index db451b0784..320697f347 100644
--- a/hw/9pfs/9p-util-linux.c
+++ b/hw/9pfs/9p-util-linux.c
@@ -68,3 +68,9 @@ int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
{
return mknodat(dirfd, filename, mode, dev);
}
+
+int utimensat_nofollow(int dirfd, const char *filename,
+ const struct timespec times[2])
+{
+ return utimensat(dirfd, filename, times, AT_SYMLINK_NOFOLLOW);
+}
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
index 97e681e167..fd50d6243a 100644
--- a/hw/9pfs/9p-util.h
+++ b/hw/9pfs/9p-util.h
@@ -36,6 +36,12 @@ static inline int qemu_lsetxattr(const char *path, const char *name,
#define qemu_lsetxattr lsetxattr
#endif
+/* Compatibility with old SDK Versions for Darwin */
+#if defined(CONFIG_DARWIN) && !defined(UTIME_NOW)
+#define UTIME_NOW -1
+#define UTIME_OMIT -2
+#endif
+
static inline void close_preserve_errno(int fd)
{
int serrno = errno;
@@ -98,6 +104,8 @@ ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
char *list, size_t size);
ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
const char *name);
+int utimensat_nofollow(int dirfd, const char *filename,
+ const struct timespec times[2]);
/*
* Darwin has d_seekoff, which appears to function similarly to d_off.
--
2.35.1

View file

@ -0,0 +1,208 @@
From 19b0952b36b6b5c4bd2665cc0bd4e55a85f81b55 Mon Sep 17 00:00:00 2001
From: Will Cohen <willcohen@users.noreply.github.com>
Date: Tue, 29 Mar 2022 14:00:56 -0400
Subject: [PATCH] Revert "ui/cocoa: Add clipboard support"
This reverts commit 7e3e20d89129614f4a7b2451fe321cc6ccca3b76.
---
include/ui/clipboard.h | 2 +-
ui/clipboard.c | 2 +-
ui/cocoa.m | 121 -----------------------------------------
3 files changed, 2 insertions(+), 123 deletions(-)
diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h
index ce76aa451f..c4e1dc4ff4 100644
--- a/include/ui/clipboard.h
+++ b/include/ui/clipboard.h
@@ -269,7 +269,7 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
QemuClipboardInfo *info,
QemuClipboardType type,
uint32_t size,
- const void *data,
+ void *data,
bool update);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuClipboardInfo, qemu_clipboard_info_unref)
diff --git a/ui/clipboard.c b/ui/clipboard.c
index 9079ef829b..6b9ed59e1b 100644
--- a/ui/clipboard.c
+++ b/ui/clipboard.c
@@ -140,7 +140,7 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
QemuClipboardInfo *info,
QemuClipboardType type,
uint32_t size,
- const void *data,
+ void *data,
bool update)
{
if (!info ||
diff --git a/ui/cocoa.m b/ui/cocoa.m
index c4e5468f9e..cd3bdf0cec 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -28,7 +28,6 @@
#include <crt_externs.h>
#include "qemu-common.h"
-#include "ui/clipboard.h"
#include "ui/console.h"
#include "ui/input.h"
#include "ui/kbd-state.h"
@@ -107,10 +106,6 @@ static void cocoa_switch(DisplayChangeListener *dcl,
static QemuSemaphore app_started_sem;
static bool allow_events;
-static NSInteger cbchangecount = -1;
-static QemuClipboardInfo *cbinfo;
-static QemuEvent cbevent;
-
// Utility functions to run specified code block with iothread lock held
typedef void (^CodeBlock)(void);
typedef bool (^BoolCodeBlock)(void);
@@ -1805,105 +1800,6 @@ static void addRemovableDevicesMenuItems(void)
qapi_free_BlockInfoList(pointerToFree);
}
-@interface QemuCocoaPasteboardTypeOwner : NSObject<NSPasteboardTypeOwner>
-@end
-
-@implementation QemuCocoaPasteboardTypeOwner
-
-- (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSPasteboardType)type
-{
- if (type != NSPasteboardTypeString) {
- return;
- }
-
- with_iothread_lock(^{
- QemuClipboardInfo *info = qemu_clipboard_info_ref(cbinfo);
- qemu_event_reset(&cbevent);
- qemu_clipboard_request(info, QEMU_CLIPBOARD_TYPE_TEXT);
-
- while (info == cbinfo &&
- info->types[QEMU_CLIPBOARD_TYPE_TEXT].available &&
- info->types[QEMU_CLIPBOARD_TYPE_TEXT].data == NULL) {
- qemu_mutex_unlock_iothread();
- qemu_event_wait(&cbevent);
- qemu_mutex_lock_iothread();
- }
-
- if (info == cbinfo) {
- NSData *data = [[NSData alloc] initWithBytes:info->types[QEMU_CLIPBOARD_TYPE_TEXT].data
- length:info->types[QEMU_CLIPBOARD_TYPE_TEXT].size];
- [sender setData:data forType:NSPasteboardTypeString];
- [data release];
- }
-
- qemu_clipboard_info_unref(info);
- });
-}
-
-@end
-
-static QemuCocoaPasteboardTypeOwner *cbowner;
-
-static void cocoa_clipboard_notify(Notifier *notifier, void *data);
-static void cocoa_clipboard_request(QemuClipboardInfo *info,
- QemuClipboardType type);
-
-static QemuClipboardPeer cbpeer = {
- .name = "cocoa",
- .notifier = { .notify = cocoa_clipboard_notify },
- .request = cocoa_clipboard_request
-};
-
-static void cocoa_clipboard_update_info(QemuClipboardInfo *info)
-{
- if (info->owner == &cbpeer || info->selection != QEMU_CLIPBOARD_SELECTION_CLIPBOARD) {
- return;
- }
-
- if (info != cbinfo) {
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- qemu_clipboard_info_unref(cbinfo);
- cbinfo = qemu_clipboard_info_ref(info);
- cbchangecount = [[NSPasteboard generalPasteboard] declareTypes:@[NSPasteboardTypeString] owner:cbowner];
- [pool release];
- }
-
- qemu_event_set(&cbevent);
-}
-
-static void cocoa_clipboard_notify(Notifier *notifier, void *data)
-{
- QemuClipboardNotify *notify = data;
-
- switch (notify->type) {
- case QEMU_CLIPBOARD_UPDATE_INFO:
- cocoa_clipboard_update_info(notify->info);
- return;
- case QEMU_CLIPBOARD_RESET_SERIAL:
- /* ignore */
- return;
- }
-}
-
-static void cocoa_clipboard_request(QemuClipboardInfo *info,
- QemuClipboardType type)
-{
- NSData *text;
-
- switch (type) {
- case QEMU_CLIPBOARD_TYPE_TEXT:
- text = [[NSPasteboard generalPasteboard] dataForType:NSPasteboardTypeString];
- if (text) {
- qemu_clipboard_set_data(&cbpeer, info, type,
- [text length], [text bytes], true);
- [text release];
- }
- break;
- default:
- break;
- }
-}
-
/*
* The startup process for the OSX/Cocoa UI is complicated, because
* OSX insists that the UI runs on the initial main thread, and so we
@@ -1938,7 +1834,6 @@ static void cocoa_clipboard_request(QemuClipboardInfo *info,
COCOA_DEBUG("Second thread: calling qemu_main()\n");
status = qemu_main(gArgc, gArgv, *_NSGetEnviron());
COCOA_DEBUG("Second thread: qemu_main() returned, exiting\n");
- [cbowner release];
exit(status);
}
@@ -2054,18 +1949,6 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
[cocoaView setAbsoluteEnabled:YES];
});
}
-
- if (cbchangecount != [[NSPasteboard generalPasteboard] changeCount]) {
- qemu_clipboard_info_unref(cbinfo);
- cbinfo = qemu_clipboard_info_new(&cbpeer, QEMU_CLIPBOARD_SELECTION_CLIPBOARD);
- if ([[NSPasteboard generalPasteboard] availableTypeFromArray:@[NSPasteboardTypeString]]) {
- cbinfo->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
- }
- qemu_clipboard_update(cbinfo);
- cbchangecount = [[NSPasteboard generalPasteboard] changeCount];
- qemu_event_set(&cbevent);
- }
-
[pool release];
}
@@ -2105,10 +1988,6 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
// register vga output callbacks
register_displaychangelistener(&dcl);
-
- qemu_event_init(&cbevent, false);
- cbowner = [[QemuCocoaPasteboardTypeOwner alloc] init];
- qemu_clipboard_peer_register(&cbpeer);
}
static QemuDisplay qemu_display_cocoa = {
--
2.35.1

View file

@ -0,0 +1,22 @@
{ stdenv, installShellFiles, qemu }:
stdenv.mkDerivation rec {
pname = "qemu-utils";
inherit (qemu) version;
nativeBuildInputs = [ installShellFiles ];
buildInputs = [ qemu ];
unpackPhase = "true";
installPhase = ''
mkdir -p "$out/bin"
cp "${qemu}/bin/qemu-img" "$out/bin/qemu-img"
cp "${qemu}/bin/qemu-io" "$out/bin/qemu-io"
cp "${qemu}/bin/qemu-nbd" "$out/bin/qemu-nbd"
installManPage ${qemu}/share/man/man1/qemu-img.1.gz
installManPage ${qemu}/share/man/man8/qemu-nbd.8.gz
'';
inherit (qemu) meta;
}