Используя strace
в интерпретаторе Perl, выполняющем скрипт, становится ясно, что проблема в том, что Perl не упаковывает struct timeval
(требуется SO_RCVTIMEO
) для вас.Кроме того, не существует вспомогательных функций, которые могут сделать это за вас.Вместо этого вы должны сделать это самостоятельно.
Это оказывается проблематичным, поскольку struct timeval
зависит от конкретной машины.Единая спецификация Unix определяет ее :
Заголовок должен определять временную структуру, которая должна включать как минимум следующие члены:
time_t tv_sec Seconds.
suseconds_t tv_usec Microseconds.
В нем также говорится, что time_t является целочисленным или вещественно-плавающим типом, а «suseconds_t должен быть целочисленным типом со знаком, способным хранить значения по крайней мере в диапазоне [-1, 1000000]» (см. sys / types.h).
Без доступа к структуре C это невозможно сделать переносимым.Но если мы примем glibc, у него будет более ограничительное определение, указывающее как long
, и что они являются единственными двумя членами.Тем не менее, это ошибка документации .Так что не бери в голову.
Итак, лучшее, что я могу сделать, что, как я считаю, работает как на GNU / Linux IA-32, так и на GNU / Linux AMD64, это:
$sock->setsockopt(SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 30, 0))
or die "setsockopt: $!";
The pack
format l!
означает использование нативной текущей машины long
, о которой говорят документы glibc, и, по-видимому, она реализована, по крайней мере, для некоторых архитектур glibc (но не SPARC, согласно ошибке).