I want to map a pid_t returned by wait
or waitpid
to a struct of pipe file descriptors.
In the example below I do that with linear search. Is there better way to do that without a linear search or even a hash table? Using a function provided by UNIX or by approaching the problem a different way?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <sys/wait.h>
#define READ_END 0
#define WRITE_END 1
typedef struct {
pid_t pid;
int fd_stdout[2];
int fd_stdin[2];
int fd_stderr[2];
char *temp;
} Proc;
Proc fork_exec(char *file);
int main(int argc, char **argv) {
char *files[] = {
"A", "B", "C", "D",
"E", "F", "G", "H",
"I", "J", "K"
// ...
};
const int num_files = sizeof(files) / sizeof(char *);
const int process_count = 4;
Proc procs[process_count];
int file_index = 0;
for (int i = 0; i < process_count && i < num_files; i++, file_index++) {
procs[i] = fork_exec(files[i]);
}
for (; file_index < num_files; file_index++) {
int status = 0;
pid_t pid = waitpid(-1, &status, 0);
/* !!! \/ How do I avoid this? \/ !!! */
int index = -1;
for (int i = 0; i < process_count; i++) {
if (procs[i].pid == pid) {
index = i;
break;
}
}
/* !!! ^ How do I avoid this? ^ !!! */
assert(index != -1);
printf("Done with %s\n", procs[index].temp);
procs[index] = fork_exec(files[file_index]);
}
for (int j = 0; j < 4; j++) {
int status = 0;
pid_t pid = waitpid(-1, &status, 0);
/* !!! \/ How do I avoid this? \/ !!! */
int index = -1;
for (int i = 0; i < process_count; i++) {
if (procs[i].pid == pid) {
index = i;
break;
}
}
/* !!! ^ How do I avoid this? ^ !!! */
assert(index != -1);
printf("Done with %s\n", procs[index].temp);
}
}
Proc fork_exec(char *file) {
Proc p = { 0 };
assert(pipe(p.fd_stdin) != -1);
assert(pipe(p.fd_stdout) != -1);
assert(pipe(p.fd_stderr) != -1);
pid_t pid = fork();
assert(pid != -1);
if (pid == 0) {
close(p.fd_stdin[WRITE_END]);
close(p.fd_stdout[READ_END]);
close(p.fd_stderr[READ_END]);
dup2(p.fd_stdin[READ_END], STDIN_FILENO);
dup2(p.fd_stdout[WRITE_END], STDOUT_FILENO);
dup2(p.fd_stderr[WRITE_END], STDERR_FILENO);
close(p.fd_stdin[READ_END]);
close(p.fd_stdout[WRITE_END]);
close(p.fd_stderr[WRITE_END]);
execl("sha256sum", "sha256sum", file);
}
close(p.fd_stdin[READ_END]);
close(p.fd_stdout[WRITE_END]);
close(p.fd_stderr[WRITE_END]);
p.pid = pid;
p.temp = file;
return p;
}