进程,分叉,管道程序......我哪里出错了?

时间:2015-04-20 18:55:37

标签: c unix process pipe fork

我在Unix工作,我正在尝试编写一个.c文件来执行以下操作:

对于每个命令行参数,主进程将启动一个子进程(类型A)。

A进程将尝试在新的子进程(类型B)中使用其中一个exec函数(接收到的参数)执行。

如果失败,类型A的进程将使用管道通道向其父级发送exec调用生成的错误代码(errno值)。

成功时,进程A将等待B类进程,一旦完成,它将使用相同的管道通道向其父级传输零代码。

如果执行成功与否,主进程将为每个参数打印。仅对于失败的执行,也会打印错误接收代码。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char const *argv[]) {
        int c2p[2], g2c[2];
        int i;
        char n[100];
        int *stat;
        for (i = 0; i < argc; i++ ) {
                pipe(c2p);
                pipe(g2c);
                if (fork() == 0) {
                        //child code
                        if (fork() == 0) {
                                //grandchild code
                                if (execlp("argv[i]", "argv[i]", NULL) == -1) {
                                        write(g2c[1], errno, sizeof(int));
                                } else {
                                        write(g2c[1], 0, sizeof(int));
                                }
                        }
                        wait(0);
                        read(g2c[0], n, 10);
                        write(c2p[1], n, 10);
                        exit(0);
                }
                read(c2p[0], &stat, sizeof(int));
                if (*stat !=0) {
                        printf("Not succsesful: %s  %d\n", argv[i], *stat);
                } else {
                        printf("Succes! %s\n", argv[i]);
                }
        }

        return 0;
}

2 个答案:

答案 0 :(得分:4)

更改了您的代码,如下所示,这对您有用:

int main(int argc, char const *argv[])
{
    int c2p[2];
    int i;
    int stat;

    for (i = 1; i < argc; i++ ) {
            pipe(c2p);
            if (fork() == 0) {
                    //child code
                    if (fork() == 0) {
                            //grandchild code
                            if (execlp(argv[i], argv[i], NULL) == -1)
                                 exit(errno);
                    }
                    wait(&stat);
                    write(c2p[1], &stat, sizeof(stat));
                    exit(0);
             }
             read(c2p[0], &stat, sizeof(int));
             if (stat != 0)
                   printf("Not succsesful: %s %d\n", argv[i], stat);
             else
                   printf("Succes! %s\n", argv[i]);
    }
}
正如你在我的代码中看到的那样

  • stat必须是整数而非指针
  • 你传递argv [i]作为参数而不是&#34; argv [i]&#34;进入execlp
  • 你退出状态代码以传递孙子的状态(你也可以 孩子的这种技巧)
  • 从1开始执行循环,因为argv [0]是您的程序名称。
  • 在使用exec系列函数之后总是记住你的源代码 进程替换为您调用的程序,因此在成功运行后无法执行。

答案 1 :(得分:0)

两个问题:

  • 你不能用这种方式写一个整数,write需要一个指针,所以 int n; ...; write(fd, &n, sizeof n);
  • execlp 替换调用它的进程,这意味着如果它工作,你永远不会将0写入管道,因为孙子已被程序替换为execlp()ing