aboutsummaryrefslogtreecommitdiff
path: root/sys/mtio/mtopen.x
diff options
context:
space:
mode:
Diffstat (limited to 'sys/mtio/mtopen.x')
-rw-r--r--sys/mtio/mtopen.x188
1 files changed, 188 insertions, 0 deletions
diff --git a/sys/mtio/mtopen.x b/sys/mtio/mtopen.x
new file mode 100644
index 00000000..fc5d6c4f
--- /dev/null
+++ b/sys/mtio/mtopen.x
@@ -0,0 +1,188 @@
+# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+
+include <knet.h>
+include <config.h>
+include <syserr.h>
+include <fset.h>
+include <mach.h>
+include "mtio.h"
+
+# MTOPEN -- Open a magtape file, or a regular binary file if the file name is
+# not "mt" prefixed. Access modes are restricted to read_only, write_only,
+# append, and new_tape. The buffer size argument specifies the size of the
+# FIO buffer used to access the tape; a system and device dependent default
+# is supplied if the buffer size is given as zero. If the device is a fixed
+# block size device the buffer size will be adjusted to an integral multiple
+# of the device block size. For variable size record devices, the buffer size
+# determines the size of the tape record on a write, or the maximum record
+# size on a read.
+#
+# The device to be accessed is specified as follows:
+#
+# [node!] mtX [ '[' file[.record] [:attr-list] ']' ]
+#
+# for example,
+#
+# mtexb1[4:nb:se@:ts=1200:so=/dev/ttya8]
+#
+# The "mt" prefix is required for the object to be considered a magtape device
+# reference. The device name returned is "mtX" as shown above; there must be
+# an entry for device mtX in the tapecap file in DEV.
+#
+# The file and record numbers are optional. Files and records are numbered
+# starting with 1. A sequence such as "mtX[eot]" will cause the tape to be
+# positioned to end of tape. "mtX[0]" causes the tape to be opened at the
+# current position, i.e., without being moved.
+#
+# The optional attr-list field consists of a sequence of colon-delimited
+# tapecap fields. These will override any values given in the tapecap entry
+# for the device. The syntax for attr-list is the same as in tapecap.
+#
+# If the filespec does not have the prefix "mt", we assume that the file is
+# a regular binary file and try to open that. If a tape file is specified
+# then the drive must be allocated before we are called. We allocate and
+# initialize an MTIO file descriptor and call FOPNBF to install the magtape
+# device in FIO and open the device/file.
+
+int procedure mtopen (mtname, acmode, bufsize)
+
+char mtname[ARB] #I device to be opened
+int acmode #I access mode
+int bufsize #I fio buffer size (record size) or 0
+
+bool first_time
+pointer sp, devcap, fname, gty
+int mt, fd, nskip, new_file, new_record
+
+bool streq()
+pointer mt_gtyopen(), gtycaps()
+int open(), fopnbf(), gtygets(), access()
+int mt_skip_record(), mtfile(), mt_devallocated()
+extern zopnmt(), zardmt(), zawrmt(), zawtmt(), zsttmt(), zclsmt()
+
+errchk open, fopnbf, fseti, syserrs, mtparse
+errchk mt_getpos, mt_skip_record, mt_gtyopen, gtygets, mt_glock, mtallocate
+data first_time /true/
+include "mtio.com"
+
+begin
+ call smark (sp)
+ call salloc (fname, SZ_PATHNAME, TY_CHAR)
+ call salloc (devcap, SZ_DEVCAP, TY_CHAR)
+
+ # Runtime initialization of the mtio file descriptor common.
+ # Make each file descriptor available for use.
+
+ if (first_time) {
+ call mt_clrcache()
+ do mt = 1, MT_MAXTAPES
+ MT_OSCHAN(mt) = NULL
+ first_time = false
+ }
+
+ # If regular binary file, we are done.
+ if (mtfile(mtname) == NO) {
+ call sfree (sp)
+ return (open (mtname, acmode, BINARY_FILE))
+ }
+
+ # Get mtio file descriptor slot, but do not allocate it until
+ # we are ready to open the file.
+
+ for (mt=1; mt <= MT_MAXTAPES && MT_OSCHAN(mt) != NULL; mt=mt+1)
+ ;
+ if (mt > MT_MAXTAPES)
+ call syserrs (SYS_MTMULTOPEN, mtname)
+
+ # Break mtname into drive name, file and record number, etc.
+ call mtparse (mtname, MT_DEVICE(mt), SZ_DEVICE,
+ new_file, new_record, Memc[devcap], SZ_DEVCAP)
+ if (new_record == ERR)
+ new_record = 1
+
+ # Get tapecap info.
+ gty = mt_gtyopen (MT_DEVICE(mt), Memc[devcap])
+ MT_DEVCAP(mt) = gtycaps (gty)
+ if (gtygets (gty, "dv", MT_IODEV(mt), SZ_IODEV) <= 0) {
+ call eprintf ("missing `dv' parameter in tapecap entry for %s\n")
+ call pargstr (mtname)
+ call syserrs (SYS_MTTAPECAP, mtname)
+ }
+ call ki_xnode (MT_DEVICE(mt), MT_IODEV(mt), SZ_IODEV)
+
+ # If the device has not been allocated, at least write out the
+ # lock file. This will not physically allocate the device, but
+ # the lock file is required to be able to access the device.
+
+ call mt_glock (mtname, MT_LKNAME(mt), SZ_LKNAME)
+ if (mt_devallocated (MT_IODEV(mt)) == NO)
+ if (access (MT_LKNAME(mt), 0,0) == NO)
+ call mtallocate (mtname)
+
+ # Get current tape position.
+ call mt_getpos (mtname, mt)
+
+ MT_FILE(mt) = new_file
+ MT_RECORD(mt) = new_record
+ MT_ATEOF(mt) = NO
+
+ # If tape is opened for writing but no file number is given, default
+ # to EOT. Defaulting to current file or BOT could result in
+ # destruction of the tape. Note that this default WILL RESULT IN TAPE
+ # RUNAWAY if used on a blank tape. Blank tapes must be explicitly
+ # written at file [1], or opened with access mode NEW_TAPE.
+
+ if ((acmode == WRITE_ONLY && MT_FILE(mt) == -1) || (acmode == APPEND)) {
+ MT_FILE(mt) = EOT
+ MT_RECORD(mt) = 1
+ } else if (acmode == NEW_TAPE) {
+ MT_FILE(mt) = 1
+ MT_RECORD(mt) = 1
+ }
+
+ # Make sure that we are not reopening a drive which is already open.
+ for (fd=1; fd <= MT_MAXTAPES; fd=fd+1)
+ if (fd != mt && MT_OSCHAN(fd) != NULL)
+ if (streq (MT_DEVICE(fd), MT_DEVICE(mt)))
+ call syserrs (SYS_MTMULTOPEN, mtname)
+
+ # Initialize the remaining fields in the file descriptor and open the
+ # device. ZOPNMT will position the tape. Note that we pass the index
+ # of the new mtio descriptor slot to ZOPNMT in the common. This is a
+ # bit ugly, but is safe enough, since we know that FOPNBF is going to
+ # call ZOPNMT.
+
+ switch (acmode) {
+ case READ_ONLY:
+ MT_ACMODE(mt) = READ_ONLY
+ case WRITE_ONLY, APPEND, NEW_TAPE:
+ MT_ACMODE(mt) = WRITE_ONLY
+ default:
+ call syserrs (SYS_MTACMODE, mtname)
+ }
+
+ new_mtchan = mt
+ fd = fopnbf (MT_IODEV(mt), acmode,
+ zopnmt, zardmt, zawrmt, zawtmt, zsttmt, zclsmt)
+
+ # Set the file buffer size (record size for variable block devices).
+ if (bufsize > 0)
+ call fseti (fd, F_BUFSIZE, bufsize)
+
+ # If the user specified a record offset, skip records up to there.
+ # Zero means leave positioned to old record.
+
+ if (MT_RECORD(mt) == 0)
+ MT_RECORD(mt) = MT_RECNO(mt)
+ if (MT_RECORD(mt) > 1) {
+ nskip = MT_RECORD(mt) - 1
+ MT_RECORD(mt) = 1
+ if (mt_skip_record (fd, nskip) != nskip)
+ call syserrs (SYS_MTSKIPREC, mtname)
+ }
+
+ call mt_savepos (mt)
+
+ call sfree (sp)
+ return (fd)
+end