RHEL6
在C中,一个传递如何包含execvp,而execvp又运行perl可执行文件? (这是在打开污点模式时将PERL5LIB的缺失翻译替换为@INC的方法)
这个问题正在寻找暴徒提供的答案的工作实施...... Why does @INC change when setgid-bit of C wrapper around perl script change?
我在一个使用execvp调用perl的C程序中包装perl脚本执行。由于启用了污点模式,因此@INC将不会加载$ PERL5LIB的内容,因此我已使用“-I”将路径传递给perl可执行文件。 perlsec说这是可能的(参考上面注释中的暴徒提供的答案)。
我尝试这样做的尝试失败了。我的C程序试图将perl可执行文件作为execvp的第一个arg运行,然后将perl脚本作为参数列表的一部分运行。包含是perl脚本可执行语句的一部分。这是一个例子......
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char **args; /*args will be passed to execvp. prepend perl executable*/
args=malloc(3*sizeof(char*));
args[0]=malloc(sizeof("/tools/bin/perl -I/proj/perlmods")+1);
strcpy(args[0],"/tools/bin/perl -I/proj/perlmods");
args[1]=malloc(sizeof("/home/me/the.pl")+1);
strcpy(args[1],"/home/me/the.pl");
args[2]=NULL;
execvp("/tools/bin/perl",args);
}
perl脚本只是......
use html_mail;
print "In my.pl\n";
exit;
/ proj / perlmods有html_mail.pm
在linux提示符下使用-I工作直接执行perl执行...
% /tools/bin/perl -I /proj/perlmods /home/me/my.pl
In my.pl
但是运行C二进制文件却没有。它抱怨无法找到perl模块。但是,如果将/ proj / perlmods放入PERL5LIB中,那么它确实有效。所以我认为args是好的,因为perl脚本在args [1]中。
我相信我投入args的include语句被忽略了。如果我把它作为后缀添加到execvp中的perl可执行调用...
execvp("/tools/bin/perl -I /proj/perlmods",args);
... C程序失败了,所以我不认为它属于那里。如果我把include作为perl脚本调用的一部分....
strcpy(args[1],"/home/me/the.pl -I /proj/perlmods");
......它失败了。如果我将它添加为args的新元素(args [3]),它只是作为arg传递给perl脚本并且没有任何影响。
我查看了execvpe,但这看起来像是设置env vars的方法。
问题是,如何将包含信息实际传递给execvp?
答案 0 :(得分:5)
您需要将每个参数作为args
中的单独条目。试试这个:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char *argv[])
{
char *args[4]; /* args will be passed to execvp. prepend perl executable */
args[0] = "/tools/bin/perl";
args[1] = "-I/proj/perlmods";
args[2] = "/home/me/the.pl";
args[3] = NULL;
execvp(args[0], args);
}
答案 1 :(得分:4)
如果你使用的是-I
,那么你做错了什么。脚本的执行者不应该关心脚本库的位置。
如果多个应用程序使用/proj/perlmods
,您应该将以下内容添加到登录脚本中:
export PERL5LIB=/proj/perlmods
如果/proj/perlmods
仅由该Perl程序使用,请将以下内容添加到Perl程序中:
use lib qw( /proj/perlmods );
然后,C程序变为
char *args[2]; # Or char **args = malloc(2 * sizeof(char*));
args[0] = "/home/me/the.pl"; # No need to duplicate the string; just copy the ptr.
args[1] = NULL;
execvp(args[0], args);
而不是
char *args[4]; # Or char **args = malloc(4 * sizeof(char*));
args[0] = "/tools/bin/perl";
args[1] = "-I/proj/perlmods";
args[2] = "/home/me/the.pl";
args[3] = NULL;
execvp(args[0], args);