首页 > 解决方案 > 如果我不刷新缓冲区,execlp 将失败

问题描述

我正在尝试在 C 中的子进程中运行命令:

int main()
{
    if (fork()) {
        wait(0);
    } else {
        fflush(stdout);
        execlp("ls", "ls");
        printf("Command not found: \"%s\"\n", "ls");
    }   
}

我的理解是调用fork()将创建进程的克隆(子进程)。这里的父进程会wait(0),因为fork()不返回null,并等待子进程完成。

我理解子进程的图像ls在调用execlp("ls", "ls");.

此时,如果ls路径中存在,则ls程序接管并且printf()永远不应调用第 8 行。

这与我在上面发布的代码段按预期工作,并且我ls在当前目录中获得了输出。

但是,如果我注释掉 fflush(stdout)printf()就会被调用!

Command not found: "ls"

printf()如果我注释掉,为什么会被调用fflush(stdout)

标签: cexec

解决方案


以下建议的代码:

  1. 干净地编译
  2. 执行所需的功能
  3. 正确检查错误
  4. 对于任何错误,正确传递“您的”错误消息和系统认为发生错误的文本原因stderr
  5. 将有效的参数列表传递给execlp()
  6. 记录为什么包含每个头文件
  7. main()为函数使用 C 编程语言标准中定义的有效签名
  8. 不对从返回的值做出假设fork()
  9. 遵循公理:每行只有一个语句,并且(最多)每个语句一个变量声明。

现在,建议的代码:

#include <stdio.h>    // perror(), printf()
#include <stdlib.h>   // exit(), EXIT_FAILURE
#include <unistd.h>   // execlp(), fork(), pid_t
#include <sys/wait.h> // wait()


int main( void )
{
    pid_t pid = fork();

    if ( pid < 0 ) 
    {   // then error
        perror( "fork failed" );
        exit( EXIT_FAILURE );
    }

    if( pid == 0 )
    {   // then child
        execlp("ls", "ls", NULL );
        perror( "execlp failed" );
        exit( EXIT_FAILURE );
    }

    else
    {   // then parent
        wait(0);
    } 
}

推荐阅读