# make_iport --- make an entry in the input port descriptor table integer function make_iport (node, type, port, path, sopde) integer node, type, port, sopde pointer path include PORT_COMMON integer i i = Next_iport (node) if (i > MAXIPORTS) { call synerr ("too many input ports"p) return (ERR) } Next_iport (node) += 1 Ipd (PD_TYPE, i, node) = type # FROM_SYM, CMDSRC_SYM or PIPESYM Ipd (PD_PORT, i, node) = port # 1:MAXIPORTS; 0 => defaulted Ipd (PD_PATH, i, node) = path # pointer to pathname Ipd (PD_SOPDE, i, node) = sopde # Opd entry for source port of pipe Ipd (PD_FD, i, node) = TTY # fd, changed by 'setup_ports' return (OK) end # make_oport --- make an entry in the output port descriptor table integer function make_oport (node, type, port, path, dport) integer node, type, port, dport pointer path include PORT_COMMON integer i i = Next_oport (node) if (i > MAXOPORTS) { call synerr ("too many output ports"p) return (ERR) } Next_oport (node) += 1 Opd (PD_TYPE, i, node) = type # TOWARD_SYM, APPEND_SYM or PIPE_SYM Opd (PD_PORT, i, node) = port # 1:MAXOPORTS; 0 => defaulted Opd (PD_PATH, i, node) = path # pointer to pathname Opd (PD_DPORT, i, node) = dport # destination port of pipe Opd (PD_FD, i, node) = TTY # fd, changed by 'setup_ports' return (OK) end # init_ports --- initialize port descriptor tables subroutine init_ports include PORT_COMMON integer i do i = 1, MAXNODES; { Next_iport (i) = 1 Next_oport (i) = 1 } return end # clr_ports --- reinitialize port descriptor tables subroutine clr_ports include PORT_COMMON integer i, j do i = 1, MAXNODES; { for (j = 1; j < Next_iport (i); j += 1) if (Ipd (PD_TYPE, j, i) == FROM_SYM) call lsfree (Ipd (PD_PATH, j, i), ALL) Next_iport (i) = 1 for (j = 1; j < Next_oport (i); j += 1) if (Opd (PD_TYPE, j, i) == TOWARD_SYM || Opd (PD_TYPE, j, i) == APPEND_SYM) call lsfree (Opd (PD_PATH, j, i), ALL) Next_oport (i) = 1 } return end # assign_ports --- make port number assignments to defaulted ports integer function assign_ports (status) integer status include PARSE_COMMON integer node integer assign_oports, assign_iports for (node = 1; node <= Curnode; node += 1) if (assign_oports (node) == ERR) { status = ERR return (status) } for (node = 1; node <= Curnode; node += 1) if (assign_iports (node) == ERR) { status = ERR return (status) } status = OK return (status) end # assign_oports --- make output port number assignments integer function assign_oports (node) integer node include PORT_COMMON include PARSE_COMMON include CI_COMMON include EXEC_COMMON integer i, list (MAXOPORTS), port, dnode integer reserve_port, make_iport, select_port call make_portlist (list, MAXOPORTS) ### handle user-specified ports: for (i = 1; i < Next_oport (node); i += 1) if (Opd (PD_PORT, i, node) ~= 0) # non-defaulted port no. if (reserve_port (Opd (PD_PORT, i, node), list, MAXOPORTS) == ERR) return (ERR) ### handle defaulted ports: for (i = 1; i < Next_oport (node); i += 1) { if (Opd (PD_PORT, i, node) == 0) { # defaulted port port = select_port (list, MAXOPORTS) if (port == ERR) return (port) Opd (PD_PORT, i, node) = port } if (Opd (PD_TYPE, i, node) == PIPE_SYM) { # make ipd entry for dest if (Opd (PD_DNODE, i, node) > Curnode) { # illegal node call semerr ("pipe destination not found"p) return (ERR) } dnode = Opd (PD_DNODE, i, node) if (make_iport (dnode, PIPE_SYM, Opd (PD_DPORT, i, node), node, i) == ERR) return (ERR) Connect (node, dnode) = 1 # enter in connectivity matrix } } return (OK) end # assign_iports --- make input port number assignments integer function assign_iports (node) integer node include PORT_COMMON integer i, list (MAXIPORTS), port, snode, sopde integer reserve_port, select_port call make_portlist (list, MAXIPORTS) ### handle user-specified ports: for (i = 1; i < Next_iport (node); i += 1) if (Ipd (PD_PORT, i, node) ~= 0) # non-defaulted port if (reserve_port (Ipd (PD_PORT, i, node), list, MAXIPORTS) == ERR) return (ERR) ### handle defaulted pipes from previous nodes: for (i = 1; i < Next_iport (node); i += 1) if (Ipd (PD_TYPE, i, node) == PIPE_SYM && Ipd (PD_PORT, i, node) == 0 && Ipd (PD_SNODE, i, node) < node) { port = select_port (list, MAXIPORTS) if (port == ERR) return (ERR) Ipd (PD_PORT, i, node) = port snode = Ipd (PD_SNODE, i, node) sopde = Ipd (PD_SOPDE, i, node) Opd (PD_DPORT, sopde, snode) = port } ### handle remaining defaulted ports: for (i = 1; i < Next_iport (node); i += 1) if (Ipd (PD_PORT, i, node) == 0) { port = select_port (list, MAXIPORTS) if (port == ERR) return (port) Ipd (PD_PORT, i, node) = port if (Ipd (PD_TYPE, i, node) == PIPE_SYM) { snode = Ipd (PD_SNODE, i, node) sopde = Ipd (PD_SOPDE, i, node) Opd (PD_DPORT, sopde, snode) = port } } return (OK) end # make_portlist --- make a list of all possible i/o ports for a node subroutine make_portlist (list, maxport) integer maxport, list (maxport) integer i do i = 1, maxport list (i) = i return end # reserve_port --- reserve a particular port in a port list integer function reserve_port (portno, list, maxport) integer portno, maxport, list (maxport) if (portno > maxport) { call semerr ("illegal port number"p) reserve_port = ERR } elif (list (portno) == 0) { call semerr ("port referenced more than once"p) reserve_port = ERR } else { list (portno) = 0 reserve_port = OK } return end # select_port --- pick an i/o port to satisfy a default integer function select_port (list, maxport) integer maxport, list (maxport) integer i do i = 1, maxport if (list (i) ~= 0) { select_port = list (i) list (i) = 0 return } call semerr ("too many ports referenced"p) return (ERR) end # setup_ports --- prepare port tables for node execution integer function setup_ports (n) integer n include PORT_COMMON include CI_COMMON include SWT_COMMON integer i, fd, p, sn integer open, create, mktemp character pathname (MAXLINE) setup_ports = ERR do i = 1, MAX_STD_PORTS Std_port_tbl (i) = Default_port_table (i) for (i = 1; i < Next_iport (n); i += 1) { select (Ipd (PD_TYPE, i, n)) when (CMDSRC_SYM) fd = Ci_fd (Ci_file) when (FROM_SYM) { call lsextr (Ipd (PD_PATH, i, n), pathname, MAXLINE) fd = open (pathname, READ) if (fd == ERR) { call putlin (pathname, TTY) call semerr (": can't open"p) return } } when (PIPE_SYM) { p = Ipd (PD_SOPDE, i, n) sn = Ipd (PD_SNODE, i, n) fd = Opd (PD_FD, p, sn) call rewind (fd) } Ipd (PD_FD, i, n) = fd p = 2 * Ipd (PD_PORT, i, n) - 1 # STDINx = 1, 3, 5, ... Std_port_tbl (p) = fd } for (i = 1; i < Next_oport (n); i += 1) { select (Opd (PD_TYPE, i, n)) when (TOWARD_SYM) { call lsextr (Opd (PD_PATH, i, n), pathname, MAXLINE) fd = create (pathname, WRITE) if (fd == ERR) { call putlin (pathname, TTY) call semerr (": can't create"p) return } } when (APPEND_SYM) { call lsextr (Opd (PD_PATH, i, n), pathname, MAXLINE) fd = open (pathname, READWRITE) if (fd == ERR) { call putlin (pathname, TTY) call semerr (": can't open"p) return } call wind (fd) } when (PIPE_SYM) { fd = mktemp (READWRITE) if (fd == ERR) { call semerr ("can't open pipe temporary"p) return } } Opd (PD_FD, i, n) = fd p = 2 * Opd (PD_PORT, i, n) # STDOUTx = 2, 4, 6, . . . Std_port_tbl (p) = fd } return (OK) end # cleanup_ports --- close all ports associated with a node subroutine cleanup_ports (n) integer n include PORT_COMMON include SWT_COMMON integer i for (i = 1; i < Next_iport (n); i += 1) select (Ipd (PD_TYPE, i, n)) when (FROM_SYM) call close (Ipd (PD_FD, i, n)) when (PIPE_SYM) call rmtemp (Ipd (PD_FD, i, n)) for (i = 1; i < Next_oport (n); i += 1) select (Opd (PD_TYPE, i, n)) when (TOWARD_SYM, APPEND_SYM) call close (Opd (PD_FD, i, n)) do i = 1, MAX_STD_PORTS Std_port_tbl (i) = Default_port_table (i) return end # dump_ports --- dump port descriptor tables for debugging subroutine dump_ports (node) integer node include PORT_COMMON include SWT_COMMON integer i, j, p, sn do i = 1, MAX_IPORTS; { call print (TTY, "STDIN*i "p, i) if (Std_port_tbl (2 * i - 1) == TTY) call print (TTY, "TTY "p) else call print (TTY, "*3i "p, Std_port_tbl (2 * i - 1)) for (j = 1; j < Next_iport (node); j += 1) if (Ipd (PD_PORT, j, node) == i) { select (Ipd (PD_TYPE, j, node)) when (CMDSRC_SYM) call print (TTY, "command source*n"p) when (FROM_SYM) { call print (TTY, "from "p) call lsputf (Ipd (PD_PATH, j, node), TTY) call putch (NEWLINE, TTY) } when (PIPE_SYM) { sn = Ipd (PD_SNODE, j, node) p = Ipd (PD_SOPDE, j, node) call print (TTY, "pipe from node *i port *i*n"p, sn, Opd (PD_PORT, p, sn)) } next 2 } call print (TTY, "defaulted*n"p) } do i = 1, MAX_OPORTS; { call print (TTY, "STDOUT*i "p, i) if (Std_port_tbl (2 * i) == TTY) call print (TTY, "TTY "p) else call print (TTY, "*3i "p, Std_port_tbl (2 * i)) for (j = 1; j < Next_oport (node); j += 1) if (Opd (PD_PORT, j, node) == i) { select (Opd (PD_TYPE, j, node)) when (TOWARD_SYM) { call print (TTY, "toward "p) call lsputf (Opd (PD_PATH, j, node), TTY) call putch (NEWLINE, TTY) } when (APPEND_SYM) { call print (TTY, "append to "p) call lsputf (Opd (PD_PATH, j, node), TTY) call putch (NEWLINE, TTY) } when (PIPE_SYM) call print (TTY, "pipe to node *i port *i*n"p, Opd (PD_DNODE, j, node), Opd (PD_DPORT, j, node)) next 2 } call print (TTY, "defaulted*n"p) } return end