【问题标题】:C - Execl system callC - 执行系统调用
【发布时间】:2016-10-05 22:53:00
【问题描述】:

我正在尝试在子进程上使用 execl 执行函数,但它返回错误。 这是我的代码:

pid_t Process = fork();
if(Process == 0){
    execl("path/to/executable/executable", "executable", "function", "function_parameter", (const char*)NULL);
}
else if(Process < 0){ //do something
}
else
{
   //parent 
}

程序从标准输入读取命令(每个命令都是一个函数),“函数名”和“函数参数”是输入。为了 示例:

$ ./executable

Welcome to the program

functionN 2

(function N gets executed with 2 as a parameter)
$

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 检查execl调用是否成功(如果返回则失败)。并且“按照惯例,第一个参数应该指向与正在执行的文件关联的文件名”。
  • @kaylum 它不返回-1,这意味着它成功了对吧?我注意到它在打印“Welcome to the program”时进入了程序,但它没有运行 arg0 和 arg1...
  • 嗯,那是一个不同的问题。你说“什么都没发生”!这非常具有误导性,因为您现在说可执行文件实际上已运行。我们看不到被调用程序的代码。但正如我所说,大多数程序都希望 arg0 是程序名称,如果是这种情况,那么你所有的 args 都不合适。
  • 请注意,如果您在命令行中运行executable arg0 arg1,则需要使用execl("path/to/executable", "executable", "arg0", "arg1", (char *)NULL);。如果execl() 返回,您还应该做一些理智的事情(意思是“报告错误并以错误状态退出”),如果它无法执行命令,它会这样做。成功时,它不会返回。因此,无需测试来自execl() 的返回值。
  • 在execl 返回后调用perror 以获得更精确的错误描述。

标签: c system-calls


【解决方案1】:

您需要将输入写入可执行文件的标准输入,因此您可能应该使用管道:

int p[2];
pipe(p);      // Error check?

pid_t Process = fork();
if (Process < 0)
{
    perror("fork()");
    close(p[0]);
    close(p[1]);
}
else if (Process == 0)
{
    dup2(p[0], 0);
    close(p[0]);
    close(p[1]);
    execl("path/to/executable/executable", "executable", (char *)NULL);
    perror("executable");
    exit(1);
}
else
{
    close(p[0]);
    write(p[1], "functionN 2\n", sizeof("functionN 2\n")-1);
    close(p[1]);
    int status;
    pid_t corpse = wait(&status);
}

对于显示的代码,您需要标头 &lt;unistd.h&gt; 和 &lt;sys/wait.h&gt;(除了 &lt;stdio.h&gt; 和 &lt;stdlib.h&gt;)。有无数其他方法可以指定functionN 2 行;也许使用起来会更正统:

char line[] = "functionN 2\n";
…
write(p[1], line, sizeof(line) - 1);

(请记住,sizeof() 在字符串文字中包含终端 null,或者在调整像 line 这样的字符串数组时;不应将其写入子级。)

可以说,您应该检查corpse 值是否与Process 值匹配。你会循环直到你得到正确的尸体,或者你得到一个错误,表明没有更多的孩子。如果您还有其他尚未等待的父进程也启动了,这可以保护您。您还应该考虑报告尸体及其退出状态,至少出于调试目的:

int status = 0;
pid_t corpse;

while ((corpse = wait(&status)) != Process && corpse != -1)
    printf("Other child %d exited with status 0x%.4X\n", (int)corpse, status);
if (corpse == -1)
    printf("Oops! Executable died and we did not get told!\n");
else
    printf("Executable %d exited with status 0x%.4X\n", (int)corpse, status);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-09
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 2011-07-26
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多