From Gracious Giraffe, 3 Months ago, written in Plain Text.
  1. #!/bin/bash
  2. # desc: link a pipe to an unique file in tmpfs, due habits of `foo>./x`, and working in ~/HWD/
  3. # usage: mite
  4. # note: sigusr1 will reset id
  5.  
  6. genid(){
  7.   printf -- "p:%s:%s:%s" "$$" "$(awk 'BEGIN{srand();print srand()}')" "${RANDOM##-}"
  8. }
  9.  
  10. mksink(){
  11.   # TODO: How to feed sink id back through pipe
  12.   # As in `mite& echo abc>./pipe` and after `echo`, sink id is printed...
  13.   local s
  14.   s="$1"
  15.   touch "$s"
  16.   printf -- "%s" "$s"
  17. }
  18.  
  19. mkpipe(){
  20.   local p
  21.   p="$1"
  22.   rm "$p" 2<&-
  23.   mkfifo "$p"
  24.   printf -- "%s" "$p"
  25. }
  26.  
  27. mkhole(){
  28.   set -vx
  29.   local i o
  30.   i="${1:-pipe}" o="${2:-sink}"
  31.   sink="$(mksink "$o")"
  32.   pipe="$(mkpipe "$i")"
  33.   exec 7<>"$pipe"
  34.   rm -f "${i%/*}/o" 2<&-
  35.   ln -s "$o" "${i%/*}/o" # link to sinkfile
  36. }
  37.  
  38. mksiphon(){
  39.   local 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 | POLLOUT;
  45.       while((ret = poll(&fd, 1, 100))>0) {
  46.         switch (ret) {
  47.             case -1: break;
  48.             case 0: sleep("3"); 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.  
  68. declare -g pipe sink siphon
  69. pipe="$(mkpipe ~/HWD/x)"
  70. sink="$(mksink ~/dev/mem/"$(genid)")"
  71. siphon="${XDG_RUNTIME_DIR:-~/.cache}/${sink##*/}"
  72. #ulimit -S -f 67108864 # 256mb limit
  73. trap 'rm "$siphon" 2<&-; exit' INT EXIT
  74. trap 'mkhole "$pipe" "$sink"' PIPE
  75. trap 'mkhole "$pipe" ~/dev/mem/"$(genid)"; printf -- "">&7' USR1
  76.  
  77. eval "sip(){ "$(mksiphon "$siphon")";}"
  78. mkhole "$pipe" "$sink"
  79.  
  80. while :; do
  81.   [[ ! -p "$pipe" ]] && kill -13 $$ && continue
  82.   [[ ! -r "$sink" ]] && kill -13 $$ && continue
  83.  
  84.   sip <&7 >>"$sink"
  85. done
captcha