From Lousy Baboon, 3 Months ago, written in Plain Text.
  1. #!/bin/bash
  2. # desc: link a pipe to an unique file. Preferebly something like ~/tmp/bash/
  3. # usage: mite PIPE SINKDIR [TAG]
  4. # signals: USR1    reset id
  5. #          USR2    send USR1 and WINCH
  6. #          WINCH   dump sink to tty device[1]
  7.  
  8. set -x
  9. genid(){
  10.   local tag
  11.   tag="$1"
  12.   printf -- "%s:%s:%s:%s" "$tag" "$(date +%s)" "$$" "$(mktemp -u XXXXXX)"
  13. }
  14.  
  15. mksink(){
  16.   local s
  17.   s="$1"
  18.   touch "$s"
  19.   printf -- "%s" "$s"
  20. }
  21.  
  22. mkpipe(){
  23.   local p
  24.   p="$1"
  25.   rm "$p" 2<&-
  26.   mkfifo "$p"
  27.   printf -- "%s" "$p"
  28. }
  29.  
  30. mkhole(){
  31.   local i o
  32.   i="$1" o="$2"
  33.   SINK="$(mksink "$o")"
  34.   PIPE="$(mkpipe "$i")"
  35.   exec 7<>"$PIPE"
  36. }
  37.  
  38. mksiphon(){
  39.   local m s
  40.   s="$1"
  41.   m="$(cat <<<$'
  42.     #include <stdio.h>\x0a#include <unistd.h>\x0a#include <signal.h>\x0a#include <poll.h>
  43.     int main(){ char buf[BUFSIZ]; int nb, ret; struct pollfd fd;
  44.       fd.fd = (long)stdin; fd.events = POLLIN;
  45.       while((ret = poll(&fd, 1, 500))>0) {
  46.         switch (ret) {
  47.             case -1: break;
  48.             case 0: break; // timeout
  49.             default: nb=read(0, buf, BUFSIZ);
  50.                      write(1, buf, nb);
  51.       }break;}return 0;}
  52.   ')"
  53.  
  54.   #m="$(cat <<<"
  55.   #  #include <stdio.h>
  56.   #  #include <unistd.h>
  57.   #  int main(){ char buf[BUFSIZ]; int nb;
  58.   #  while((nb=read(0, buf, BUFSIZ))>0){
  59.   #    write(1, buf, nb);}
  60.   #  return 0;}")"
  61.  
  62.   cc -xc -o /dev/fd/1 - <<<"$m" >"$s"
  63.   chmod +x "$s"
  64.   printf -- "%s" "$s"
  65. }
  66.  
  67. bilge(){
  68.   # desc: spray contents of the $sink at calling tty
  69.   # usage: bilge <FILE>
  70.   # note: nasty hack with xdotool and xprop
  71.   local tty bucket
  72.   bucket="$1"
  73.   read -r tty < <(xprop -id "$(xdotool getactivewindow)" PTS)
  74.   eval tty=\"${tty##*= }\"
  75.   printf -- "%s\n%s\n" "$bucket" "$(< "$bucket")" >"$tty"
  76. }
  77.  
  78. # mite PIPE SINKDIR [TAG]
  79. declare -g PIPE SINK SIPHON TAG
  80. [[ -n "$1" ]] || bail "E!: missing argument 1, pipe name"
  81. [[ -d "$2" ]] || bail "E!: not a directory '$2'"
  82. [[ -n "$3" ]] || wmsg "W!: no tag specified. defaulting to 'out'"
  83. TAG="${3:-out}"
  84. PIPE="$(mkpipe "$1")"
  85. SINK="$(mksink "${2%/}/$(genid "$TAG")")"
  86. SIPHON="${XDG_RUNTIME_DIR:-$HOME/.cache}/${SINK##*/}"
  87. #ulimit -S -f 67108864 # 256mb limit
  88. trap 'rm "$SIPHON" 2<&-; exit' INT EXIT
  89. trap 'exec 7<&-; mkhole "$PIPE" "$SINK"' PIPE
  90. trap 'exec 7<&-; mkhole "$PIPE" "${2%/}/$(genid "$TAG")"' USR1
  91. trap 'bilge "$SINK"' USR2
  92. #trap 'bilge "$SINK" && exec 7<&- && mkhole "$SINK" "${2%/}/$(genid "$TAG")"' USR2
  93.  
  94.  
  95. eval "sip(){ "$(mksiphon "$SIPHON")";}"
  96. mkhole "$PIPE" "$SINK"
  97.  
  98. while :; do
  99.   [[ ! -p "$PIPE" ]] && kill -13 $$ && continue
  100.   [[ ! -r "$SINK" ]] && kill -13 $$ && continue
  101.  
  102.   sip <&7 >>"$SINK"
  103. done
captcha