Это продолжение моего предыдущего вопроса:
В Perl, как я могу проверить наличие опций Socket без генерации предупреждений?
Если я запускаю следующий код, я получаю ожидаемый результат:
#!/usr/bin/perl -w
use strict;
use diagnostics;
use Socket qw(:all);
my %opts;
if ( defined( eval { SO_REUSEPORT } ) ) {
$opts{'SO_REUSEPORT'}
= {opt_level =>SOL_SOCKET,opt_name=>SO_REUSEPORT,opt_print=>\&sock_str_flag};
} else {
print "SO_REUSEPORT undefined\n";
$opts{'SO_REUSEPORT'}
= {opt_level =>0,opt_name=>0,opt_print=>undef};
}
=head
# IPV6 options
if ( defined( eval { IPV6_DONTFRAG } ) ) {
$opts{'IPV6_DONTFRAG'}
= {opt_level =>IPPROTO_IPV6,opt_name=>IPV6_DONTFRAG,opt_print=>\&sock_str_flag};
} else {
print "IPV6_DONTFRAG undefined\n";
$opts{'IPV6_DONTFRAG'}
= {opt_level =>0,opt_name=>0,opt_print=>undef};
}
=cut
Это выводит:
anon@perl$ ./test.pl
SO_REUSEPORT undefined
Но если я раскомментирую блок для IPV6_DONTFRAG
, я получу:
Bareword "IPV6_DONTFRAG" not allowed while "strict subs" in use at ./test.pl line 17.
Bareword "IPV6_DONTFRAG" not allowed while "strict subs" in use at ./test.pl line 17.
Почему одно неопределенное голое слово приводит к тому, что оно срывается, а другое нет? И как может ошибка распространяться из блока eval { }
?
Редактировать
Очевидно, SO_REUSEPORT
экспортируется Socket.pm некоторым образом, так как он находится в массиве @EXPORT. Таким образом, очевидно, что он определен, но его использование выдает ошибку, которую перехватывает eval.
Это все еще не объясняет, что происходит с IPV6_DONTFRAG
. Я полагаю, мне нужно определить его самому, а затем просто позвонить getsockopt
, чтобы проверить, поддерживается ли он ...