qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] linux-user: implement pipe2 syscall [v2]


From: Riku Voipio
Subject: [Qemu-devel] [PATCH] linux-user: implement pipe2 syscall [v2]
Date: Tue, 5 May 2009 23:43:03 +0300
User-agent: Mutt/1.5.18 (2008-05-17)

On Tue, May 05, 2009 at 04:30:48PM +0300, Riku Voipio wrote:
> implement pipe2 syscall. instead of calling pipe2 directly
> (which was introduced in 2.6.27), emulate the flag functionality
> with fcntl.

and badly tested from me. failed to build on mips and sh4 targets.

>From bf49a705ddbec1821163c54f326782b924729310 Mon Sep 17 00:00:00 2001
From: Riku Voipio <address@hidden>
Date: Tue, 5 May 2009 12:10:04 +0300
Subject: [PATCH] linux-user: implement pipe2 [v2]

implement pipe2 syscall. instead of calling pipe2 directly
(which was introduced in 2.6.27), emulate the flag functionality
with fcntl.

[v2] fix do_pipe build on mips and sh4

Signed-off-by: Riku Voipio <address@hidden>
---
 linux-user/syscall.c |   70 +++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 18 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1096bb1..e3cd185 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -943,6 +943,52 @@ static abi_long do_select(int n,
 
     return ret;
 }
+static abi_long pipe_set_flag(int fd, int readcmd, int writecmd, long newflag)
+{
+    int flags = fcntl(fd, readcmd);
+    if (flags<0)
+        return get_errno(flags);
+    flags |= newflag;
+    flags = fcntl(fd, writecmd, flags);
+    return get_errno(flags);
+}
+
+static abi_long do_pipe(void *cpu_env, int pipedes, int flags)
+{
+    int host_pipe[2];
+    abi_long ret;
+    ret = pipe(host_pipe);
+    if (is_error(ret))
+        return get_errno(ret);
+#if defined(TARGET_MIPS)
+    ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = host_pipe[1];
+    ret = host_pipe[0];
+#elif defined(TARGET_SH4)
+    ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
+    ret = host_pipe[0];
+#else
+    if (put_user_s32(host_pipe[0], pipedes)
+        || put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0])))
+        return -TARGET_EFAULT;
+#endif
+    if (flags & O_NONBLOCK) {
+        ret = pipe_set_flag(host_pipe[0], F_GETFL, F_SETFL, O_NONBLOCK);
+        if (is_error(ret))
+            return get_errno(ret);
+        ret = pipe_set_flag(host_pipe[1], F_GETFL, F_SETFL, O_NONBLOCK);
+        if (is_error(ret))
+            return get_errno(ret);
+    }
+    if (flags & O_CLOEXEC) {
+        ret = pipe_set_flag(host_pipe[0], F_GETFD, F_SETFD, FD_CLOEXEC);
+        if (is_error(ret))
+            return get_errno(ret);
+        ret = pipe_set_flag(host_pipe[1], F_GETFD, F_SETFD, FD_CLOEXEC);
+        if (is_error(ret))
+            return get_errno(ret);
+    }
+    return get_errno(ret);
+}
 
 static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn,
                                               abi_ulong target_addr,
@@ -4525,25 +4571,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
arg1,
         ret = get_errno(dup(arg1));
         break;
     case TARGET_NR_pipe:
-        {
-            int host_pipe[2];
-            ret = get_errno(pipe(host_pipe));
-            if (!is_error(ret)) {
-#if defined(TARGET_MIPS)
-                CPUMIPSState *env = (CPUMIPSState*)cpu_env;
-               env->active_tc.gpr[3] = host_pipe[1];
-               ret = host_pipe[0];
-#elif defined(TARGET_SH4)
-               ((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
-               ret = host_pipe[0];
-#else
-                if (put_user_s32(host_pipe[0], arg1)
-                    || put_user_s32(host_pipe[1], arg1 + sizeof(host_pipe[0])))
-                    goto efault;
-#endif
-            }
-        }
+        ret = do_pipe(cpu_env, arg1, 0);
+        break;
+#ifdef TARGET_NR_pipe2
+    case TARGET_NR_pipe2:
+        ret = do_pipe(cpu_env, arg1, arg2);
         break;
+#endif
     case TARGET_NR_times:
         {
             struct target_tms *tmsp;
-- 
1.6.2.1






reply via email to

[Prev in Thread] Current Thread [Next in Thread]