Я пытаюсь отправить файл из родительского процесса двум дочерним процессам, а дочерние записи записывают файл в две отдельные общие памяти, после чего родитель будет читать общие памяти и выводить результаты в 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;
}