【问题标题】:c dup undefined errorc dup 未定义错误
【发布时间】:2014-09-25 00:53:58
【问题描述】:

我正在尝试创建两个子进程:

一个孩子从文件中读取其输入,该文件作为参数传入,并将输出写入管道。

另一个孩子从管道中读取其输出并将其输出写入文件,也作为参数传入。

父级为子级设置一些文件描述符,当子级创建时,他们完成对描述符的操作以满足他们的需要。

但是,我在设置文件描述符时遇到了问题,特别是当我尝试关闭并复制输入文件描述符以代替标准输入时。

这是我所有的代码:

#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
    //Open input file
    int fdin;
    fdin = open(argv[1], O_RDONLY);
    //Check if opening the file was successful
    if(fdin > 0)
    {
        //Open output file
        int fdout;
        //Create the output file and
        //check if the output file was created
        if((fdout = creat(argv[2], 0644)) > 0)
        {
            //Captures whether the dup's were successful
            int dup_in;
            int dup_out;

            //Close stdin so we can replace it with our input file
            close(0);
            //Attempt to put the input file at position 0
            //and check if the dup was successful
            if((dup_in = dup(fdin)) > 0)
            {
                //Close stdout so we can replace it with our output file
                close(1);

                //Attempt to put the output file at position 1
                //and check if the dup was successful
                if((dup_out = dup(fdout)) > 0)
                {
                    //Pipe success
                    int pipecreate;
                    //Pipe file descriptors
                    int pipe_fd[2];

                    //Make the pipe and check
                    //if it was successful
                    if((pipecreate = pipe(pipe_fd)) > 0)
                    {
                        //close unneeded file descriptors
                        close(fdin);
                        close(fdout);

                        //Process id for first child
                        int cpid1;
                        //Create first child process
                        cpid1 = fork();

                        //Process creation successful, child block
                        if(cpid1 == 0)
                        {
                            //Read pipe dup success
                            int rpipe_dup;
                            //close f_in
                            close(0);

                            rpipe_dup = dup(pipe_fd[0]);

                            //Dup successful
                            if(rpipe_dup > 0)
                            {
                                //close uneeded file descriptors
                                close(pipe_fd[0]);
                                close(pipe_fd[1]);

                                execl("count", "count", (char *) 0);

                                char readbuf[100] = {0};

                                read(2, readbuf, 100);
                            }
                            //Dup failed
                            else
                            {
                                fprintf(stderr, "Read pipe dup failed.\n");
                                exit(EXIT_FAILURE);
                            }
                        }
                        //Process creation successful, parent block
                        else if(cpid1 > 0)
                        {
                            //Process id for second child
                            int cpid2;
                            //Create second child process
                            cpid2 = fork();

                            //Process creation successful, child block
                            if(cpid2 == 0)
                            {
                                //Write pipe dup success
                                int wpipe_dup;
                                //close f_out
                                close(1);

                                wpipe_dup = dup(pipe_fd[1]);

                                //Dup successful
                                if(wpipe_dup > 0)
                                {
                                    //close uneeded file descriptors
                                    close(pipe_fd[0]);
                                    close(pipe_fd[1]);

                                    execl("convert", "convert", (char *) 0);

                                    char readbuf[100] = {0};

                                    write(1, readbuf, 100);
                                }
                                //Dup failed
                                else
                                {
                                    fprintf(stderr, "Write pipe dup failed.\n");
                                    exit(EXIT_FAILURE);
                                }
                            }
                            //Process creation successful, parent block
                            else if(cpid2 > 0)
                            {
                                //Close unneeded file descriptors
                                close(pipe_fd[0]);
                                close(pipe_fd[1]);

                                int pid;
                                int status;

                                pid = wait(&status);
                                pid = wait(&status);

                            }
                            //Dup failed
                            else
                            {
                                fprintf(stderr, "Error creating child process 2.\n");
                                exit(EXIT_FAILURE);
                            }
                        }
                        //Process creation unsuccessful
                        else
                        {
                            fprintf(stderr, "Error creating child process 1.\n");
                            exit(EXIT_FAILURE);
                        }
                    }
                    //Pipe creation failed
                    else
                    {
                        fprintf(stderr, "Error creating pipe.\n");
                        exit(EXIT_FAILURE);
                    }
                }
                //Dup'ing the output file descriptor failed
                else
                {
                    fprintf(stderr, "Error dup'ing out file descriptor.\n");
                    exit(EXIT_FAILURE);
                }
            }
            //Dup'ing the input file descriptor failed
            else
            {
                //fprintf(stderr, "Error dup'ing in file descriptor.\n
                perror("\nError dup'ing in file descriptor: ");
                exit(EXIT_FAILURE);
            }
        }
        //Creat failed
        else
        {
            fprintf(stderr, "Error creating out file.\n");
            exit(EXIT_FAILURE);
        }
    }
    //Opening input file failed
    else
    {
        fprintf(stderr, "Error opening in file.\n");
        exit(EXIT_FAILURE);
    }
}

我正在 MINIX3 上编译和运行它。

这是我的运行方式,包括程序输出:

cc fork.c
./a.out input.txt output.txt

Error dup'ing in file descriptor: : Undefined error: 0

非常感谢任何帮助。

【问题讨论】:

  • 我找到了原因。 dup 返回文件描述符编号,在本例中为 0。 if((dup_in = dup(fdin)) > 0) 应该是 if((dup_in >= dup(fdin)) > 0)
  • 如果您找到了问题的答案,请将其发布为答案,而不是评论。

标签: c fork pipe dup


【解决方案1】:

我找到了原因。

dup 返回文件描述符编号,在本例中为 0。if ((dup_in = dup(fdin)) &gt; 0) 应为 if ((dup_in &gt;= dup(fdin)))

【讨论】:

  • 你为什么有那个&gt;0?为什么不只是if(dup_in &gt;= dup(fdin))
  • dup_in = dup(fdin)dup_in &gt;= dup(fdin) 显然是非常不同的语句,不能远程相互替代。在后一种情况下,来自dup() 的返回值不会分配给dup_in,并且会丢失。此外,您将尝试访问 dup_in 的值,此时该值尚未初始化。也许你的意思是if ( (dup_in = dup(fdin)) &gt;= 0 ),或者更好的是if ( (dup_in = dup(fdin)) != -1 )
  • >0 本来就不应该在那里,我修复它时忘记将其删除。另外,Paul,我确实将其更改为 if ( (dup_in = dup(fdin)) >= 0 )
猜你喜欢
  • 2014-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
相关资源
最近更新 更多