【问题标题】:Working with pipes, getting error my pipe isn't declared使用管道,出现错误我的管道未声明
【发布时间】:2015-02-16 15:05:47
【问题描述】:

我正在制作一个基本上可以模仿的程序

    find $1 -name '*'.[ch] | xargs grep -c $2 | sort -t : +1.0 -2.0 --numeric --reverse | head --lines=$3

该程序将分叉成 4 个子进程,第一个子进程的输出是下一个子进程的输入。现在它说我的 pipe12 和 pipe23 没有被声明。他们显然是,但我不确定他们是否可能在错误的位置或正在发生其他事情。任何帮助是极大的赞赏。抱歉所有奇怪的注释块。

    [cs@cycle2 ipc]$ make clean
    rm -f finder pipe tmp1 tmp2
    [cs@cycle2 ipc]$ make build
    gcc -Wall -g finder.c -o finder
    finder.c: In function ‘main’:
    finder.c:45:15: error: ‘pipe12’ undeclared (first use in this function)
         if ((dup2(pipe12[1], 1)) < 0){
           ^
    finder.c:45:15: note: each undeclared identifier is reported only once for each function it appears in
    finder.c:95:15: error: ‘pipe23’ undeclared (first use in this function)
         if ((dup2(pipe23[1], 1)) < 0){
           ^
    finder.c:73:11: warning: unused variable ‘count’ [-Wunused-variable]
       ssize_t count;
       ^
    make: *** [build] Error 1
    [cs@cycle2 ipc]$ vim finder.c


    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <strings.h>
    #include <errno.h>
    #include <sys/wait.h>

    #define BSIZE 256

    #define BASH_EXEC  "/bin/bash"
    #define FIND_EXEC  "/bin/find"
    #define XARGS_EXEC "/usr/bin/xargs"
    #define GREP_EXEC  "/bin/grep"
    #define SORT_EXEC  "/bin/sort"
    #define HEAD_EXEC  "/usr/bin/head"

    int main(int argc, char *argv[]){
      int status;
      pid_t pid_1, pid_2, pid_3, pid_4;



    //  int pipe(int pipe12[2]),pipe(int pipe23[2]),pipe(int pipe34[2]);
        int pipe(int pipe12[2]);
        int pipe(int pipe23[2]);


      if (argc != 4) {
        printf("usage: finder DIR STR NUM_FILES\n");
        exit(0);
      }



      pid_1 = fork();
      if (pid_1 == 0) {
        /* First Child */


      char cmdbuf[BSIZE];
      bzero(cmdbuf, BSIZE);
      sprintf(cmdbuf, "%s %s -name \'*\'.[ch]",FIND_EXEC, argv[1]);

        if ((dup2(pipe12[1], 1)) < 0){
            perror("pipe12 broke in process 1");
            exit(-1);
        }
        close(pipe12[1]);
        close(pipe12[0]);
            if ( (execl(BASH_EXEC, BASH_EXEC, "-c", cmdbuf, (char *) 0)) < 0) {
     fprintf(stderr, "\nError execing find. ERROR#%d\n", errno);
     return EXIT_FAILURE;
     }


        /*
        if((execl("/usr/bin/find","find","-name","*.[ch]", (char *)NULL)) < 0){
    perror("execl 1 didn't work. child 1");
    exit(-1);
       }
    */
        exit(0);
      }



    //----------------------------------------------------------------------


      char buffer;
      ssize_t count;

      pid_2 = fork();
      if (pid_2 == 0) {
        /* Second Child */

        if ( (read(pipe12[0], &buffer, 1))< 0){
            perror("read broke in pipe12 process 2");
            exit(-1);
        }
        if ((dup2(pipe12[0],0)) < 0){
            perror("");
            exit(-1);
        }
        close(pipe12[1]);
        close(pipe12[0]);


      char cmdbuf[BSIZE];
      bzero(cmdbuf, BSIZE);
      sprintf(cmdbuf, "%s %s -c %s ",XARGS_EXEC, GREP_EXEC, argv[1]);

        if ((dup2(pipe23[1], 1)) < 0){
            perror("pipe23 broke in process 2");
            exit(-1);
        }
        close(pipe23[1]);
        close(pipe23[0]);


        if((execl(BASH_EXEC, BASH_EXEC, "-c", cmdbuf, (char *) 0)) < 0){
    fprintf(stderr, "\nError execing find. ERROR#%d\n", errno);
    return EXIT_FAILURE;
       }

    /*
        if((execl("/usr/bin/xargs","grep","-c",argv[1], (char *)NULL))< 0){
            perror("execl 2 didn't work. child 2");
            exit(-1);
        }

    */
        exit(0);
      }

    //----------------------------------------------------------------------


      pid_3 = fork();
      if (pid_3 == 0) {
        /* Third Child */
        exit(0);
      }

    //----------------------------------------------------------------------


      pid_4 = fork();
      if (pid_4 == 0) {
        /* Fourth Child */
        exit(0);
      }

    //----------------------------------------------------------------------


      if ((waitpid(pid_1, &status, 0)) == -1) {
        fprintf(stderr, "Process 1 encountered an error. ERROR%d", errno);
        return EXIT_FAILURE;
      }
      if ((waitpid(pid_2, &status, 0)) == -1) {
        fprintf(stderr, "Process 2 encountered an error. ERROR%d", errno);
        return EXIT_FAILURE;
      }
      if ((waitpid(pid_3, &status, 0)) == -1) {
        fprintf(stderr, "Process 3 encountered an error. ERROR%d", errno);
        return EXIT_FAILURE;
      }
      if ((waitpid(pid_4, &status, 0)) == -1) {
        fprintf(stderr, "Process 4 encountered an error. ERROR%d", errno);
        return EXIT_FAILURE;
      }

      return 0;
    }

【问题讨论】:

    标签: c linux pipe


    【解决方案1】:

    这里有点:

    int pipe(int pipe12[2]);
    int pipe(int pipe23[2]);
    

    两次声明一个函数pipe 接受一个由两个整数组成的数组。1 相反,我假设您要声明两个由两个ints 组成的数组,并以它们作为参数调用pipe。如果您将上述内容替换为

    // declare two arrays of two ints each called pipe12 and pipe23
    int pipe12[2];
    int pipe23[2];
    
    // call pipe with them.
    pipe(pipe12);
    pipe(pipe23);
    

    它编译,程序的这一部分将工作。我还没有检查程序的其余部分。

    1实际上是一个函数pipe,它接受一个指向int 的指针,原因并不太重要。如果您有兴趣:数组不能是函数参数,但指向其元素的指针可以,因此标准中有一条特殊规则,即函数参数列表中的数组声明符具有指向声明的数组类型的元素。长话短说:int pipe(int foo[2]); 等同于 int pipe(int *foo);

    【讨论】:

    • 这很有趣,因为在类的幻灯片中他们使用 int pipe(int foo[2]);
    • 这样做没有问题(事实上我认为这是一件好事),但这只是一个意向声明。您会看到函数签名,并立即知道您应该将 int[2] 放入其中,但并未强制执行。编译器会接受int i; pipe(&amp;i);(虽然你的程序会表现得很奇怪,所以不要那样做)。
    猜你喜欢
    • 2019-06-01
    • 2017-03-14
    • 2019-09-10
    • 2019-03-18
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多