#!/bin/zsh

set -e -u
zmodload zsh/zselect

fanin() {
  typeset line=""
  read -r line <&$1 && echo "$line"
}

fanout() {
  typeset wIn=() wOut=() fds=() line="" i="" o=""
  nworkers=$1
  workercmd=$2

  for ix in `seq 1 ${nworkers}`; do
    coproc ${workercmd}
    exec {i}>&p {o}<&p
    coproc exit
    wIn+=($i)
    wOut+=($o)
  done

  while read -r line; do
    zselect -r ${wOut[@]} -w ${wIn[@]} -A fds
    for i in "${(@k)fds}"; do
      case "${fds[$i]}" in
        w) if [ ! -z ${line+x} ]; then
            echo "$line" >&$i
            unset line
           fi ;;
        r) fanin $i ;;
      esac
    done
  done

  for i in ${wIn[@]}; do
    exec {i}>&-
  done

  for o in ${wOut[@]}; do
    while read -r line <&$o; do echo "$line"; done
  done
}

fanout "$@"
