c++ - 将 execl 命令的结果(即目录列表)通过管道传递给父进程?

标签 c++ linux system

我正在做一些关于 Linux 中的进程管理以及如何使用系统调用和子进程与父进程之间的通信的练习。我需要实现一个管道来获取子进程提供的字符串,这是目录列表作为字符串并将其传递给父进程以计算该字符串中的行数并通过这样做找到该目录中的文件数.我遇到的问题在这里:

错误:初始化程序无法确定“dirFileList”的大小 char dirFileList[] = read(tunnel[0],buf,MAX_BUF)

我的代码也在下面:

#define die(e) do { fprintf(stderr, "%s\n", e); exit(EXIT_FAILURE); }    while (0);
#define MAX_BUF 2024
int main()
{
const char *path = (char *)"/";                              /* Root path */
const char *childCommand = (char *)"ls |";                   /* Command to be executed by the child process */
const char *parentCommand = (char *)"wc -l";                 /* Command to be executed by the parent process */

int i = 0;                                                   /* A simple loop counter :) */
int counter = 0;                                             /* Counts the number of lines in the string provided in the child process */
int dirFileNum;                                              /* Keeps the list of files in the directory */
int tunnel[2];                                               /* Defining an array of integer to let the child process store a number and parent process to pick that number */
pid_t pID = fork(); 
char buf[MAX_BUF];                                           /* Fork from the main process */


if (pipe(tunnel) == -1)                                      /* Pipe from the parent to the child */
    die("pipe died.");

if(pID == -1)                                                /* Check if the fork result is valid */
{
    die("fork died.");
}   
else if(pID == 0)                                            /* Check if we are in the child process */ 
{
    dup2 (tunnel[1], STDOUT_FILENO);                         /* Redirect standard output */                 
    close(tunnel[0]);
    close(tunnel[1]);
    execl(childCommand, path);                               /* Execute the child command */
    die("execl died.");
}   
else                                                         /* When we are still in the main process */
{
    close(tunnel[1]);
    char dirFileList[] = read(tunnel[0],buf,MAX_BUF);                    /* Read the list of directories provided by the child process */
    for(i;i<strlen(dirFileList);i++)                         /* Find the number of lines in the list provided by the child process */
        if(dirFileList[i] == '\n')
            counter++;

    printf("Root contains %d files.", counter);              /* Print the result */
    wait(NULL);                                              /* Wait until the job is done by the child process */

}       

return 0;       
 }

最佳答案

如果您向我们展示了整个错误消息,我们会看到它指的是这一行:

char dirFileList[] = read(tunnel[0],buf,MAX_BUF);

你不能像那样声明一个不确定的数组。如果您阅读 read(2) 的手册页,您会看到返回值为

On success, the number of bytes read ...
On error, -1 ...

所以你想要类似的东西

int bytes_read = read(...);
if (bytes_read < 0) {
    perror("read");
    exit(1);
}

一些额外的评论(您没有要求,但可能具有指导意义):

不要将字符串文字转换为 char*,尤其是当您随后分配给 const char* 变量时。

如果您使用 perror(),您可以在设置了 errno 的调用之后提供更多信息,而不仅仅是在出错时打印固定消息 - 请参阅我上面的示例.

die() 可以作为一个函数来实现,这将比宏更容易调试和正确使用。

关于c++ - 将 execl 命令的结果(即目录列表)通过管道传递给父进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42488656/

相关文章:

spring - 将加密属性传递给 spring 上下文

c++ - 我可以控制鼠标属性,例如点击速度吗?

linux - 跨不同计算机的同步调用

c++ - 计算字符串中的单词

c++ - wxWidgets 2.9+ 中的 wxGetElapsedTime 函数

java - 如何释放字符**

linux - 为什么 bash/echo 在此 CMake 脚本中不起作用?

linux - 指定 GCC 输出二进制文件的预期 Linux 版本

c - 手动获取系统函数的地址?

c++ - 为什么我重载的 << 运算符没有输出最后一行?