Skip to content

Commit f1bf058

Browse files
committed
Handle SO_ options only at SOL_SOCKET level
These options may have the same value as options at other levels. This issue showed up on ppc64el.
1 parent 0a216f5 commit f1bf058

File tree

1 file changed

+41
-40
lines changed

1 file changed

+41
-40
lines changed

ext/sockets/sockets.c

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,61 +2028,62 @@ PHP_FUNCTION(socket_get_option)
20282028
}
20292029
#endif
20302030

2031-
/* sol_socket options and general case */
2032-
switch(optname) {
2033-
case SO_LINGER:
2034-
optlen = sizeof(linger_val);
2031+
if (level == SOL_SOCKET) {
2032+
switch (optname) {
2033+
case SO_LINGER:
2034+
optlen = sizeof(linger_val);
20352035

2036-
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&linger_val, &optlen) != 0) {
2037-
PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
2038-
RETURN_FALSE;
2039-
}
2036+
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&linger_val, &optlen) != 0) {
2037+
PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
2038+
RETURN_FALSE;
2039+
}
20402040

2041-
array_init(return_value);
2042-
add_assoc_long(return_value, "l_onoff", linger_val.l_onoff);
2043-
add_assoc_long(return_value, "l_linger", linger_val.l_linger);
2044-
break;
2041+
array_init(return_value);
2042+
add_assoc_long(return_value, "l_onoff", linger_val.l_onoff);
2043+
add_assoc_long(return_value, "l_linger", linger_val.l_linger);
2044+
return;
20452045

2046-
case SO_RCVTIMEO:
2047-
case SO_SNDTIMEO:
2046+
case SO_RCVTIMEO:
2047+
case SO_SNDTIMEO:
20482048
#ifndef PHP_WIN32
2049-
optlen = sizeof(tv);
2049+
optlen = sizeof(tv);
20502050

2051-
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&tv, &optlen) != 0) {
2052-
PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
2053-
RETURN_FALSE;
2054-
}
2051+
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&tv, &optlen) != 0) {
2052+
PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
2053+
RETURN_FALSE;
2054+
}
20552055
#else
2056-
optlen = sizeof(int);
2056+
optlen = sizeof(int);
20572057

2058-
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&timeout, &optlen) != 0) {
2059-
PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
2060-
RETURN_FALSE;
2061-
}
2058+
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&timeout, &optlen) != 0) {
2059+
PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
2060+
RETURN_FALSE;
2061+
}
20622062

2063-
tv.tv_sec = timeout ? timeout / 1000 : 0;
2064-
tv.tv_usec = timeout ? (timeout * 1000) % 1000000 : 0;
2063+
tv.tv_sec = timeout ? timeout / 1000 : 0;
2064+
tv.tv_usec = timeout ? (timeout * 1000) % 1000000 : 0;
20652065
#endif
20662066

2067-
array_init(return_value);
2067+
array_init(return_value);
20682068

2069-
add_assoc_long(return_value, "sec", tv.tv_sec);
2070-
add_assoc_long(return_value, "usec", tv.tv_usec);
2071-
break;
2069+
add_assoc_long(return_value, "sec", tv.tv_sec);
2070+
add_assoc_long(return_value, "usec", tv.tv_usec);
2071+
return;
2072+
}
2073+
}
20722074

2073-
default:
2074-
optlen = sizeof(other_val);
2075+
optlen = sizeof(other_val);
20752076

2076-
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) {
2077-
PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
2078-
RETURN_FALSE;
2079-
}
2080-
if (optlen == 1)
2081-
other_val = *((unsigned char *)&other_val);
2077+
if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) {
2078+
PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
2079+
RETURN_FALSE;
2080+
}
20822081

2083-
RETURN_LONG(other_val);
2084-
break;
2082+
if (optlen == 1) {
2083+
other_val = *((unsigned char *)&other_val);
20852084
}
2085+
2086+
RETURN_LONG(other_val);
20862087
}
20872088
/* }}} */
20882089

0 commit comments

Comments
 (0)