将execl命令(目录列表)的结果传递给父进程?

时间:2017-02-27 14:47:19

标签: 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;       
 }

1 个答案:

答案 0 :(得分:0)

如果您向我们展示了整个错误消息,我们会看到它引用此行:

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

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

  

成功时,读取的字节数...
  出错,-1 ...

所以你想要像

这样的东西
int bytes_read = read(...);
if (bytes_read < 0) {
    perror("read");
    exit(1);
}

一些额外的评论(您没有要求,但可能有所帮助):

不要将字符串文字投射到char*,特别是当您再分配给const char*变量时。

如果您使用errno,则在设置perror()的通话后,您可以提供更多信息,而不仅仅是在错误时打印固定消息 - 请参阅上面的示例。

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