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 | 1304 | utimens=yes |
1305 | 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 | 1325 | # Check if tools are available to build documentation. |
1308 | 1326 | if test "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then |
1309 | 1327 | build_docs="no" |
... | ... | @@ -1704,6 +1722,9 @@ fi |
1704 | 1722 | if test "$utimens" = "yes" ; then |
1705 | 1723 | echo "#define CONFIG_UTIMENSAT 1" >> $config_h |
1706 | 1724 | fi |
1725 | +if test "$pipe2" = "yes" ; then | |
1726 | + echo "#define CONFIG_PIPE2 1" >> $config_h | |
1727 | +fi | |
1707 | 1728 | if test "$inotify" = "yes" ; then |
1708 | 1729 | echo "#define CONFIG_INOTIFY 1" >> $config_h |
1709 | 1730 | fi | ... | ... |
linux-user/syscall.c
... | ... | @@ -944,6 +944,37 @@ static abi_long do_select(int n, |
944 | 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 | 978 | static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, |
948 | 979 | abi_ulong target_addr, |
949 | 980 | socklen_t len) |
... | ... | @@ -4529,25 +4560,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
4529 | 4560 | ret = get_errno(dup(arg1)); |
4530 | 4561 | break; |
4531 | 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 | 4568 | break; |
4569 | +#endif | |
4551 | 4570 | case TARGET_NR_times: |
4552 | 4571 | { |
4553 | 4572 | struct target_tms *tmsp; | ... | ... |