summary refs log tree commit diff stats
path: root/linux-user/syscall.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-06-05 01:52:59 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-06-05 01:52:59 +0000
commit4add45b4f6695c2a2d61b5da0f750519fa400630 (patch)
treea0b598a1cc1370f0b6449ca09ea8a737a182f3a4 /linux-user/syscall.c
parent4f101ad7ff41d1b5f21c4042040c9be7b7817ca0 (diff)
downloadfocaccia-qemu-4add45b4f6695c2a2d61b5da0f750519fa400630.tar.gz
focaccia-qemu-4add45b4f6695c2a2d61b5da0f750519fa400630.zip
getdents for 64 bit cpus
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@212 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r--linux-user/syscall.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4a4a4f7cbe..9b02d5eaf4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2015,7 +2015,47 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
     case TARGET_NR_getdents:
 #if TARGET_LONG_SIZE != 4
 #error not supported
-#endif
+#elif TARGET_LONG_SIZE == 4 && HOST_LONG_SIZE == 8
+        {
+            struct target_dirent *target_dirp = (void *)arg2;
+            struct dirent *dirp;
+            long count = arg3;
+
+	    dirp = malloc(count);
+	    if (!dirp)
+                return -ENOMEM;
+            
+            ret = get_errno(sys_getdents(arg1, dirp, count));
+            if (!is_error(ret)) {
+                struct dirent *de;
+		struct target_dirent *tde;
+                int len = ret;
+                int reclen, treclen;
+		int count1, tnamelen;
+
+		count1 = 0;
+                de = dirp;
+		tde = target_dirp;
+                while (len > 0) {
+                    reclen = de->d_reclen;
+		    treclen = reclen - (2 * (sizeof(long) - sizeof(target_long)));
+                    tde->d_reclen = tswap16(treclen);
+                    tde->d_ino = tswapl(de->d_ino);
+                    tde->d_off = tswapl(de->d_off);
+		    tnamelen = treclen - (2 * sizeof(target_long) + 2);
+		    if (tnamelen > 256)
+                        tnamelen = 256;
+		    strncpy(tde->d_name, de->d_name, tnamelen);
+                    de = (struct dirent *)((char *)de + reclen);
+                    len -= reclen;
+                    tde = (struct dirent *)((char *)tde + treclen);
+		    count1 += treclen;
+                }
+		ret = count1;
+            }
+	    free(dirp);
+        }
+#else
         {
             struct dirent *dirp = (void *)arg2;
             long count = arg3;
@@ -2038,6 +2078,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
                 }
             }
         }
+#endif
         break;
     case TARGET_NR_getdents64:
         {