Здравствуйте. Столкнулся со следующей проблемой.
Существует родительский процесс выполнения программы по бэкапу информации на флешку. Он должен создавать два дочерних процесса по архивирования и шифрованию данных, отобранных в других модулях программы, не создавая промежуточных файлов. Т.е. желаемая схема: родитель пишет через пайп на stdin gzip'а, stdout gzip'а связан пайпом с stdin'ом OpenSSL'а, который уже пишет в конечный файл.
Модуль, создающий дочерний процесс с перенаправлением stdin и stdout
pid_t exec_redirect(const char *path, char *const args[], int& wr_fd, int rd_fd)
{
int in[2] = {0};
// для возможности передачи модулю готового пайпа
if (wr_fd == 0)
{
pipe(in);
}
const pid_t child = fork();
if (child == 0)
{
// потомок читает со входа и пишет на выход
close(in[1]);
// для возможности передачи уже готового пайпа
if (wr_fd == 0)
{
dup2(in[0], STDIN_FILENO);
}
else
{
dup2(wr_fd, STDIN_FILENO);
}
dup2(rd_fd, STDOUT_FILENO);
execv(path, args);
perror("execv");
exit(0);
}
else
{
// в родителе закрываем чтобы не терять ф.деск.
close(in[0]);
}
if (wr_fd == 0)
{
// родитель должен записать данные на вход
// т.е. у родителя должен быть in[1]
wr_fd = in[1]; // вход на запись в родителе
}
return child;
}
Модуль, вызывающий и связывающий эти два процесса.
FILE* redirect(char* out_fname)
{
int arch_enc[2] = {0};
pipe(arch_enc);
int out = open(out_fname, O_WRONLY | O_APPEND);
int in = 0;
puts("IO redirect started");
const char *cmd = "/bin/gzip";
char *const args[] = {"/bin/gzip", "gzip", "-f", "-", NULL};
exec_redirect(cmd, args, in, arch_enc[1]);
const char *cmd2 = "/usr/bin/openssl";
char *const args2[] = {"/usr/bin/openssl" ,"enc", "-blowfish", "-pass", ENC_PASS, NULL};
exec_redirect(cmd2, args2, arch_enc[0], out);
FILE* stream = fdopen(in, "w");
if (stream == NULL)
{
perror("fdopen");
return NULL;
}
return stream;
}
В результате выполнения такого кода оба процесса создаются, но данных на выходе нет, и процессы висят, пока им не сделать kill. Стало интересно, где я ошибся. Под отладчиком видно, что номера ф.д. не портятся, т.е. ошибка где-то в логике. Буду очень рад и благодарен, если кто-нибудь подскажет.