Commit 099d6b0fe9e6d5855403d2d0a8ae800b7bdb24a7

Authored by Riku Voipio
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>
configure
@@ -1304,6 +1304,24 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2&gt; /dev/null ; then @@ -1304,6 +1304,24 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2&gt; /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;