Данные pipe () не передаются дочернему процессу - PullRequest
1 голос
/ 10 мая 2019

Я пытаюсь записать в канал и прочитать его содержимое, когда exec в другой файл, но по какой-то причине не могу заставить его работать.

Вот файл main.c

int main(int argc, char * argv[]) {
    int pipe_descs[2];
    int matrix[SIZE][SIZE];
    int fdr, fdw;   // file descriptors
    int i;
    pid_t status=0;
    if (pipe(pipe_descs) == -1) {
        fprintf(stderr, "cannot open");
        exit(1);
    }
    fdr = open(argv[1], O_RDONLY);   // open files
    fdw = open("gg.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);

    if (fdr < 0 || fdw < 0) { //validation for error
        perror("failed to open input or output files");
        exit(EXIT_FAILURE);
    }
    removeSpaces(matrix, fdr, fdw);
    status=fork();
    if (status < 0) {
        fputs("error in fork", stderr);
        exit(EXIT_FAILURE);
    }
    close(pipe_descs[0]);
    close(STDOUT_FILENO);
    dup(pipe_descs[1]);
    write(pipe_descs[1],matrix,sizeof(matrix));
    if(status == 0) {
        execl("rowsValidation", "rowsValidation", NULL);
        /*dup2(pipe_descs[IN],0);
        dup2(pipe_descs[OUT],4);
        close(STDOUT_FILENO);*/
    }
    …

Это другой файл, который пытается прочитать данные из буфера, но ничего не произошло.

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

int main(int argc, char * argv[]){
    int pipe_descs[2];
    int mat[9][9];


    int fdr, fdw;   // file descriptors
    char ans='9';
        int i, j;
    printf("%s","got here");
        close(pipe_descs[1]);
    close(STDIN_FILENO);
    dup(pipe_descs[0]);
    read(pipe_descs[0],mat,sizeof(mat));

    for (i = 0; i < 9; i++) { /* Iterate of each row */
        for (j = 0; j < 9; j++) { /* In each row, go over each col element  */
            printf("%d ", mat[i][j]); /* Print each row element */
        }
        printf("\n"); /* Finish a row, start a new line */
    }

    exit(0);
}

После прочтения комментариев и прочтения в сети я изменил это на это. Я попытался проверить это с помощью символа, но я все еще не могу управлять им, чтобы работать. отец записывает символ в канал, а сын выполняет exec для нового процесса, а затем он читает из канала, но он все еще не работает. пожалуйста, помогите мне исправить это

int main(int argc, char * argv[]) {
    int pipe_descs[2];
    int matrix[SIZE][SIZE];
    int fdr, fdw;   // file descriptors
    int i;
    char a='10';
    pid_t status=0;
    if (pipe(pipe_descs) == -1) {
        fprintf(stderr, "cannot open");
        exit(1);
    }
            fdr = open(argv[1], O_RDONLY);   // open files
            fdw = open("gg.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
         if (fdr < 0 || fdw < 0) { //validation for error
             perror("failed to open input or output files");
             exit(EXIT_FAILURE);
         }
        removeSpaces(matrix, fdr, fdw);
         status=fork();
        if (status < 0) {
            fputs("error in fork", stderr);
            exit(EXIT_FAILURE);
        }
         if(status == 0) {

                dup2(pipe_descs[0], 0);     // read the matrix from pipe1 to 0
                close(pipe_descs[0]);
                dup2(pipe_descs[1], 4);
                printf("Execl1 start\n");
                                        // write to 4 instead of pipe1[1]
                execl("rowsValidation", "rowsValidation", NULL);


        }
         else{

                write(pipe_descs[1],&a,sizeof(char));
                close(pipe_descs[1]);


                    /*char buffer[10];
                            close(pipe_descs[1]);
                            close(STDIN_FILENO);
                            dup(pipe_descs[0]);
                            read(pipe_descs[0],buffer,sizeof(buffer));
                            printf("%s",buffer);
                            close(pipe_descs[0]);*/
         }
    close(fdr);   // close the files
    close(fdw);
    exit(EXIT_SUCCESS);
}



 int main(int argc, char * argv[]){
        int pipe_descs[2];
        int mat[9][9];


        int fdr, fdw;   // file descriptors
        char ans;
            int i, j;

        read(0,&ans,sizeof(char));
        printf("%c ", ans);
        for (i = 0; i < 9; i++) { /* Iterate of each row */
            for (j = 0; j < 9; j++) { /* In each row, go over each col element  */
                printf("%d ", mat[i][j]); /* Print each row element */
            }
            printf("\n"); /* Finish a row, start a new line */
        }
    /*  if (pipe(pipe_descs) == -1) {
            fprintf(stderr, "cannot open");
            exit(1);
        }*/
        //write(4,1,sizeof(char));
        exit(0);
    }

1 Ответ

2 голосов
/ 10 мая 2019

Я думаю, у вас есть небольшое понимание того, что вы хотите и как это сделать, но вы не на 100% там. Если вы хотите создать канал, напишите туда информацию и попросите другую программу ее прочитать: вы начинаете с создания канала, например, создаете новый процесс с помощью fork () (некоторые люди советуют не использовать fork: https://www.microsoft.com/en-us/research/publication/a-fork-in-the-road/) и измените дескрипторы файлов с помощью вызовов dup2 () (и dup ()). Процесс создания канала, разветвления и выполнения exec можно легко выполнить с помощью вызова popen (), и я советую вам посмотрите на это.

Вот пример, который может вам помочь:

char* generate_hash(char* password, char* salt)
{
    char password_plus_salt[MAX_PASSWORD_LEN + SALT_LEN];
    strcpy(password_plus_salt, password);
    strcat(password_plus_salt, salt);

    int fd[2];
    pipe(fd);

    int stdout_save = dup(STDOUT_FILENO);
    dup2(fd[WRITE], STDOUT_FILENO);

    FILE* input = popen("sha256sum", "w");

    fprintf(input, password_plus_salt, "%s");

    FILE* output = fdopen(fd[READ], "r");

    pclose(input);

    char* hash = (char*)malloc(sizeof(char) * (HASH_LEN + 1));
    memset(hash, '\0', (HASH_LEN + 1) * sizeof(char));

    for (int i = 0; i < HASH_LEN; i++) {
        hash[i] = (char)fgetc(output);
    }

    dup2(stdout_save, STDOUT_FILENO);

    return hash;
}

Я также советую вам переключить проверку ошибок и изменить такие вещи, как:

if (fdr < 0 || fdw < 0) { //validation for error
             perror("failed to open input or output files");
             exit(EXIT_FAILURE);
         }

для:

if (fdr < 0) 
{ 
    perror("fdr");
    exit(EXIT_FAILURE);
}
if (fdw < 0) 
{ 
    perror("fdw");
    exit(EXIT_FAILURE);
}

Таким образом, вы можете быть уверены в происхождении ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...