Commit a311f891 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-4.0-pull-request' into staging



Minor linux-user update (2019-01-10)
Fixes LTP tests pwrite03 and pwrite03_64

# gpg: Signature made Thu 10 Jan 2019 08:37:04 GMT
# gpg:                using RSA key F30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>"
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>"
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>"
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier2/tags/linux-user-for-4.0-pull-request:
  linux-user: make pwrite64/pread64(fd, NULL, 0, offset) return 0
  Add getsockopt for settable SOL_IPV6 options

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 823dcd58 2bd3f899
Loading
Loading
Loading
Loading
+57 −4
Original line number Diff line number Diff line
@@ -2352,6 +2352,45 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
            break;
        }
        break;
    case SOL_IPV6:
        switch (optname) {
        case IPV6_MTU_DISCOVER:
        case IPV6_MTU:
        case IPV6_V6ONLY:
        case IPV6_RECVPKTINFO:
        case IPV6_UNICAST_HOPS:
        case IPV6_MULTICAST_HOPS:
        case IPV6_MULTICAST_LOOP:
        case IPV6_RECVERR:
        case IPV6_RECVHOPLIMIT:
        case IPV6_2292HOPLIMIT:
        case IPV6_CHECKSUM:
            if (get_user_u32(len, optlen))
                return -TARGET_EFAULT;
            if (len < 0)
                return -TARGET_EINVAL;
            lv = sizeof(lv);
            ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
            if (ret < 0)
                return ret;
            if (len < sizeof(int) && len > 0 && val >= 0 && val < 255) {
                len = 1;
                if (put_user_u32(len, optlen)
                    || put_user_u8(val, optval_addr))
                    return -TARGET_EFAULT;
            } else {
                if (len > sizeof(int))
                    len = sizeof(int);
                if (put_user_u32(len, optlen)
                    || put_user_u32(val, optval_addr))
                    return -TARGET_EFAULT;
            }
            break;
        default:
            ret = -TARGET_ENOPROTOOPT;
            break;
        }
        break;
    default:
    unimplemented:
        gemu_log("getsockopt level=%d optname=%d not yet supported\n",
@@ -9677,8 +9716,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
            arg4 = arg5;
            arg5 = arg6;
        }
        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
        if (arg2 == 0 && arg3 == 0) {
            /* Special-case NULL buffer and zero length, which should succeed */
            p = 0;
        } else {
            p = lock_user(VERIFY_WRITE, arg2, arg3, 0);
            if (!p) {
                return -TARGET_EFAULT;
            }
        }
        ret = get_errno(pread64(arg1, p, arg3, target_offset64(arg4, arg5)));
        unlock_user(p, arg2, ret);
        return ret;
@@ -9687,8 +9733,15 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
            arg4 = arg5;
            arg5 = arg6;
        }
        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
        if (arg2 == 0 && arg3 == 0) {
            /* Special-case NULL buffer and zero length, which should succeed */
            p = 0;
        } else {
            p = lock_user(VERIFY_READ, arg2, arg3, 1);
            if (!p) {
                return -TARGET_EFAULT;
            }
        }
        ret = get_errno(pwrite64(arg1, p, arg3, target_offset64(arg4, arg5)));
        unlock_user(p, arg2, 0);
        return ret;