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 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 3663 static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3626 3664 {
3627 3665 struct flock fl;
... ... @@ -3629,6 +3667,10 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3629 3667 struct flock64 fl64;
3630 3668 struct target_flock64 *target_fl64;
3631 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 3675 switch(cmd) {
3634 3676 case TARGET_F_GETLK:
... ... @@ -3640,7 +3682,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3640 3682 fl.l_len = tswapl(target_fl->l_len);
3641 3683 fl.l_pid = tswapl(target_fl->l_pid);
3642 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 3686 if (ret == 0) {
3645 3687 if (!lock_user_struct(VERIFY_WRITE, target_fl, arg, 0))
3646 3688 return -TARGET_EFAULT;
... ... @@ -3663,7 +3705,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3663 3705 fl.l_len = tswapl(target_fl->l_len);
3664 3706 fl.l_pid = tswapl(target_fl->l_pid);
3665 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 3709 break;
3668 3710  
3669 3711 case TARGET_F_GETLK64:
... ... @@ -3675,7 +3717,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3675 3717 fl64.l_len = tswapl(target_fl64->l_len);
3676 3718 fl64.l_pid = tswap16(target_fl64->l_pid);
3677 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 3721 if (ret == 0) {
3680 3722 if (!lock_user_struct(VERIFY_WRITE, target_fl64, arg, 0))
3681 3723 return -TARGET_EFAULT;
... ... @@ -3697,18 +3739,25 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
3697 3739 fl64.l_len = tswapl(target_fl64->l_len);
3698 3740 fl64.l_pid = tswap16(target_fl64->l_pid);
3699 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 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 3747 if (ret >= 0) {
3706 3748 ret = host_to_target_bitmask(ret, fcntl_flags_tbl);
3707 3749 }
3708 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 3761 break;
3713 3762  
3714 3763 default:
... ... @@ -6501,20 +6550,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
6501 6550 struct target_eabi_flock64 *target_efl;
6502 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 6557 switch(arg2) {
6520 6558 case TARGET_F_GETLK64:
... ... @@ -6594,7 +6632,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
6594 6632 ret = get_errno(fcntl(arg1, cmd, &fl));
6595 6633 break;
6596 6634 default:
6597   - ret = do_fcntl(arg1, cmd, arg3);
  6635 + ret = do_fcntl(arg1, arg2, arg3);
6598 6636 break;
6599 6637 }
6600 6638 break;
... ...
linux-user/syscall_defs.h
... ... @@ -1745,6 +1745,12 @@ struct target_statfs64 {
1745 1745 #define TARGET_F_SETLKW 9
1746 1746 #define TARGET_F_SETOWN 5 /* for sockets. */
1747 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 1754 #else
1749 1755 #define TARGET_F_GETLK 5
1750 1756 #define TARGET_F_SETLK 6
... ... @@ -1756,10 +1762,15 @@ struct target_statfs64 {
1756 1762 #define TARGET_F_SETSIG 10 /* for sockets. */
1757 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 1770 #define TARGET_F_GETLK64 12 /* using 'struct flock64' */
1760 1771 #define TARGET_F_SETLK64 13
1761 1772 #define TARGET_F_SETLKW64 14
1762   -
  1773 +#endif
1763 1774 #if defined (TARGET_ARM)
1764 1775 #define TARGET_O_ACCMODE 0003
1765 1776 #define TARGET_O_RDONLY 00
... ...