Общая память на стандартный вывод ничего не выводит в C - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь отправить файл из родительского процесса двум дочерним процессам, а дочерние записи записывают файл в две отдельные общие памяти, после чего родитель будет читать общие памяти и выводить результаты в stdout и stderr. Однако после некоторого запуска моя программа начала не выдавать вывод. буквально ничего не печатается, нет сообщений об ошибках или что-то еще. Я не могу понять, почему.

Я запускаю свой код как:

./myprogram >out.txt 2>out2.txt

Но оба файла пусты.

Вот мой код:

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

#define SHM_NAME_1 "SHM1"
#define SHM_NAME_2 "SHM2"
#define FIFO_1 "FIFO1"
#define FIFO_2 "FIFO2"
#define BUFFER_SIZE 65536 // 64 KB
#define MEM_SIZE 2097152 // 2 MB


void stringtohex(char* input, char* output)
{
    int loop;
    int i; 

    i=0;
    loop=0;

    while(input[loop] != '\0')
    {
        sprintf((char*)(output+i),"%02X", input[loop]);
        loop+=1;
        i+=2;
    }
    //insert NULL at the end of the output string
    output[i++] = '\0';
}

int main(){

    pid_t pid,pid_2;
    FILE *file;
    char *infile = "input.txt";

    pid = fork();

    if(pid < 0){
        fprintf(stderr, "Fork failed\n");
        return 1;
    }

    if(pid > 0){ // parent

        pid_2 = fork();

        if(pid_2 > 0){ // parent

            file = fopen(infile, "r");

            if(file == 0){
                fprintf(stderr, "File failed\n");
                return 1;
            }
            // close read end of pipe
            mknod(FIFO_1, S_IFIFO | 0666, 0);
            mknod(FIFO_2, S_IFIFO | 0666, 0);

            int fd = open(FIFO_1, O_WRONLY);
            int sd = open(FIFO_2, O_WRONLY);

            char str[BUFFER_SIZE];
            while(fgets(str, BUFFER_SIZE, file) > 0)
            {
                // write all lines of file
                write(fd, str, strlen(str));
                write(sd, str, strlen(str));
            }
            // send EOF explicitly
            write(fd, "\0", 1);
            write(sd, "\0", 1);
            // close file and pipes
            close(fd);
            close(sd);
            fclose(file);
            // wait for child to write to shared memory
            wait(NULL);

            // open shared segments
            int shm_first = shm_open(SHM_NAME_1, O_RDONLY, 0666);
            int shm_second = shm_open(SHM_NAME_2, O_RDONLY, 0666);

            if (shm_first == -1 || shm_second == -1) {
                fprintf(stderr, "Failed: Shared Memory 1");
                exit(-1);
            }

            // create memory pointers
            void *ptr = mmap(0,MEM_SIZE, PROT_READ, MAP_SHARED, shm_first, 0);
            void *ptr2 = mmap(0,MEM_SIZE, PROT_READ, MAP_SHARED, shm_second, 0);

            if (ptr == MAP_FAILED || ptr2 == MAP_FAILED) {
                printf("Map failed 1\n");
                return -1;
            }

            // print out results and unlink shared segments
            fprintf(stdout, "Normal ouput: \n%s\n", ptr);
            fprintf(stderr, "Hexadecimal output: \n%s\n", ptr2);

            shm_unlink(SHM_NAME_1);
            shm_unlink(SHM_NAME_2);

        } else {

            int shm_child_2 = shm_open(SHM_NAME_2, O_CREAT | O_RDWR, 0666);

            // configure the size of the shared memory segment 
            ftruncate(shm_child_2,MEM_SIZE);
            // map the pointer to the segment
            void *ptr_child_2 = mmap(0,MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_child_2, 0);

            if (ptr_child_2 == MAP_FAILED) 
            {
                printf("Map failed in second child\n");
                return -1;
            }

            mknod(FIFO_2, S_IFIFO | 0666, 0);
            int fd = open(FIFO_2, O_RDONLY);

            int num;
            char s[BUFFER_SIZE];
            while((num = read(fd, s, BUFFER_SIZE)) > 0)
            {     
                char hex[num*2];
                stringtohex(s, hex);
                sprintf(ptr_child_2, "%s", hex);
                ptr_child_2 += num*2;
            }

            close(fd);
            exit(0);
        }

    } else { // child

        // create the shared segment for the first time
        int shm_child_1 = shm_open(SHM_NAME_1, O_CREAT | O_RDWR, 0666);

        // configure the size of the shared memory segment 
        ftruncate(shm_child_1,MEM_SIZE);
        // map the pointer to the segment
        void *ptr_child_1 = mmap(0,MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_child_1, 0);

        if (ptr_child_1 == MAP_FAILED) 
        {
            printf("Map failed in first child\n");
            return -1;
        }


        mknod(FIFO_1, S_IFIFO | 0666, 0);
        int fd = open(FIFO_1, O_RDONLY);

        int num;
        char s[BUFFER_SIZE];
        while((num = read(fd, s, BUFFER_SIZE)) > 0)
        {     
            sprintf(ptr_child_1, "%s", s);
            ptr_child_1 += num;
        }

        close(fd);
        exit(0);

    }

    return 0;
}
...