1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <afblib/outbuf_printf.h>

/* function to be executed by a worker,
   where id is an integer in [0, # workers)
   and fd the writing end of the pipeline */
typedef void (*JobHandler)(unsigned int id, int fd);

typedef struct Worker {
   pid_t pid;
   int fd; /* reading end of the pipeline */
} Worker;

bool spawn_workers(Worker workers[], unsigned int number_of_workers,
      JobHandler handler) {
   /* FIXME */
}

void do_sth(unsigned int id, int fd) {
   outbuf out = {fd};
   outbuf_printf(&out, "Greetings from worker %u!\n", id);
   outbuf_flush(&out);
}

bool copy(int in, int out) {
   char buf[8192];
   ssize_t nbytes;
   while ((nbytes = read(in, buf, sizeof buf)) > 0) {
      ssize_t written = 0;
      while (written < nbytes) {
	 ssize_t count = write(out, buf + written, nbytes - written);
	 if (count <= 0) return false;
	 written += count;
      }
   }
   return nbytes == 0;
}

#define WORKERS (10)

int main() {
   Worker workers[WORKERS];
   if (!spawn_workers(workers, WORKERS, do_sth)) {
      perror("spawn_workers"); exit(1);
   }
   for (unsigned int i = 0; i < WORKERS; ++i) {
      copy(workers[i].fd, 1); close(workers[i].fd);
      int wstat; waitpid(workers[i].pid, &wstat, 0);
   }
}