# open --- open a file for reading and/or writing filedes function open (path, mode, ftype, delay) character path (ARB) integer mode, ftype, delay include SWT_COMMON integer fd, f, i, j integer dopen$, lopen$, mapdn, strbsr, expand, getfd$ character dev_name (30), epath (MAXPATH) string_table dev_pos, dev_tab, / 1, ERRIN, "errin" _ / 1, ERROUT, "errout" _ / 4, 0, "lps" _ / 2, 0, "null" _ / 1, STDIN, "stdin" _ / 1, STDIN1, "stdin1" _ / 1, STDIN2, "stdin2" _ / 1, STDIN3, "stdin3" _ / 1, STDOUT, "stdout" _ / 1, STDOUT1, "stdout1" _ / 1, STDOUT2, "stdout2" _ / 1, STDOUT3, "stdout3" _ / 3, 0, "tty" procedure creturn (val) forward # Find an empty descriptor if (getfd$ (fd) == ERR) return (ERR) f = fd_offset (fd) call break$ (DISABLE) # Initialize the descriptor (except device type) Fd_bufstart (f) = fd * BUFSIZE - BUFSIZE Fd_buflen (f) = BUFSIZE Fd_bufend (f) = 0 Fd_count (f) = 0 Fd_bcount (f) = 0 select (and (mode, 3)) # look only at 2 low-order bits when (READ) Fd_flags (f) = FD_READ when (WRITE) Fd_flags (f) = FD_WRITE when (READWRITE) Fd_flags (f) = FD_READ + FD_WRITE else creturn (ERR) Fd_flags (f) |= FD_OPENED + FD_INITIAL # Expand the templates in the name: if (expand (path, epath, MAXPATH) == ERR) creturn (ERR) # Select the device type: i = 1 SKIPBL (epath, i) # Is it a disk file? if ( epath (i + 0) ~= '/'c || mapdn (epath (i + 1)) ~= 'd'c || mapdn (epath (i + 2)) ~= 'e'c || mapdn (epath (i + 3)) ~= 'v'c || epath (i + 4) ~= '/'c) { Fd_dev (f) = DEV_DSK creturn (dopen$ (path, fd, mode, ftype, delay)) } # It must be a device file i += 5 # skip past "/dev/" for (j = 1; epath (i) ~= EOS && epath (i) ~= '/'c && epath (i) ~= ' 'c; {j += 1; i += 1}) dev_name (j) = mapdn (epath (i)) dev_name (j) = EOS # Look up the device j = strbsr (dev_pos, dev_tab, 2, dev_name) if (j == EOF) creturn (ERR) select (dev_tab (dev_pos (j))) when (1) { Fd_flags (f) = 0 # give back the file descriptor creturn (dev_tab (dev_pos (j) + 1)) # return the standard port } when (2) { Fd_dev (f) = DEV_NULL creturn (fd) } when (3) { Fd_dev (f) = DEV_TTY creturn (fd) } when (4) { Fd_dev (f) = DEV_DSK creturn (lopen$ (epath (i), fd, mode)) } Fd_flags (f) = 0 call break$ (ENABLE) return (ERR) # error in table # creturn --- deallocate file descriptor if returning error status procedure creturn (val) { integer val if (val == ERR) Fd_flags (f) = 0 call break$ (ENABLE) return (val) } end