Commit 5f10681186e3a993b534c58ef0a57477ea47e505

Authored by Arnaud Patard (Rtp)
Committed by Riku Voipio
1 parent 3ce34dfb

RFC: fix fcntl support in linux-user - new try

Hi,

This is a new try to fix the fcntl support in linux-user. I tried to
adress all comments but as the previous version is several weeks old,
it's possible that I've missed some.

This patch doesn't handle linux specific fcntl flags. My plan is to get
this version of the patch reviewed/fixed and then, add them if wanted.

Thanks,
Arnaud

Signed-off-by: Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
linux-user/syscall.c
@@ -3622,6 +3622,44 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp, @@ -3622,6 +3622,44 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
3622 return ret; 3622 return ret;
3623 } 3623 }
3624 3624
  3625 +/* warning : doesn't handle linux specific flags... */
  3626 +static int target_to_host_fcntl_cmd(int cmd)
  3627 +{
  3628 + switch(cmd) {
  3629 + case TARGET_F_DUPFD:
  3630 + case TARGET_F_GETFD:
  3631 + case TARGET_F_SETFD:
  3632 + case TARGET_F_GETFL:
  3633 + case TARGET_F_SETFL:
  3634 + return cmd;
  3635 + case TARGET_F_GETLK:
  3636 + return F_GETLK;
  3637 + case TARGET_F_SETLK:
  3638 + return F_SETLK;
  3639 + case TARGET_F_SETLKW:
  3640 + return F_SETLKW;
  3641 + case TARGET_F_GETOWN:
  3642 + return F_GETOWN;
  3643 + case TARGET_F_SETOWN:
  3644 + return F_SETOWN;
  3645 + case TARGET_F_GETSIG:
  3646 + return F_GETSIG;
  3647 + case TARGET_F_SETSIG:
  3648 + return F_SETSIG;
  3649 +#if TARGET_ABI_BITS == 32
  3650 + case TARGET_F_GETLK64:
  3651 + return F_GETLK64;
  3652 + case TARGET_F_SETLK64:
  3653 + return F_SETLK64;
  3654 + case TARGET_F_SETLKW64:
  3655 + return F_SETLKW64;
  3656 +#endif
  3657 + default:
  3658 + return -TARGET_EINVAL;
  3659 + }
  3660 + return -TARGET_EINVAL;
  3661 +}
  3662 +
3625 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) 3663 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3626 { 3664 {
3627 struct flock fl; 3665 struct flock fl;
@@ -3629,6 +3667,10 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -3629,6 +3667,10 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3629 struct flock64 fl64; 3667 struct flock64 fl64;
3630 struct target_flock64 *target_fl64; 3668 struct target_flock64 *target_fl64;
3631 abi_long ret; 3669 abi_long ret;
  3670 + int host_cmd = target_to_host_fcntl_cmd(cmd);
  3671 +
  3672 + if (host_cmd == -TARGET_EINVAL)
  3673 + return host_cmd;
3632 3674
3633 switch(cmd) { 3675 switch(cmd) {
3634 case TARGET_F_GETLK: 3676 case TARGET_F_GETLK:
@@ -3640,7 +3682,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -3640,7 +3682,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3640 fl.l_len = tswapl(target_fl->l_len); 3682 fl.l_len = tswapl(target_fl->l_len);
3641 fl.l_pid = tswapl(target_fl->l_pid); 3683 fl.l_pid = tswapl(target_fl->l_pid);
3642 unlock_user_struct(target_fl, arg, 0); 3684 unlock_user_struct(target_fl, arg, 0);
3643 - ret = get_errno(fcntl(fd, cmd, &fl)); 3685 + ret = get_errno(fcntl(fd, host_cmd, &fl));
3644 if (ret == 0) { 3686 if (ret == 0) {
3645 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0)) 3687 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3646 return -TARGET_EFAULT; 3688 return -TARGET_EFAULT;
@@ -3663,7 +3705,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -3663,7 +3705,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3663 fl.l_len = tswapl(target_fl->l_len); 3705 fl.l_len = tswapl(target_fl->l_len);
3664 fl.l_pid = tswapl(target_fl->l_pid); 3706 fl.l_pid = tswapl(target_fl->l_pid);
3665 unlock_user_struct(target_fl, arg, 0); 3707 unlock_user_struct(target_fl, arg, 0);
3666 - ret = get_errno(fcntl(fd, cmd, &fl)); 3708 + ret = get_errno(fcntl(fd, host_cmd, &fl));
3667 break; 3709 break;
3668 3710
3669 case TARGET_F_GETLK64: 3711 case TARGET_F_GETLK64:
@@ -3675,7 +3717,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -3675,7 +3717,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3675 fl64.l_len = tswapl(target_fl64->l_len); 3717 fl64.l_len = tswapl(target_fl64->l_len);
3676 fl64.l_pid = tswap16(target_fl64->l_pid); 3718 fl64.l_pid = tswap16(target_fl64->l_pid);
3677 unlock_user_struct(target_fl64, arg, 0); 3719 unlock_user_struct(target_fl64, arg, 0);
3678 - ret = get_errno(fcntl(fd, cmd >> 1, &fl64)); 3720 + ret = get_errno(fcntl(fd, host_cmd, &fl64));
3679 if (ret == 0) { 3721 if (ret == 0) {
3680 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0)) 3722 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3681 return -TARGET_EFAULT; 3723 return -TARGET_EFAULT;
@@ -3697,18 +3739,25 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg) @@ -3697,18 +3739,25 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3697 fl64.l_len = tswapl(target_fl64->l_len); 3739 fl64.l_len = tswapl(target_fl64->l_len);
3698 fl64.l_pid = tswap16(target_fl64->l_pid); 3740 fl64.l_pid = tswap16(target_fl64->l_pid);
3699 unlock_user_struct(target_fl64, arg, 0); 3741 unlock_user_struct(target_fl64, arg, 0);
3700 - ret = get_errno(fcntl(fd, cmd >> 1, &fl64)); 3742 + ret = get_errno(fcntl(fd, host_cmd, &fl64));
3701 break; 3743 break;
3702 3744
3703 - case F_GETFL:  
3704 - ret = get_errno(fcntl(fd, cmd, arg)); 3745 + case TARGET_F_GETFL:
  3746 + ret = get_errno(fcntl(fd, host_cmd, arg));
3705 if (ret >= 0) { 3747 if (ret >= 0) {
3706 ret = host_to_target_bitmask(ret, fcntl_flags_tbl); 3748 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3707 } 3749 }
3708 break; 3750 break;
3709 3751
3710 - case F_SETFL:  
3711 - ret = get_errno(fcntl(fd, cmd, target_to_host_bitmask(arg, fcntl_flags_tbl))); 3752 + case TARGET_F_SETFL:
  3753 + ret = get_errno(fcntl(fd, host_cmd, target_to_host_bitmask(arg, fcntl_flags_tbl)));
  3754 + break;
  3755 +
  3756 + case TARGET_F_SETOWN:
  3757 + case TARGET_F_GETOWN:
  3758 + case TARGET_F_SETSIG:
  3759 + case TARGET_F_GETSIG:
  3760 + ret = get_errno(fcntl(fd, host_cmd, arg));
3712 break; 3761 break;
3713 3762
3714 default: 3763 default:
@@ -6501,20 +6550,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -6501,20 +6550,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
6501 struct target_eabi_flock64 *target_efl; 6550 struct target_eabi_flock64 *target_efl;
6502 #endif 6551 #endif
6503 6552
6504 - switch(arg2){  
6505 - case TARGET_F_GETLK64:  
6506 - cmd = F_GETLK64;  
6507 - break;  
6508 - case TARGET_F_SETLK64:  
6509 - cmd = F_SETLK64;  
6510 - break;  
6511 - case TARGET_F_SETLKW64:  
6512 - cmd = F_SETLK64;  
6513 - break;  
6514 - default:  
6515 - cmd = arg2;  
6516 - break;  
6517 - } 6553 + cmd = target_to_host_fcntl_cmd(arg2);
  6554 + if (cmd == -TARGET_EINVAL)
  6555 + return cmd;
6518 6556
6519 switch(arg2) { 6557 switch(arg2) {
6520 case TARGET_F_GETLK64: 6558 case TARGET_F_GETLK64:
@@ -6594,7 +6632,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, @@ -6594,7 +6632,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
6594 ret = get_errno(fcntl(arg1, cmd, &fl)); 6632 ret = get_errno(fcntl(arg1, cmd, &fl));
6595 break; 6633 break;
6596 default: 6634 default:
6597 - ret = do_fcntl(arg1, cmd, arg3); 6635 + ret = do_fcntl(arg1, arg2, arg3);
6598 break; 6636 break;
6599 } 6637 }
6600 break; 6638 break;
linux-user/syscall_defs.h
@@ -1745,6 +1745,12 @@ struct target_statfs64 { @@ -1745,6 +1745,12 @@ struct target_statfs64 {
1745 #define TARGET_F_SETLKW 9 1745 #define TARGET_F_SETLKW 9
1746 #define TARGET_F_SETOWN 5 /* for sockets. */ 1746 #define TARGET_F_SETOWN 5 /* for sockets. */
1747 #define TARGET_F_GETOWN 6 /* for sockets. */ 1747 #define TARGET_F_GETOWN 6 /* for sockets. */
  1748 +#elif defined(TARGET_MIPS)
  1749 +#define TARGET_F_GETLK 14
  1750 +#define TARGET_F_SETLK 6
  1751 +#define TARGET_F_SETLKW 7
  1752 +#define TARGET_F_SETOWN 24 /* for sockets. */
  1753 +#define TARGET_F_GETOWN 25 /* for sockets. */
1748 #else 1754 #else
1749 #define TARGET_F_GETLK 5 1755 #define TARGET_F_GETLK 5
1750 #define TARGET_F_SETLK 6 1756 #define TARGET_F_SETLK 6
@@ -1756,10 +1762,15 @@ struct target_statfs64 { @@ -1756,10 +1762,15 @@ struct target_statfs64 {
1756 #define TARGET_F_SETSIG 10 /* for sockets. */ 1762 #define TARGET_F_SETSIG 10 /* for sockets. */
1757 #define TARGET_F_GETSIG 11 /* for sockets. */ 1763 #define TARGET_F_GETSIG 11 /* for sockets. */
1758 1764
  1765 +#if defined(TARGET_MIPS)
  1766 +#define TARGET_F_GETLK64 33 /* using 'struct flock64' */
  1767 +#define TARGET_F_SETLK64 34
  1768 +#define TARGET_F_SETLKW64 35
  1769 +#else
1759 #define TARGET_F_GETLK64 12 /* using 'struct flock64' */ 1770 #define TARGET_F_GETLK64 12 /* using 'struct flock64' */
1760 #define TARGET_F_SETLK64 13 1771 #define TARGET_F_SETLK64 13
1761 #define TARGET_F_SETLKW64 14 1772 #define TARGET_F_SETLKW64 14
1762 - 1773 +#endif
1763 #if defined (TARGET_ARM) 1774 #if defined (TARGET_ARM)
1764 #define TARGET_O_ACCMODE 0003 1775 #define TARGET_O_ACCMODE 0003
1765 #define TARGET_O_RDONLY 00 1776 #define TARGET_O_RDONLY 00