Проблема с передачей данных между процессами в C

Мне нужно подключиться от моей функции чтения к моей функции записи. Я тестировал с помощью командной строки ./mapstore retrieve ABCD 2>/dev/null | ./mapstore -p ./new_dir/ stream ABCD, и это успешно записало данные в канал, а поток успешно прочитал данные из канала и записал их в файловую систему.

Я хотел бы сделать это на C, но у меня проблемы. retrieve_data failed: Undefined error: 0 Я основывал свой код на том, что было в этом выпуске Классический C. Использование каналов в функции execvp, перенаправление stdin и stdout

#include <unistd.h>
#include <stdlib.h>
#include "mapstore.h"

int main(int argc, char *argv[]) {

    mapstore_ctx ctx;
    if (initialize_mapstore(ctx, NULL) != 0) {
       fprintf(stderr, "Error initializing mapstore\n");
        return 1;
    }

    mapstore_ctx new_ctx;
    if (initialize_mapstore(&new_ctx, NULL) != 0) {
       fprintf(stderr, "Error initializing mapstore\n");
        return 1;
    }

    char *hash = argv[1];
    int des_p[2];
    if(pipe(des_p) == -1) {
      fprintf(stderr, "Failed to create pipe\n");
      status = 1;
      goto end_restructure;
    }
    printf("1\n");

    if(fork() == 0) {
        printf("1a\n");
        close(des_p[0]);       //closing pipe read
        printf("2a\n");
        close(des_p[1]);
        printf("3a\n");
        if ((status = retrieve_data(ctx, des_p[1], hashes[i])) != 0) {
            perror("retrieve_data failed");
            exit(1);
        }
        printf("4a\n");
        exit(0);
    }

    if(fork() == 0) {
        printf("1b\n");
        close(des_p[1]);       //closing pipe write
        printf("2b\n");
        close(des_p[0]);
        printf("3b\n");
        if ((status = store_data(&new_ctx, des_p[0], hashes[i])) != 0) {
            perror("store_data failed");
            exit(1);
        }
        printf("4b\n");
        exit(0);
    }
    printf("2\n");
    close(des_p[0]);
    printf("3\n");
    close(des_p[1]);
    printf("4\n");
    wait(0);
    wait(0);
    return 0;
}

Полный код доступен здесь https://github.com/aleitner/libmapstore/blob/master/src/mapstore.c#L374


person Alexander Leitner    schedule 08.12.2017    source источник
comment
На первый взгляд ваш код выглядит правильно. Какие у вас проблемы?   -  person John Bollinger    schedule 09.12.2017
comment
Когда я запускаю код, он выдает мне что-то вроде ./src/mapstore restructure Hash: 04a672a6eae704366c44d666890e43ad16bad2b9 retrieve_data failed: Undefined error: 0, а затем он просто зависает навсегда, пока я не отправлю сигнал для выхода   -  person Alexander Leitner    schedule 09.12.2017
comment
Это сообщение об ошибке говорит мне, что ваша функция retrieve_data() вернула 0, а errno имеет значение 0. Действительно ли retrieve_data() возвращает 0 в случае сбоя, или, может быть, вы изменили свою логику?   -  person John Bollinger    schedule 09.12.2017
comment
Кроме того, каждая из ваших функций store_data() и retrieve_data() принимает дескриптор файла в качестве аргумента. Если эти функции на самом деле используют их для чтения/записи, то что вы получите, дублируя концы канала на стандартные потоки вместо того, чтобы просто использовать концы канала напрямую?   -  person John Bollinger    schedule 09.12.2017
comment
Код возврата 0 означает, что функции выполнены успешно. Я просто предположил, что дублировать трубу было хорошей практикой.   -  person Alexander Leitner    schedule 09.12.2017
comment
Итак, если эти функции возвращают 0 в случае успеха, то вы действительно изменили логику относительно того, вызывают ли они return status или perror().   -  person John Bollinger    schedule 09.12.2017
comment
Что касается дублирования концов труб, то лучше избегать лишних операций. Дублирование концов канала является стандартной практикой, когда вы программно перенаправляете в стандартные потоки программы, но это обычно сопровождается exec использованием другой программы. Вам это, похоже, не нужно.   -  person John Bollinger    schedule 09.12.2017
comment
Понял, что у меня опечатка. Я обновил код, и это результаты работы с операторами печати. Hash: 04a672a6eae704366c44d666890e43ad16bad2b9 1 1a 2 3 4 2a 3a 1b 2b 3b 4a после 4а приложение зависает   -  person Alexander Leitner    schedule 09.12.2017
comment
Это разумная техника отладки. Я уверен, что вам не нужно, чтобы я говорил вам, что это, похоже, указывает на то, что ваша функция store_data() не возвращается. В моем хрустальном шаре я вижу, как store_data() выполняет по крайней мере одно чтение из стандартного ввода вместо указанного файлового дескриптора, но в наши дни это довольно туманно. Больше похоже на снежный шар, правда.   -  person John Bollinger    schedule 09.12.2017
comment
Похоже, sqlite в какой-то момент получает ошибку ioerror, а затем зацикливается, снова и снова выдавая ошибку неправильного использования. классическая функциональность базы данных. Я думаю, что store_data и read_data пытаются одновременно получить доступ к sqlite   -  person Alexander Leitner    schedule 09.12.2017
comment
Странно, что эта проблема возникает, когда я использую конвейер в своем коде, но теперь, когда я передаю вывод одной функции в другую через командную строку   -  person Alexander Leitner    schedule 09.12.2017