Unix 调用exec返回带有绝对路径的errno 14(错误地址)
为课程制作一个简单的cgi服务器。要做到这一点,我必须创建一个fork/exec来启动cgi处理程序,问题是exec一直返回errno 14。我在一个独立版本中尝试了以下代码,它可以使用绝对路径,也可以不使用绝对路径 代码如下:Unix 调用exec返回带有绝对路径的errno 14(错误地址),unix,cgi,exec,fork,Unix,Cgi,Exec,Fork,为课程制作一个简单的cgi服务器。要做到这一点,我必须创建一个fork/exec来启动cgi处理程序,问题是exec一直返回errno 14。我在一个独立版本中尝试了以下代码,它可以使用绝对路径,也可以不使用绝对路径 代码如下: static void _process_cgi(int fd, http_context_t* ctx) { pid_t childProcess; int ret; char returnValue[1024]; log(LOG, "
static void _process_cgi(int fd, http_context_t* ctx)
{
pid_t childProcess;
int ret;
char returnValue[1024];
log(LOG, "calling cgi", &ctx->uri[1], 0);
if((childProcess = fork()) != 0)
{
///
/// Set the CGI standard output to the socket.
///
dup2(fd, STANDARD_OUTPUT);
//ctx->uri = "/simple.cgi"
execl("/home/dvd/nwebdir/simple.cgi",&ctx->uri[1]);
sprintf(returnValue,"%d",errno);
log(LOG, "exec returned ", returnValue, 0);
return -1;
}
ret = waitpid(childProcess,NULL,0);
sprintf(returnValue,"%d",ret);
log(LOG, "cgi returned", returnValue, 0);
}
以下是服务器在到达我的代码之前通过的sys调用列表(按顺序):
-chdir
-叉子
-setpqrp
-叉子
我不知道这是否相关,但在我的测试程序中,我没有chdir或setpqrp
测试代码如下所示:
pid_t pid;
if ((pid = fork()) != 0)
{
execl("simple.cgi","simple");
//execl("/home/dvd/nwebdir/simple.cgi","simple");
return 0;
}
printf("waiting\n");
waitpid(pid, NULL, 0);
printf("Parent exiting\n");
注意,我在服务器代码中尝试了execl和execlp
您可以在这里找到基本的服务器实现(没有CGI),我所做的唯一更改是在web功能中:
问候
execl("simple.cgi","simple", NULL);
需要null,因为execl()是varargs函数
execl("/home/dvd/nwebdir/simple.cgi", &ctx->uri[1], (char *)0);
execl()
的最后一个参数必须是nullchar*
。通常,您可以编写NULL
而不是(char*)0
,但如果您有#定义NULL 0
,并且您在一台机器上,sizeof(int)!=sizeof(char*)
,例如64位系统。顺便说一句,您复制的代码不正确或存在逻辑错误。Fork()将非零返回给父进程,而不是子进程,因此应恢复条件。(此处没有注释按钮,因此无法做出回答。)这就成功了,但为什么它在测试版本中有效,而在服务器版本中无效?调用未定义的行为会导致未定义(读取不稳定)的行为,包括有时看起来有效。显式强制转换之所以必要,是因为编译器通常可以从函数原型推断要放在堆栈上的参数的长度。但是,在本例中,最后一个指针是变量参数列表的一部分(…
,在原型中),因此编译器在看到0
时只会推送int
。execv()
函数没有出现此问题,因为它传递了一个数组char*const argv[]
。