@@ -10806,25 +10806,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
10806
10806
case TARGET_NR_getdents :
10807
10807
{
10808
10808
struct target_dirent * target_dirp ;
10809
- struct dirent * host_dirp ;
10810
10809
DIR * dirp ;
10811
10810
abi_long dir_fd = arg1 ;
10812
10811
abi_long count = arg3 ;
10813
- int found_err = FALSE;
10814
- // ret == bytes read, or target error code
10812
+
10813
+ // ret == >0 => bytes read
10814
+ // 0 => end of directory
10815
+ // <0 => -(target errno)
10815
10816
10816
10817
dirp = fdopendir (dir_fd );
10817
10818
if (!dirp ) {
10818
10819
ret = - host_to_target_errno (errno );
10819
10820
goto fail ;
10820
10821
}
10821
10822
10822
- host_dirp = g_try_malloc (count );
10823
- if (!host_dirp ) {
10824
- ret = - TARGET_ENOMEM ;
10825
- goto fail ;
10826
- }
10827
-
10828
10823
// collect readdir calls into getdents dirp * buffer
10829
10824
target_dirp = lock_user (VERIFY_WRITE , arg2 , count , 0 );
10830
10825
if (!target_dirp ) {
@@ -10837,10 +10832,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
10837
10832
uint target_reclen ;
10838
10833
uint name_len ;
10839
10834
10835
+ errno = 0 ;
10840
10836
while ((de = readdir (dirp ))) {
10841
10837
// check if new entry will overflow the target buffer
10842
10838
name_len = de -> d_namlen + 1 ;
10843
- target_reclen = target_dirent_len + name_len ;
10839
+ target_reclen = TARGET_DIRENT_LEN + name_len ;
10844
10840
// is this the correct way to align this structure..?
10845
10841
target_reclen = QEMU_ALIGN_UP (target_reclen , __alignof(struct target_dirent ));
10846
10842
if (bytes_used + target_reclen > count ) {
@@ -10857,7 +10853,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
10857
10853
bytes_used += target_reclen ;
10858
10854
}
10859
10855
10860
- if (found_err ) {
10856
+ if (errno != 0 ) {
10861
10857
ret = - host_to_target_errno (errno );
10862
10858
} else {
10863
10859
ret = bytes_used ;
@@ -10867,112 +10863,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
10867
10863
// which was used in `fdopendir`
10868
10864
// closedir(dirp);
10869
10865
}
10870
- // Old Linux code
10871
- // #ifdef __NR_getdents
10872
- // {
10873
- // struct target_dirent *target_dirp;
10874
- // struct linux_dirent *dirp;
10875
- // abi_long count = arg3;
10876
- //
10877
- // dirp = g_try_malloc(count);
10878
- // if (!dirp) {
10879
- // ret = -TARGET_ENOMEM;
10880
- // goto fail;
10881
- // }
10882
- //
10883
- // ret = get_errno(sys_getdents(arg1, dirp, count));
10884
- // if (!is_error(ret)) {
10885
- // struct linux_dirent *de;
10886
- // struct target_dirent *tde;
10887
- // int len = ret;
10888
- // int reclen, treclen;
10889
- // int count1, tnamelen;
10890
- //
10891
- // count1 = 0;
10892
- // de = dirp;
10893
- // if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
10894
- // goto efault;
10895
- // tde = target_dirp;
10896
- // while (len > 0) {
10897
- // reclen = de->d_reclen;
10898
- // tnamelen = reclen - offsetof(struct linux_dirent, d_name);
10899
- // tnamelen = strnlen(de->d_name, tnamelen) + 1;
10900
- // assert(tnamelen >= 0);
10901
- // treclen = tnamelen + offsetof(struct target_dirent, d_name);
10902
- // /* XXX: avoid buffer overflow, for the price of lost entries */
10903
- // if (count1 + treclen > count)
10904
- // break;
10905
- // __put_user(treclen, &tde->d_reclen);
10906
- // __put_user(de->d_ino, &tde->d_ino);
10907
- // __put_user(de->d_off, &tde->d_off);
10908
- // memcpy(tde->d_name, de->d_name, tnamelen);
10909
- // de = (struct linux_dirent *)((char *)de + reclen);
10910
- // len -= reclen;
10911
- // tde = (struct target_dirent *)((char *)tde + treclen);
10912
- // count1 += treclen;
10913
- // }
10914
- // ret = count1;
10915
- // unlock_user(target_dirp, arg2, ret);
10916
- // }
10917
- // g_free(dirp);
10918
- // }
10919
- // #else
10920
- // /* Implement getdents in terms of getdents64 */
10921
- // {
10922
- // struct linux_dirent64 *dirp;
10923
- // abi_long count = arg3;
10924
- //
10925
- // dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
10926
- // if (!dirp) {
10927
- // goto efault;
10928
- // }
10929
- // ret = get_errno(sys_getdents64(arg1, dirp, count));
10930
- // if (!is_error(ret)) {
10931
- // /* Convert the dirent64 structs to target dirent. We do this
10932
- // * in-place, since we can guarantee that a target_dirent is no
10933
- // * larger than a dirent64; however this means we have to be
10934
- // * careful to read everything before writing in the new format.
10935
- // */
10936
- // struct linux_dirent64 *de;
10937
- // struct target_dirent *tde;
10938
- // int len = ret;
10939
- // int tlen = 0;
10940
- //
10941
- // de = dirp;
10942
- // tde = (struct target_dirent *)dirp;
10943
- // while (len > 0) {
10944
- // int namelen, treclen;
10945
- // int reclen = de->d_reclen;
10946
- // uint64_t ino = de->d_ino;
10947
- // int64_t off = de->d_off;
10948
- // uint8_t type = de->d_type;
10949
- //
10950
- // namelen = de->d_reclen - offsetof(struct linux_dirent64, d_name);
10951
- // namelen = strnlen(de->d_name, namelen);
10952
- // treclen = offsetof(struct target_dirent, d_name)
10953
- // + namelen + 2;
10954
- // treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
10955
- //
10956
- // memmove(tde->d_name, de->d_name, namelen + 1);
10957
- // __put_user(ino, &tde->d_ino);
10958
- // __put_user(off, &tde->d_off);
10959
- // __put_user(treclen, &tde->d_reclen);
10960
- // #if !defined TARGET_ABI_IRIX && !defined TARGET_ABI_SOLARIS
10961
- // /* The target_dirent type is in what was formerly a padding
10962
- // * byte at the end of the structure:
10963
- // */
10964
- // *(((char *)tde) + treclen - 1) = type;
10965
- // #endif
10966
- // de = (struct linux_dirent64 *)((char *)de + reclen);
10967
- // tde = (struct target_dirent *)((char *)tde + treclen);
10968
- // len -= reclen;
10969
- // tlen += treclen;
10970
- // }
10971
- // ret = tlen;
10972
- // }
10973
- // unlock_user(dirp, arg2, ret);
10974
- // }
10975
- // #endif
10976
10866
#ifdef TARGET_NR_ngetdents
10977
10867
if (ret >= 0 && num == TARGET_NR_ngetdents ) {
10978
10868
abi_long * p = lock_user (VERIFY_WRITE , arg4 , sizeof (abi_long ), 0 );
@@ -14484,31 +14374,31 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
14484
14374
}
14485
14375
}
14486
14376
break ;
14487
- case TARGET_NR_syssgi_sysid :
14488
- {
14489
- char * buf = lock_user (VERIFY_WRITE , arg2 , 64 , 0 );
14490
- if (!buf ) {
14491
- goto efault ;
14377
+ case TARGET_NR_syssgi_sysid :
14378
+ {
14379
+ char * buf = lock_user (VERIFY_WRITE , arg2 , 64 , 0 );
14380
+ if (!buf ) {
14381
+ goto efault ;
14382
+ }
14383
+ snprintf (buf , 64 , "%12llx" , 0x08006900000DULL );
14384
+ ret = 0 ;
14385
+ unlock_user (buf , arg2 , 64 );
14386
+ break ;
14492
14387
}
14493
- snprintf (buf , 64 , "%12llx" , 0x08006900000DULL );
14388
+ case TARGET_NR_syssgi_rldenv :
14389
+ case TARGET_NR_syssgi_tosstsave :
14390
+ case TARGET_NR_syssgi_fpbcopy :
14391
+ case TARGET_NR_syssgi_getprocattr : /* ? 2nd=string 3rd=result ptr */
14494
14392
ret = 0 ;
14495
- unlock_user (buf , arg2 , 64 );
14496
14393
break ;
14497
- }
14498
- case TARGET_NR_syssgi_rldenv :
14499
- case TARGET_NR_syssgi_tosstsave :
14500
- case TARGET_NR_syssgi_fpbcopy :
14501
- case TARGET_NR_syssgi_getprocattr : /* ? 2nd=string 3rd=result ptr */
14502
- ret = 0 ;
14503
- break ;
14504
14394
case TARGET_NR_syssgi_setgroups :
14505
14395
case TARGET_NR_syssgi_getgroups :
14506
14396
default :
14507
14397
gemu_log ("qemu: Unsupported syscall: sgisys(%d)\n" , (int )arg1 );
14508
14398
ret = - TARGET_ENOSYS ;
14509
14399
break ;
14510
14400
}
14511
- break ;
14401
+ break ;
14512
14402
}
14513
14403
#endif
14514
14404
#ifdef TARGET_NR_sginap
0 commit comments