diff options
Diffstat (limited to 'emulators/qemu-devel/files/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1')
| -rw-r--r-- | emulators/qemu-devel/files/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1 | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/emulators/qemu-devel/files/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1 b/emulators/qemu-devel/files/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1 new file mode 100644 index 000000000000..d3c58a53e914 --- /dev/null +++ b/emulators/qemu-devel/files/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1 @@ -0,0 +1,91 @@ +From a72c668c8ab84c24372ff664d9b853c2a42d37b1 Mon Sep 17 00:00:00 2001 +From: Stacey Son <sson@FreeBSD.org> +Date: Mon, 1 Dec 2014 22:06:58 +0000 +Subject: [PATCH] Fix the pipe(2) and pipe2(2) so the file descriptors are + returned correctly. + +The pipe(2) system call returns the file descriptors in registers. The +pipe2(2) system call copies out the file descriptors. They are not the +same. +--- + bsd-user/bsd-file.h | 13 ++++++++----- + bsd-user/freebsd/os-file.h | 27 ++++++++++++++------------- + 2 files changed, 22 insertions(+), 18 deletions(-) + +diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h +index defa8bb..02698a3 100644 +--- a/bsd-user/bsd-file.h ++++ b/bsd-user/bsd-file.h +@@ -1009,7 +1009,7 @@ static abi_long do_bsd_lseek(void *cpu_env, abi_long arg1, abi_long arg2, + ret = ((res >> 32) & 0xFFFFFFFF); + set_second_rval(cpu_env, res & 0xFFFFFFFF); + #else +- ret = res & 0xFFFFFFFF; ++ ret = res & 0xFFFFFFFF; + set_second_rval(cpu_env, (res >> 32) & 0xFFFFFFFF); + #endif + } +@@ -1027,12 +1027,15 @@ static abi_long do_bsd_pipe(void *cpu_env, abi_ulong pipedes) + int host_ret = pipe(host_pipe); + + if (host_ret != -1) { ++ /* XXX pipe(2), unlike pipe2(), returns the second FD in a register. */ + set_second_rval(cpu_env, host_pipe[1]); + ret = host_pipe[0]; +- if (put_user_s32(host_pipe[0], pipedes) || +- put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { +- return -TARGET_EFAULT; +- } ++ /* XXX Not needed for pipe(): ++ if (put_user_s32(host_pipe[0], pipedes) || ++ put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { ++ return -TARGET_EFAULT; ++ } ++ */ + } else { + ret = get_errno(host_ret); + } +diff --git a/bsd-user/freebsd/os-file.h b/bsd-user/freebsd/os-file.h +index 0b3e8c5..bd94c84 100644 +--- a/bsd-user/freebsd/os-file.h ++++ b/bsd-user/freebsd/os-file.h +@@ -108,25 +108,26 @@ static abi_long do_freebsd_aio_mlock(__unused abi_ulong iocb) + /* pipe2(2) */ + static abi_long do_bsd_pipe2(void *cpu_env, abi_ulong pipedes, int flags) + { +- abi_long ret; + int host_pipe[2]; +- int host_ret = pipe2(host_pipe, flags); ++ int host_ret = pipe2(host_pipe, flags); /* XXXss - flags should be ++ translated from target to host. */ + + if (is_error(host_ret)) { +- return get_errno(host_ret); ++ return get_errno(host_ret); + } +- if (host_ret != -1) { +- set_second_rval(cpu_env, host_pipe[1]); +- ret = host_pipe[0]; ++ /* ++ * XXX pipe2() returns it's second FD by copying it back to ++ * userspace and not in a second register like pipe(2): ++ * set_second_rval(cpu_env, host_pipe[1]); ++ * ++ * Copy the FD's back to userspace: ++ */ + if (put_user_s32(host_pipe[0], pipedes) || +- put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { +- return -TARGET_EFAULT; ++ put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { ++ return -TARGET_EFAULT; + } +- } else { +- ret = get_errno(host_ret); +- } +- return ret; +-} ++ return 0; ++} + + /* chflagsat(2) */ + static inline abi_long do_bsd_chflagsat(int fd, abi_ulong path, |
