diff options
Diffstat (limited to '9harness/zmxify')
| -rwxr-xr-x | 9harness/zmxify | 176 |
1 files changed, 0 insertions, 176 deletions
diff --git a/9harness/zmxify b/9harness/zmxify deleted file mode 100755 index 5512ffa..0000000 --- a/9harness/zmxify +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/lib/plan9/bin/rc -# zmxify - move a live harness session into a zmx session -# -# Lists the agents 9harness serves under /active, offers them to fzf, and -# writes the chosen zmx session name into that agent's `zmx` file. The -# daemon does the rest: it kills the harness and re-execs it under zmx -# with its session resumed. -# -# usage: zmxify [-n] [dir] -# dir only agents running there; all of them if omitted -# -n print the plan, write nothing -# -# This is the whole script now. Everything it used to work out for -# itself - which processes are harnesses, which stored session each one -# is writing, whether it already lives in zmx, and how to resume it - -# is a file under /active, resolved by the daemon and covered by its -# tests. Nothing here parses /proc, opens an fd table or queries a -# database, and nothing here kills anything: a name written into `zmx` -# is refused unless the session behind it was resolved first, so a move -# always has somewhere to come back to. - -path=(/usr/bin /bin $path) - -nl=' -' -tab=' ' -dry=() -here=() - -if(~ $1 -n){ - dry=y - shift -} -if(! ~ $#* 0){ - here=`$nl {readlink -f $1} - if(~ $#here 0 || ! test -d $here){ - echo 'zmxify: '^$1^': not a directory' >[1=2] - exit dir - } - shift -} -if(! ~ $#* 0){ - echo 'usage: zmxify [-n] [dir]' >[1=2] - exit usage -} - -mnt=$NINE_MOUNT -if(~ $#mnt 0) - mnt=/mnt/9p -act=$mnt/harness/active -if(! test -d $act){ - echo 'zmxify: no harness fs at '^$act >[1=2] - echo ' start it with: zmx run harness -d 9harness --allow-move' >[1=2] - echo ' and run this inside a 9ns mount (an interactive fish already is)' >[1=2] - exit nofs -} - -# A field that is absent (the harness does not publish it) and one that -# is present but empty (`zmx` on an agent outside zmx) both answer `-`: -# a null list would blow up the concatenations below. -fn field { # field dir name: its contents, or - - fv=() - if(test -e $1/$2) - fv=`$nl {cat $1/$2 >[2]/dev/null} - if(~ $#fv 0) - fv=- - echo $fv -} - -# An agent already under zmx has nowhere to go: that is what this moves -# things into. Its own session is *not* excluded - moving the terminal -# you typed this into is the common case, and it is safe, because the -# daemon does the killing and the re-exec. This script only has to get -# the write out; it may die the instant after, and the move still lands. -# Ancestry is worked out only to know whether we will survive to attach. -fn ancestry { # ancestry pid: it and every parent of it - aup=$1 - while(! ~ $aup 0 1){ - echo $aup - aup=`{sed -n 's/^PPid:[ ]*//p' /proc/$aup/status >[2]/dev/null} - if(~ $#aup 0) - aup=0 - } -} -mine=`$nl {ancestry $pid} - -lines=() -for(h in `{ls $act >[2]/dev/null}){ - for(d in `{ls $act/$h >[2]/dev/null}){ - a=$act/$h/$d - acwd=`$nl {field $a cwd} - asess=`$nl {field $a session} - azmx=`{field $a zmx} - take=() - if(~ $#here 0 || ~ $acwd $here) - take=y - # Already under zmx: there is nothing to move it into. - if(! ~ $azmx -) - take=() - # Its session did not resolve, so the daemon would refuse - # the write; offering it would only produce an error. - if(~ $asess -) - take=() - if(! ~ $#take 0){ - short=$acwd - if(! ~ $#home 0) - short=`$nl {echo -n $acwd | sed 's,^'^$home^',~,'} - avia=`{field $a via} - atitle=`$nl {field $a title} - lines=($lines $d^$tab^$h^$tab^$short^$tab^'via='^$avia^$tab^$asess^$tab^$"atitle) - } - } -} - -scope=(all directories) -if(! ~ $#here 0) - scope=$here -if(~ $#lines 0){ - echo 'zmxify: no movable harness session in '^$"scope >[1=2] - exit 0 -} - -fzfopts=(--no-multi --reverse --height=40% --delimiter=$tab --prompt='zmxify ' --header='move under zmx ['^$"scope^']'^$nl^'pid harness dir via session title') -sel=`$nl {{for(l in $lines) echo $l} | fzf $fzfopts} -if(~ $#sel 0){ - echo 'zmxify: nothing picked' >[1=2] - exit 0 -} - -pick=`{echo $sel | awk '{print $1}'} -harness=`{echo $sel | awk -F$tab '{print $2}'} -a=$act/$harness/$pick -if(! test -d $a){ - echo 'zmxify: '^$harness^' pid '^$pick^' is gone' >[1=2] - exit gone -} -pickcwd=`$nl {field $a cwd} - -# A zmx session name nobody is using yet. zmx posts every session into -# the registry, so the registry is what says which names are taken. -zbase=`{basename $pickcwd | tr -c 'A-Za-z0-9'^$nl -} -if(~ $#zbase 0) - zbase=session -zname=$harness^-^$zbase -reg=$XDG_RUNTIME_DIR^/9p/zmx -if(~ $#XDG_RUNTIME_DIR 0) - reg=/run/user/^`{id -u}^/9p/zmx -n=() -while(test -e $reg/$zname){ - n=($n x) - zname=$harness^-^$zbase^-^$#n -} - -if(! ~ $#dry 0){ - echo 'move ' $harness 'pid' $pick 'in' $pickcwd - echo 'session' `{field $a via} `{field $a session} - echo 'write ' $zname '>' $a/zmx - echo 'then ' zmx attach $zname - exit 0 -} - -echo 'zmxify: moving' $harness 'pid' $pick 'into zmx session' $zname -# Moving something we hang off means this shell goes with it. Say the -# attach line first, because there may be no `we` left to say it after. -if(~ $pick $mine) - echo 'zmxify: that is this terminal; it will drop. reattach with: zmx attach '^$zname -# The write returns when the new session is up, or fails having changed -# nothing it could avoid changing. The daemon owns the kill and the -# re-exec, so the move lands even if this process dies mid-write. -if(! echo $zname > $a/zmx){ - echo 'zmxify: the move was refused' >[1=2] - exit move -} -if(~ $pick $mine) - exit 0 -exec zmx attach $zname |
