4.3BSD/usr/contrib/apl/lib/iows

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