Commit 099d6b0fe9e6d5855403d2d0a8ae800b7bdb24a7
Committed by
Riku Voipio
1 parent
4b627a23
linux-user: implement pipe2 [v3]
implement pipe2 syscall. [v2] fix do_pipe on mips and sh4 [v3] use pipe2 to ensure atomicity, but only when it is available. Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
Showing
2 changed files
with
58 additions
and
18 deletions
configure
@@ -1304,6 +1304,24 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then | @@ -1304,6 +1304,24 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then | ||
1304 | utimens=yes | 1304 | utimens=yes |
1305 | fi | 1305 | fi |
1306 | 1306 | ||
1307 | +# check if pipe2 is there | ||
1308 | +pipe2=no | ||
1309 | +cat > $TMPC << EOF | ||
1310 | +#define _GNU_SOURCE | ||
1311 | +#include <unistd.h> | ||
1312 | +#include <fcntl.h> | ||
1313 | + | ||
1314 | +int main(void) | ||
1315 | +{ | ||
1316 | + int pipefd[2]; | ||
1317 | + pipe2(pipefd, O_CLOEXEC); | ||
1318 | + return 0; | ||
1319 | +} | ||
1320 | +EOF | ||
1321 | +if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then | ||
1322 | + pipe2=yes | ||
1323 | +fi | ||
1324 | + | ||
1307 | # Check if tools are available to build documentation. | 1325 | # Check if tools are available to build documentation. |
1308 | if test "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then | 1326 | if test "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then |
1309 | build_docs="no" | 1327 | build_docs="no" |
@@ -1704,6 +1722,9 @@ fi | @@ -1704,6 +1722,9 @@ fi | ||
1704 | if test "$utimens" = "yes" ; then | 1722 | if test "$utimens" = "yes" ; then |
1705 | echo "#define CONFIG_UTIMENSAT 1" >> $config_h | 1723 | echo "#define CONFIG_UTIMENSAT 1" >> $config_h |
1706 | fi | 1724 | fi |
1725 | +if test "$pipe2" = "yes" ; then | ||
1726 | + echo "#define CONFIG_PIPE2 1" >> $config_h | ||
1727 | +fi | ||
1707 | if test "$inotify" = "yes" ; then | 1728 | if test "$inotify" = "yes" ; then |
1708 | echo "#define CONFIG_INOTIFY 1" >> $config_h | 1729 | echo "#define CONFIG_INOTIFY 1" >> $config_h |
1709 | fi | 1730 | fi |
linux-user/syscall.c
@@ -944,6 +944,37 @@ static abi_long do_select(int n, | @@ -944,6 +944,37 @@ static abi_long do_select(int n, | ||
944 | return ret; | 944 | return ret; |
945 | } | 945 | } |
946 | 946 | ||
947 | +static abi_long do_pipe2(int host_pipe[], int flags) | ||
948 | +{ | ||
949 | +#ifdef CONFIG_PIPE2 | ||
950 | + return pipe2(host_pipe, flags); | ||
951 | +#else | ||
952 | + return -ENOSYS; | ||
953 | +#endif | ||
954 | +} | ||
955 | + | ||
956 | +static abi_long do_pipe(void *cpu_env, int pipedes, int flags) | ||
957 | +{ | ||
958 | + int host_pipe[2]; | ||
959 | + abi_long ret; | ||
960 | + ret = flags ? do_pipe2(host_pipe, flags) : pipe(host_pipe); | ||
961 | + | ||
962 | + if (is_error(ret)) | ||
963 | + return get_errno(ret); | ||
964 | +#if defined(TARGET_MIPS) | ||
965 | + ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1]; | ||
966 | + ret = host_pipe[0]; | ||
967 | +#elif defined(TARGET_SH4) | ||
968 | + ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; | ||
969 | + ret = host_pipe[0]; | ||
970 | +#else | ||
971 | + if (put_user_s32(host_pipe[0], pipedes) | ||
972 | + || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) | ||
973 | + return -TARGET_EFAULT; | ||
974 | +#endif | ||
975 | + return get_errno(ret); | ||
976 | +} | ||
977 | + | ||
947 | static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, | 978 | static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, |
948 | abi_ulong target_addr, | 979 | abi_ulong target_addr, |
949 | socklen_t len) | 980 | socklen_t len) |
@@ -4529,25 +4560,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | @@ -4529,25 +4560,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, | ||
4529 | ret = get_errno(dup(arg1)); | 4560 | ret = get_errno(dup(arg1)); |
4530 | break; | 4561 | break; |
4531 | case TARGET_NR_pipe: | 4562 | case TARGET_NR_pipe: |
4532 | - { | ||
4533 | - int host_pipe[2]; | ||
4534 | - ret = get_errno(pipe(host_pipe)); | ||
4535 | - if (!is_error(ret)) { | ||
4536 | -#if defined(TARGET_MIPS) | ||
4537 | - CPUMIPSState *env = (CPUMIPSState*)cpu_env; | ||
4538 | - env->active_tc.gpr[3] = host_pipe[1]; | ||
4539 | - ret = host_pipe[0]; | ||
4540 | -#elif defined(TARGET_SH4) | ||
4541 | - ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1]; | ||
4542 | - ret = host_pipe[0]; | ||
4543 | -#else | ||
4544 | - if (put_user_s32(host_pipe[0], arg1) | ||
4545 | - || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0]))) | ||
4546 | - goto efault; | ||
4547 | -#endif | ||
4548 | - } | ||
4549 | - } | 4563 | + ret = do_pipe(cpu_env, arg1, 0); |
4564 | + break; | ||
4565 | +#ifdef TARGET_NR_pipe2 | ||
4566 | + case TARGET_NR_pipe2: | ||
4567 | + ret = do_pipe(cpu_env, arg1, arg2); | ||
4550 | break; | 4568 | break; |
4569 | +#endif | ||
4551 | case TARGET_NR_times: | 4570 | case TARGET_NR_times: |
4552 | { | 4571 | { |
4553 | struct target_tms *tmsp; | 4572 | struct target_tms *tmsp; |