スクリプトを実行している Perl インタープリターでを使用strace
すると、問題は Perl がstruct timeval
(によって必要とされるSO_RCVTIMEO
) をパックしていないことであることが明らかになります。さらに、それを行うためのヘルパー関数はないようです。代わりに、自分で行う必要があります。
struct timeval
マシン固有であるため、これは問題であることが判明しました。Single Unix Specification では次のように定義されています。
ヘッダーは、少なくとも次のメンバーを含む timeval 構造体を定義する必要があります。
time_t tv_sec Seconds.
suseconds_t tv_usec Microseconds.
また、time_t は整数型または実数浮動小数点型であり、「suseconds_t は、少なくとも範囲 [-1, 1000000] の値を格納できる符号付き整数型でなければならない」 ( sys/types.hを参照) とも述べています。
C 構造体にアクセスしないと、これを移植可能に行うことはできません。しかし、glibc を仮定すると、より制限的な定義があり、両方を として指定しlong
、メンバーは 2 つしかないことになります。ただし、これはドキュメントのバグです。だから気にしないでください。
したがって、私ができる最善のことは、GNU/Linux IA-32 と GNU/Linux AMD64 の両方で機能すると私が信じていることです。
$sock->setsockopt(SOL_SOCKET, SO_RCVTIMEO, pack('l!l!', 30, 0))
or die "setsockopt: $!";
このpack
形式l!
は、現在のマシンのネイティブを使用することを意味しますlong
— これは glibc のドキュメントに書かれていることであり、少なくとも一部の glibc アーキテクチャでは実装されているようです (バグによると SPARC では実装されていません)。