Skip to content

Instantly share code, notes, and snippets.

@leyyce
Created February 7, 2025 00:13
Show Gist options
  • Save leyyce/625be2e90afbc1df3b9e88fc936f0e85 to your computer and use it in GitHub Desktop.
Save leyyce/625be2e90afbc1df3b9e88fc936f0e85 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#include <sys/select.h>
#define NUM_JOBS 3
#define BUFFER_SIZE 1024
const char *jobs[NUM_JOBS] = {
"date",
"uptime",
"echo 'Hello from child!'"
};
void child_process(int write_fd, const char *command) {
char buffer[BUFFER_SIZE];
FILE *fp;
// Continuous execution loop
while (1) {
// Execute command and open pipe to read its output
fp = popen(command, "r");
if (fp == NULL) {
snprintf(buffer, BUFFER_SIZE, "Error executing command: %s\n", strerror(errno));
write(write_fd, buffer, strlen(buffer));
exit(EXIT_FAILURE);
}
// Read command output and send to parent
while (fgets(buffer, BUFFER_SIZE, fp) != NULL) {
write(write_fd, buffer, strlen(buffer));
}
pclose(fp);
// sleep(1); // Delay for demonstration; adjust as needed
}
}
int main() {
int pipes[NUM_JOBS][2];
pid_t pids[NUM_JOBS];
for (int i = 0; i < NUM_JOBS; i++) {
if (pipe(pipes[i]) == -1) {
perror("pipe failed");
exit(EXIT_FAILURE);
}
pids[i] = fork();
if (pids[i] < 0) {
perror("fork failed");
exit(EXIT_FAILURE);
}
if (pids[i] == 0) { // Child process
close(pipes[i][0]); // Close read end in child
child_process(pipes[i][1], jobs[i]);
close(pipes[i][1]);
exit(EXIT_SUCCESS);
} else { // Parent process
close(pipes[i][1]); // Close write end in parent
}
}
// Parent collects output
fd_set read_fds;
char buffer[BUFFER_SIZE];
while (1) {
FD_ZERO(&read_fds);
for (int i = 0; i < NUM_JOBS; i++) {
FD_SET(pipes[i][0], &read_fds);
}
// Wait for any child output
if (select(FD_SETSIZE, &read_fds, NULL, NULL, NULL) == -1) {
perror("select failed");
exit(EXIT_FAILURE);
}
// Read from ready pipes
for (int i = 0; i < NUM_JOBS; i++) {
if (FD_ISSET(pipes[i][0], &read_fds)) {
ssize_t bytes_read = read(pipes[i][0], buffer, BUFFER_SIZE - 1);
if (bytes_read > 0) {
buffer[bytes_read] = '\0';
printf("Output from job %d (%s):\n%s", i, jobs[i], buffer);
}
}
}
}
// Should not reach here as children run infinitely
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment