n*.KB H writevfd writev x;dumb;shape;rank;type rank { Rshape{Rx type { 'nc'[(1?1) + ' 'E(,0)\0Rx] dumb { fd Lwrite type dumb { fd Lwrite rank,shape dumb { fd Lwrite x readvr { readv fd;type;rank;shape;m CJ change the '8' in line 2 to '4' for apl len { 8 type { (len,1)[(1?1) + 'c' = fd Lread 1] rank { Lfloat fd Lread len shape { Lfloat fd Lread X/len,rank r { '' m { n { X/shape,type next: r { r, fd Lread m } (0 # m { n-Rr)/next } (1=type)/rshape r { Lfloat r rshape: r { shape Rr closeclose v;n n { `1+Rv{,v loop: xx { Lclose v[n+I1] } (0 $ n { n - 1) / loop splitch { split v; t; tl; n n { Rv ch { (n+1)R0 tl { (2,n)R0 i { I1 nxp: tl[;i] { Lpipe 0 } ((n+I1) > i { i + 1) / nxp i { I1 } (0 = ch[n+I1] { Lfork 0) / child parent: v { ~v child: t { Lclose tl[v[i]+I1;i] ch[i] { tl[(~v[i])+I1;i] } ((n+I1) > i { i + 1) / child execexec name; t t { Lexec name { ((2,Rname)Rname),0 t { Lexec ((2,5)R'/bin/'),name t { Lexec ((2,9)R'/usr/bin/'),name t { 2 Lwrite 'exec failed' Lexit 1 setinsetin fd; t t { Lclose 0 t { Ldup fd t { Lclose fd setoutsetout fd; t t { Lclose 1 t { Ldup fd t { Lclose fd readallr { readall fd ;t r { '' nxt: r { r,t{ fd Lread 512 }(0#Rt)/nxt t { Lclose fd writeallfd writeall data ;t t { fd Lwrite data t { Lclose fd Llx3'type ''describe'' for details' describethis workspace contains the following functions which permit the generation of, communication with, and control of independant cooperating processes. these functions are described in 'the application of an apl interpreter to the control of lower-level more efficient processors' by a. p. reeves, accepted by apl79. the following functions are available: split -- fork a child process and set up pipes to it exec -- execute (overlay apl with) another Unix program setin -- change standard input to specified file descriptor setout -- change standard output to specified fd readall -- read everything from fd and close it writeall -- write to specified fd and close it writev -- write apl variable to fd readv -- read apl variable from fd close -- close file(s) readv and writev use a special format which includes the rank and shape of the variable, so the entire nature of a variable written with 'writev' may be recovered using 'readv'. fdAxxshsh; z } (Lfork 1 /= 0) / cont Lexec 2 8 R '/bin/sh',0,'-',7R0 z _ Lexit 1 cont: z _ 3 Lsig 1 z _ Lwait 1 z _ 3 Lsig 0 'Returning to APL now' evokech { evoke process ch { split 1 0 } (0#`1Ych)/0 setin ch[1] setout ch[2] exec process readlr { readl d r { Lrd d writelch writel data ch Lap data execniexecni name; t t { 2 Lsig 1 t { Lexec name { ((2,Rname)Rname),0 t { Lexec ((2,5)R'/bin/'),name t { Lexec ((2,9)R'/usr/bin/'),name t { 2 Lwrite 'exec failed' Lexit 1