【发布时间】:2017-09-19 23:51:49
【问题描述】:
我有一个给定的application which uses Perl's gethostbyname to check if a hostname exists in DNS。我不想修补不是我编写的应用程序的源代码。但我考虑在其中一个 Perl 编写的配置文件中覆盖 gethostbyname。
所以我想知道是否有机会通过以某种方式修补该函数来覆盖该函数。
documentation of that application says that its hostname lookups work as follows:
$ perl -e 'print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");'
not found
到目前为止我尝试过:
$ perl -E 'use Socket qw(:DEFAULT getaddrinfo); sub gethostbyname { my ($err, @result) = getaddrinfo(@_); return @result; }; print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");'
not found
还有:
$ perl -E 'use Socket qw(:DEFAULT getaddrinfo); use Monkey::Patch::Action qw(patch_package); patch_package("*", "gethostbyname", "add", sub { my ($err, @result) = getaddrinfo(@_); return @result; }); print(gethostbyname("ipv6.google.com") ? "ok\n" : "not found\n");'
not found
(我也尝试用main 代替* 和replace 代替add。replace 如下所示:Replacing *::gethostbyname: must already exist at /usr/share/perl5/Monkey/Patch/Action.pm line 31.)
【问题讨论】:
-
在第二个sn-p中,你只需要
use subs qw( gethostbyname );。 -
在第三个 sn-p 中,我认为用
BEGIN包裹patch_package就可以了。 -
但是您可能希望从调用
gethostbyname的模块外部进行修补(或者您只需调用正确的子程序)。您可以通过将覆盖命名为CORE::GLOBAL::gethostbyname来做到这一点(在加载使用gethostbyname的模块之前)。见Overriding Built-in Functions。您可以使用caller仅提供覆盖以选择模块。 -
其实我也玩过
BEGIN { },但我不记得是用patch_package还是只用sub gethostbyname { }。感谢 cmets!
标签: perl ipv6 gethostbyname