summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-07-02 10:50:27 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-07-02 11:41:08 +0200
commitf1bf058d7cbb7eaa62c1850c0d931a2c2ee127db (patch)
treed14a46a203739929a8de2fbd2e282b21f5019e45
parent0a216f5edbd5526521784fde5e172bf5dc069e34 (diff)
downloadphp-git-f1bf058d7cbb7eaa62c1850c0d931a2c2ee127db.tar.gz
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.
-rw-r--r--ext/sockets/sockets.c81
1 files changed, 41 insertions, 40 deletions
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c
index f200a2819c..4c9f403131 100644
--- a/ext/sockets/sockets.c
+++ b/ext/sockets/sockets.c
@@ -2028,61 +2028,62 @@ PHP_FUNCTION(socket_get_option)
}
#endif
- /* sol_socket options and general case */
- switch(optname) {
- case SO_LINGER:
- optlen = sizeof(linger_val);
+ if (level == SOL_SOCKET) {
+ switch (optname) {
+ case SO_LINGER:
+ optlen = sizeof(linger_val);
- if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&linger_val, &optlen) != 0) {
- PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
- RETURN_FALSE;
- }
+ if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&linger_val, &optlen) != 0) {
+ PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
+ RETURN_FALSE;
+ }
- array_init(return_value);
- add_assoc_long(return_value, "l_onoff", linger_val.l_onoff);
- add_assoc_long(return_value, "l_linger", linger_val.l_linger);
- break;
+ array_init(return_value);
+ add_assoc_long(return_value, "l_onoff", linger_val.l_onoff);
+ add_assoc_long(return_value, "l_linger", linger_val.l_linger);
+ return;
- case SO_RCVTIMEO:
- case SO_SNDTIMEO:
+ case SO_RCVTIMEO:
+ case SO_SNDTIMEO:
#ifndef PHP_WIN32
- optlen = sizeof(tv);
+ optlen = sizeof(tv);
- if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&tv, &optlen) != 0) {
- PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
- RETURN_FALSE;
- }
+ if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&tv, &optlen) != 0) {
+ PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
+ RETURN_FALSE;
+ }
#else
- optlen = sizeof(int);
+ optlen = sizeof(int);
- if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&timeout, &optlen) != 0) {
- PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
- RETURN_FALSE;
- }
+ if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&timeout, &optlen) != 0) {
+ PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
+ RETURN_FALSE;
+ }
- tv.tv_sec = timeout ? timeout / 1000 : 0;
- tv.tv_usec = timeout ? (timeout * 1000) % 1000000 : 0;
+ tv.tv_sec = timeout ? timeout / 1000 : 0;
+ tv.tv_usec = timeout ? (timeout * 1000) % 1000000 : 0;
#endif
- array_init(return_value);
+ array_init(return_value);
- add_assoc_long(return_value, "sec", tv.tv_sec);
- add_assoc_long(return_value, "usec", tv.tv_usec);
- break;
+ add_assoc_long(return_value, "sec", tv.tv_sec);
+ add_assoc_long(return_value, "usec", tv.tv_usec);
+ return;
+ }
+ }
- default:
- optlen = sizeof(other_val);
+ optlen = sizeof(other_val);
- if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) {
- PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
- RETURN_FALSE;
- }
- if (optlen == 1)
- other_val = *((unsigned char *)&other_val);
+ if (getsockopt(php_sock->bsd_socket, level, optname, (char*)&other_val, &optlen) != 0) {
+ PHP_SOCKET_ERROR(php_sock, "unable to retrieve socket option", errno);
+ RETURN_FALSE;
+ }
- RETURN_LONG(other_val);
- break;
+ if (optlen == 1) {
+ other_val = *((unsigned char *)&other_val);
}
+
+ RETURN_LONG(other_val);
}
/* }}} */