n *.KB H writev fd 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 readv r { 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 close close v;n n { `1+Rv{,v loop: xx { Lclose v[n+I1] } (0 $ n { n - 1) / loop split ch { 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 exec exec 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 setin setin fd; t t { Lclose 0 t { Ldup fd t { Lclose fd setout setout fd; t t { Lclose 1 t { Ldup fd t { Lclose fd readall r { readall fd ;t r { '' nxt: r { r,t{ fd Lread 512 }(0#Rt)/nxt t { Lclose fd writeall fd writeall data ;t t { fd Lwrite data t { Lclose fd Llx 3 'type ''describe'' for details' describe this 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'. fd A xx sh sh; 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' evoke ch { evoke process ch { split 1 0 } (0#`1Ych)/0 setin ch[1] setout ch[2] exec process readl r { readl d r { Lrd d writel ch writel data ch Lap data execni execni 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