代码仅在保留未使用的数组时有效

时间:2016-02-15 03:10:51

标签: c

我有一个数组int ofd[4]我不再在我的代码中使用了。但是,如果我将其注释掉,我的代码将不再有效 - 我在stdout上没有输出并且文件已创建,但是为空。

要观察此行为,请编译并运行代码./manatee /bin/ls -l /usr/bin/sort -r out.txt

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

#define READ_STDIN    0
#define READ_STDOUT   1
#define WRITE_STDIN   2
#define WRITE_STDOUT  3
#define NUM_PIPES     4

int pipes[NUM_PIPES][2];

#define READ_FD  0
#define WRITE_FD 1

void closeThePipes() {
    close(pipes[READ_STDIN][READ_FD]);
    close(pipes[READ_STDOUT][WRITE_FD]);
    close(pipes[READ_STDOUT][READ_FD]);
    close(pipes[READ_STDIN][WRITE_FD]);
    close(pipes[WRITE_STDIN][READ_FD]);
    close(pipes[WRITE_STDOUT][WRITE_FD]);
    close(pipes[WRITE_STDOUT][READ_FD]);
    close(pipes[WRITE_STDIN][WRITE_FD]);
}

int main(int argc, char ** argv) {
    if (argc != 6) {
        exit(1);
    }

    pipe(pipes[READ_STDOUT]);
    pipe(pipes[READ_STDIN]);
    pipe(pipes[WRITE_STDOUT]);
    pipe(pipes[WRITE_STDIN]);

    int ofd[4];

    if (!fork()) {
        dup2(pipes[READ_STDIN][READ_FD], STDIN_FILENO);
        dup2(pipes[READ_STDOUT][WRITE_FD], STDOUT_FILENO);
        closeThePipes();

        char * args[2];
        args[0] = argv[1];
        args[1] = argv[2];
        execv(args[0], &args);
        exit(EXIT_SUCCESS);
    } else {
        if (!fork()) {
            dup2(pipes[WRITE_STDIN][READ_FD], STDIN_FILENO);
            dup2(pipes[WRITE_STDOUT][WRITE_FD], STDOUT_FILENO);
            closeThePipes();

            char * args[2];
            args[0] = argv[3];
            args[1] = argv[4];
            execv(args[0], &args);
            exit(EXIT_SUCCESS);
        } else {
            char buffer[100];
            int count;

            close(pipes[READ_STDIN][READ_FD]);
            close(pipes[READ_STDOUT][WRITE_FD]);
            close(pipes[WRITE_STDIN][READ_FD]);
            close(pipes[WRITE_STDOUT][WRITE_FD]);

            FILE * tee = fopen(argv[5], "w");

            close(pipes[READ_STDIN][WRITE_FD]);
            while ((count = read(pipes[READ_STDOUT][READ_FD], buffer, sizeof(buffer)-1)) > 0) {
                if (count > 0) {
                    buffer[count] = '\0';
                    fprintf(tee, "%s", buffer);
                    write(pipes[WRITE_STDIN][WRITE_FD], buffer, count);
                }
            }
            close(pipes[READ_STDOUT][READ_FD]);
            close(pipes[WRITE_STDIN][WRITE_FD]);
            while ((count = read(pipes[WRITE_STDOUT][READ_FD], buffer, sizeof(buffer)-1)) > 0) {
                if (count > 0) {
                    buffer[count] = '\0';
                    printf("%s", buffer);
                }
            }
            close(pipes[WRITE_STDIN][READ_FD]);
        }
    }
    return EXIT_SUCCESS;
}

1 个答案:

答案 0 :(得分:7)

当你遇到这样的奇怪行为时,它几乎总是意味着你的程序中有一个导致未定义行为的错误。例如,MainActivity不正确且具有UB。来自execv man page

  

指针数组必须以NULL指针

终止

在您的情况下,每个execv(args[0], &args);数组都没有使用NULL指针条目正确终止。所以只需要按如下方式更改代码的这些部分:

args