📄 syscall.c.svn-base
字号:
optname = SO_OOBINLINE; break; case TARGET_SO_NO_CHECK: optname = SO_NO_CHECK; break; case TARGET_SO_PRIORITY: optname = SO_PRIORITY; break;#ifdef SO_BSDCOMPAT case TARGET_SO_BSDCOMPAT: optname = SO_BSDCOMPAT; break;#endif case TARGET_SO_PASSCRED: optname = SO_PASSCRED; break; case TARGET_SO_TIMESTAMP: optname = SO_TIMESTAMP; break; case TARGET_SO_RCVLOWAT: optname = SO_RCVLOWAT; break; case TARGET_SO_RCVTIMEO: optname = SO_RCVTIMEO; break; case TARGET_SO_SNDTIMEO: optname = SO_SNDTIMEO; break; break; default: goto unimplemented; } if (optlen < sizeof(uint32_t)) return -TARGET_EINVAL; if (get_user_u32(val, optval_addr)) return -TARGET_EFAULT; ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val))); break; default: unimplemented: gemu_log("Unsupported setsockopt level=%d optname=%d \n", level, optname); ret = -TARGET_ENOPROTOOPT; } return ret;}/* do_getsockopt() Must return target values and target errnos. */static abi_long do_getsockopt(int sockfd, int level, int optname, abi_ulong optval_addr, abi_ulong optlen){ abi_long ret; int len, lv, val; switch(level) { case TARGET_SOL_SOCKET: level = SOL_SOCKET; switch (optname) { case TARGET_SO_LINGER: case TARGET_SO_RCVTIMEO: case TARGET_SO_SNDTIMEO: case TARGET_SO_PEERCRED: case TARGET_SO_PEERNAME: /* These don't just return a single integer */ goto unimplemented; default: goto int_case; } break; case SOL_TCP: /* TCP options all take an 'int' value. */ int_case: if (get_user_u32(len, optlen)) return -TARGET_EFAULT; if (len < 0) return -TARGET_EINVAL; lv = sizeof(int); ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); if (ret < 0) return ret; val = tswap32(val); if (len > lv) len = lv; if (len == 4) { if (put_user_u32(val, optval_addr)) return -TARGET_EFAULT; } else { if (put_user_u8(val, optval_addr)) return -TARGET_EFAULT; } if (put_user_u32(len, optlen)) return -TARGET_EFAULT; break; case SOL_IP: switch(optname) { case IP_TOS: case IP_TTL: case IP_HDRINCL: case IP_ROUTER_ALERT: case IP_RECVOPTS: case IP_RETOPTS: case IP_PKTINFO: case IP_MTU_DISCOVER: case IP_RECVERR: case IP_RECVTOS:#ifdef IP_FREEBIND case IP_FREEBIND:#endif case IP_MULTICAST_TTL: case IP_MULTICAST_LOOP: if (get_user_u32(len, optlen)) return -TARGET_EFAULT; if (len < 0) return -TARGET_EINVAL; lv = sizeof(int); 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", level, optname); ret = -TARGET_EOPNOTSUPP; break; } return ret;}/* FIXME * lock_iovec()/unlock_iovec() have a return code of 0 for success where * other lock functions have a return code of 0 for failure. */static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, int count, int copy){ struct target_iovec *target_vec; abi_ulong base; int i, j; target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); if (!target_vec) return -TARGET_EFAULT; for(i = 0;i < count; i++) { base = tswapl(target_vec[i].iov_base); vec[i].iov_len = tswapl(target_vec[i].iov_len); vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); if (!vec[i].iov_base) goto fail; } unlock_user (target_vec, target_addr, 0); return 0; fail: /* failure - unwind locks */ for (j = 0; j < i; j++) { base = tswapl(target_vec[j].iov_base); unlock_user(vec[j].iov_base, base, 0); } unlock_user (target_vec, target_addr, 0); return -TARGET_EFAULT;}static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count, int copy){ struct target_iovec *target_vec; abi_ulong base; int i; target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); if (!target_vec) return -TARGET_EFAULT; for(i = 0;i < count; i++) { base = tswapl(target_vec[i].iov_base); unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); } unlock_user (target_vec, target_addr, 0); return 0;}/* do_socket() Must return target values and target errnos. */static abi_long do_socket(int domain, int type, int protocol){#if defined(TARGET_MIPS) switch(type) { case TARGET_SOCK_DGRAM: type = SOCK_DGRAM; break; case TARGET_SOCK_STREAM: type = SOCK_STREAM; break; case TARGET_SOCK_RAW: type = SOCK_RAW; break; case TARGET_SOCK_RDM: type = SOCK_RDM; break; case TARGET_SOCK_SEQPACKET: type = SOCK_SEQPACKET; break; case TARGET_SOCK_PACKET: type = SOCK_PACKET; break; }#endif if (domain == PF_NETLINK) return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */ return get_errno(socket(domain, type, protocol));}/* do_bind() Must return target values and target errnos. */static abi_long do_bind(int sockfd, abi_ulong target_addr, socklen_t addrlen){ void *addr = alloca(addrlen); target_to_host_sockaddr(addr, target_addr, addrlen); return get_errno(bind(sockfd, addr, addrlen));}/* do_connect() Must return target values and target errnos. */static abi_long do_connect(int sockfd, abi_ulong target_addr, socklen_t addrlen){ void *addr = alloca(addrlen); target_to_host_sockaddr(addr, target_addr, addrlen); return get_errno(connect(sockfd, addr, addrlen));}/* do_sendrecvmsg() Must return target values and target errnos. */static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, int flags, int send){ abi_long ret; struct target_msghdr *msgp; struct msghdr msg; int count; struct iovec *vec; abi_ulong target_vec; /* FIXME */ if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, msgp, target_msg, send ? 1 : 0)) return -TARGET_EFAULT; if (msgp->msg_name) { msg.msg_namelen = tswap32(msgp->msg_namelen); msg.msg_name = alloca(msg.msg_namelen); target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name), msg.msg_namelen); } else { msg.msg_name = NULL; msg.msg_namelen = 0; } msg.msg_controllen = 2 * tswapl(msgp->msg_controllen); msg.msg_control = alloca(msg.msg_controllen); msg.msg_flags = tswap32(msgp->msg_flags); count = tswapl(msgp->msg_iovlen); vec = alloca(count * sizeof(struct iovec)); target_vec = tswapl(msgp->msg_iov); lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send); msg.msg_iovlen = count; msg.msg_iov = vec; if (send) { ret = target_to_host_cmsg(&msg, msgp); if (ret == 0) ret = get_errno(sendmsg(fd, &msg, flags)); } else { ret = get_errno(recvmsg(fd, &msg, flags)); if (!is_error(ret)) ret = host_to_target_cmsg(msgp, &msg); } unlock_iovec(vec, target_vec, count, !send); unlock_user_struct(msgp, target_msg, send ? 0 : 1); return ret;}/* do_accept() Must return target values and target errnos. */static abi_long do_accept(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr){ socklen_t addrlen; void *addr; abi_long ret; if (get_user_u32(addrlen, target_addrlen_addr)) return -TARGET_EFAULT; addr = alloca(addrlen); ret = get_errno(accept(fd, addr, &addrlen)); if (!is_error(ret)) { host_to_target_sockaddr(target_addr, addr, addrlen); if (put_user_u32(addrlen, target_addrlen_addr)) ret = -TARGET_EFAULT; } return ret;}/* do_getpeername() Must return target values and target errnos. */static abi_long do_getpeername(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr){ socklen_t addrlen; void *addr; abi_long ret; if (get_user_u32(addrlen, target_addrlen_addr)) return -TARGET_EFAULT; addr = alloca(addrlen); ret = get_errno(getpeername(fd, addr, &addrlen)); if (!is_error(ret)) { host_to_target_sockaddr(target_addr, addr, addrlen); if (put_user_u32(addrlen, target_addrlen_addr)) ret = -TARGET_EFAULT; } return ret;}/* do_getsockname() Must return target values and target errnos. */static abi_long do_getsockname(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr){ socklen_t addrlen; void *addr; abi_long ret; if (get_user_u32(addrlen, target_addrlen_addr)) return -TARGET_EFAULT; addr = alloca(addrlen); ret = get_errno(getsockname(fd, addr, &addrlen)); if (!is_error(ret)) { host_to_target_sockaddr(target_addr, addr, addrlen); if (put_user_u32(addrlen, target_addrlen_addr)) ret = -TARGET_EFAULT; } return ret;}/* do_socketpair() Must return target values and target errnos. */static abi_long do_socketpair(int domain, int type, int protocol, abi_ulong target_tab_addr){ int tab[2]; abi_long ret; ret = get_errno(socketpair(domain, type, protocol, tab)); if (!is_error(ret)) { if (put_user_s32(tab[0], target_tab_addr) || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0]))) ret = -TARGET_EFAULT; } return ret;}/* do_sendto() Must return target values and target errnos. */static abi_long do_sendto(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, socklen_t addrlen){ void *addr; void *host_msg; abi_long ret; host_msg = lock_user(VERIFY_READ, msg, len, 1); if (!host_msg) return -TARGET_EFAULT; if (target_addr) { addr = alloca(addrlen); target_to_host_sockaddr(addr, target_addr, addrlen); ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen)); } else { ret = get_errno(send(fd, host_msg, len, flags)); } unlock_user(host_msg, msg, 0); return ret;}/* do_recvfrom() Must return target values and target errnos. */static abi_long do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, abi_ulong target_addrlen){ socklen_t addrlen; void *addr; void *host_msg; abi_long ret; host_msg = lock_user(VERIFY_WRITE, msg, len, 0); if (!host_msg) return -TARGET_EFAULT; if (target_addr) { if (get_user_u32(addrlen, target_addrlen)) { ret = -TARGET_EFAULT; goto fail; } addr = alloca(addrlen); ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen)); } else { addr = NULL; /* To keep compiler quiet. */ ret = get_errno(recv(fd, host_msg, len, flags)); } if (!is_error(ret)) { if (target_addr) { host_to_target_sockaddr(target_addr, addr, addrlen); if (put_user_u32(addrlen, target_addrlen)) { ret = -TARGET_EFAULT; goto fail;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -