6788242 SO_{SND,RCV}TIMEO {set,get}sockopt fail with 32-bit binaries on a 64-bit kernel
6785539 IP_OPTIONS should be removed by doing a setsockopt of IP_OPTIONS with optlen=0.
6786063 For XPG4.2 interface, socket(AF_INET, SOCK_STREAM, IPPROTO_UDP) should fails with EPROTOTYPE
diff --git a/usr/src/uts/common/fs/sockfs/sockcommon_subr.c b/usr/src/uts/common/fs/sockfs/sockcommon_subr.c
index b5d6ae9..8ad0011 100644
--- a/usr/src/uts/common/fs/sockfs/sockcommon_subr.c
+++ b/usr/src/uts/common/fs/sockfs/sockcommon_subr.c
@@ -1592,17 +1592,31 @@
case SO_RCVTIMEO: {
clock_t value;
socklen_t optlen = *optlenp;
-
- if (optlen < (t_uscalar_t)sizeof (struct timeval)) {
- return (EINVAL);
+ if (get_udatamodel() == DATAMODEL_NATIVE) {
+ if (optlen < sizeof (struct timeval))
+ return (EINVAL);
+ } else {
+ if (optlen < sizeof (struct timeval32))
+ return (EINVAL);
}
if (option_name == SO_RCVTIMEO)
value = drv_hztousec(so->so_rcvtimeo);
else
value = drv_hztousec(so->so_sndtimeo);
- ((struct timeval *)(optval))->tv_sec = value / (1000 * 1000);
- ((struct timeval *)(optval))->tv_usec = value % (1000 * 1000);
- *optlenp = sizeof (struct timeval);
+
+ if (get_udatamodel() == DATAMODEL_NATIVE) {
+ ((struct timeval *)(optval))->tv_sec =
+ value / (1000 * 1000);
+ ((struct timeval *)(optval))->tv_usec =
+ value % (1000 * 1000);
+ *optlenp = sizeof (struct timeval);
+ } else {
+ ((struct timeval32 *)(optval))->tv_sec =
+ value / (1000 * 1000);
+ ((struct timeval32 *)(optval))->tv_usec =
+ value % (1000 * 1000);
+ *optlenp = sizeof (struct timeval32);
+ }
return (0);
}
case SO_DEBUG: