diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-07-02 10:50:27 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-07-02 11:41:08 +0200 |
commit | f1bf058d7cbb7eaa62c1850c0d931a2c2ee127db (patch) | |
tree | d14a46a203739929a8de2fbd2e282b21f5019e45 | |
parent | 0a216f5edbd5526521784fde5e172bf5dc069e34 (diff) | |
download | php-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.c | 81 |
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); } /* }}} */ |