REF SYSIO John Gibson Apr 1996
Revised John Gibson Apr 1999
COPYRIGHT University of Sussex 1999. All Rights Reserved.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< DEVICES AND SYSTEM >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< INPUT AND OUTPUT >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< PROCEDURES >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
This file describes the most basic level of input and output facilities
in Poplog, namely input and output via device records. For
character-stream input and output procedures, see REF * CHARIO
CONTENTS - (Use <ENTER> g to access required sections)
1 Introduction
1.1 System vs User Devices
2 Opening System Devices
3 Reading Devices
4 Writing Devices
5 Line Repeaters and Consumers
6 File Control Operations
7 File Information
8 Predicates on Devices
9 Device Information
10 Standard Devices
11 Constructing User Devices
12 Miscellaneous
---------------
1 Introduction
---------------
This file describes the most basic level of input and output facilities
in Poplog, namely input and output via device records. For
character-stream input/output procedures, see REF * CHARIO
System device records are created for files with sysopen or
syscreate (also syspipe in Unix and sysmailbox in VMS). As far as
possible, the device input and output facilities have been designed to
provide a Unix style interface (i.e. the ability to read/write any file
as a stream of bytes), but with extensions where necessary; in
particular, the above device-creating procedures take an additional
argument to their Unix counterparts, which specifies the `organisation'
of the file (and allows compatibility between Unix and VMS Poplog).
(As part of this in Unix Poplog, every device representing a
terminal maintains a full set of terminal parameters which are set on
the terminal whenever that device is used (unless it is already set for
that device). In this way multiple devices with different
characteristics can be made to work for the same underlying terminal,
with automatic switching between different settings as appropriate. See
sys_io_control below for more information.)
Interfaces to operating system I/O calls are provided where
appropriate, wherever possible in a form that can be made compatible
across all Poplog implementations. Various other operating
system-related facilities (e.g. filename processing) are dealt with in
REF * SYSUTIL
In Unix systems, see also REF * SOCKETS, which provides an interface to
the Berkeley Unix socket facilities for network communications.
1.1 System vs User Devices
---------------------------
In addition to the system devices created by sysopen, etc, there is also
a facility for creating user devices (with consdevice). User devices can
specify arbitrary procedures to deal with I/O requests from procedures
like sysread and syswrite applied to them, and can thus be used to
implement simulated I/O channels. (For example, this facility is used in
the Ved editor to allow device I/O on Ved buffers).
Note that in the descriptions that follow, sdev is used to denote a
system device, udev a user device, and dev either kind.
-------------------------
2 Opening System Devices
-------------------------
The procedures sysopen, syscreate, syspipe and sysmailbox described
below all take an argument org to specify the organisation of a file.
This argument can currently take the following values (which are by no
means satisfactory, and will hopefully be improved in the future):
false
For terminals, this gives normal interactive line mode, with prompts
given by popprompt.
For terminals and other Unix 'interactive' devices (such as pipes
and sockets), this value means that a sysread of N bytes will not
attempt to read the full N bytes if less are available, i.e. the
call may return less than N.
For Unix disk files, the full N bytes are read except at
end-of-file.
For VMS disk files and mailboxes, this value means record-oriented
processing, i.e. the file is a sequence of records (lines) each
(possibly) ending with either an explicit newline or implicit one as
specified by the "Implicit C/R" attribute of a file. Newly-created
disk files are given "Implicit C/R" attribute. In reading, the
newlines are inserted by the system where necessary; in writing, a
newline is taken as end of record. The file is then considered (in
Unix fashion) as a byte-stream.
However, VMS terminals and mailboxes behave as for Unix
'interactive' devices, i.e. a sysread of N bytes will not attempt to
read the full N bytes if the current record contains less; for VMS
files, N will be supplied even though a record boundary may be
crossed. (Similarily, one syswrite can actually write the characters
of more than one record at a time.)
the word "line"
For all kinds of device, this value will mean that a sysread of N
bytes from the device will only read up to the next newline
character, e.g. sysread(dev, buff, 512) will read the next line and
return the number of characters read.
In VMS, the characters of adjoining records are never conflated in a
single read or write operation; in other respects, this is the same
as false.
the word "record"
In Unix, this is the same as "line". In VMS however, "record" is
different from "line" in that newlines are not appended to input
records, nor stripped from output records (as with "line", the
characters of adjoining records are never conflated in a single read
or write operation). An output disk file is not created with
`Implicit C/R' attribute.
true
For Unix terminals, the device is initially set up for `rare' mode
(i.e. cbreak, -echo, -nl, -tabs) and no prompt is output for read
operations (see sys_io_control below.). VMS terminals give a similar
mode, i.e. no echoing, no prompts, all characters are `break'
characters, no formatting of output, etc.
For other Unix 'interactive' devices (such as pipes and sockets), a
sysread of N bytes will always attempt to read the full N bytes,
i.e. the call can only return less than N at end-of-file.
For Unix disk files, true is the same as false.
For VMS disk or tape files this implies block I/O, i.e. the bytes
from the virtual blocks of the file are supplied neat, with nothing
added, and there are no record boundaries. Output disk files are
created as fixed-length, 512 byte records.
The following table summarises the intended uses of each org value:
org Use For
--- -------
false Character-stream I/O on 'interactive' devices
(terminals, pipes, sockets, mailboxes), and text
files.
"line" Line I/O on 'interactive' devices and text files.
"record" VMS record I/O on any kind of record-orientated
files (in Unix, same as "line").
true `Raw' mode I/O on terminals; I/O on non-text files
(including block mode in VMS).
Note that all the procedures below which take a filename argument first
translate the given name with sysfileok (see REF * SYSUTIL).
sysopen(filename, access_mode, org) -> sdev [procedure]
sysopen(filename, access_mode, org, err_char) -> sdev
Returns a system device record sdev for the filename (or
operating system device, etc) named by the string filename,
opened for access mode access_mode with organisation org.
Permissible values of access_mode are
0 Read only
1 Write only
2 Read and Write
Permissible values for org are as described above.
The optional err_char argument is an integer character code
specifying whether to return false (as opposed to producing a
mishap) if the file cannot be opened. This can take the
following values:
Value Action
----- ------
`A` Return false for any error concerned with filename
or its existence/accessibility.
`D` Return false for a non-existent directory or file.
`F` Return false if the directory exists, but the file
doesn't. This is the default if err_char is omitted.
`N` Never return false (i.e. mishap for any error).
(Note that for `A`, a mishap can still occur for errors not
concerned directly with filename, e.g. the file can't be opened
because the operating system's limit on the number of open files
has been reached.)
readable(filename) -> sdev [procedure]
This procedure is the same as
sysopen(filename, 0, false, `A`) -> sdev
i.e. filename opened for reading with org argument false (and
false returned for any open errors).
syscreate(filename, access_mode, org) -> sdev [procedure]
syscreate(filename, access_mode, org, err_char) -> sdev
Returns a system device record sdev for filename, created for
access mode access_mode with organisation org. The values of
access_mode and org are as for sysopen. A mishap results if for
any reason the file cannot be created.
The optional err_char argument is an integer character code
allowing special behaviour in one case:
Value Action
----- ------
`F` If the file already exists, treat this as an error
and return false (note the difference between this
and `F` for sysopen). The operation of testing for
the file's presence and creating it if it doesn't
exist is guaranteed to be atomic, i.e. no other O/S
process can create the file in between (`F` is thus
suitable for creating lockfiles).
`N` Never return false -- this is the default if
err_char is omitted.
pop_file_mode -> int [variable]
int -> pop_file_mode
(Unix ONLY) This integer variable supplies the access
permissions mode given to the Unix creat system call by
syscreate. (See chmod(2) in the Unix Programmers Manual for
possible values; the default value is 8:664, i.e. read and write
by owner and group, read only for world.)
Note that this variable is only used by syscreate when creating
a NEW file: if a file exists already, its access permissions are
left unchanged.
pop_file_versions -> int_or_false [variable]
int_or_false -> pop_file_versions
In Unix, this integer variable controls the creation of `back'
file versions by syscreate. Poplog uses a convention that `back'
versions of a disk file are named by suffixing the original file
name with one or more `-` characters (i.e. the most recent back
file of 'foo' is 'foo-', the next most recent is 'foo--', and so
on).
The action of syscreate is therefore to try to maintain
pop_file_versions of a file (e.g. 2 means the original file plus
1 back version, 3 means the original plus 2 back versions, etc).
This is done by 'moving back' all existing versions up to
pop_file_versions, the oldest one being deleted.
The exact operation of 'moving back' a file depends on whether
the file has only 1 link, or more than 1: in the former case the
file is simply renamed as the 'back' name, while in the latter
case (to preserve the links), the file is copied to a new one of
that name.
The procedure sysdelete (see REF * SYSUTIL) also uses this
variable to 'move forward' old versions when deleting a file.
That is, if back versions of the file within the range
pop_file_versions exist, then the above process is reversed to
bring the back versions forward. (In order to suppress this make
pop_file_versions locally false.)
Setting pop_file_versions to false in Unix is the same as
setting it to 1 (i.e. disable the back file mechanism).
In VMS, pop_file_versions contains false or an integer
specifying the number of versions of a file that syscreate
should maintain, i.e. a value of 2 means maintain the latest
version and one old version, etc. If the value is false (the
default) then Poplog just allows the normal VMS version
mechanisms to operate (and hence any limit on the number of
versions is imposed by VMS settings). Unlike Unix,
pop_file_versions has no affect on sysdelete in VMS.
syspipe(org) -> (out_sdev, in_sdev) [procedure]
(Unix Only) Creates a Unix pipe and returns input and output
system devices for it. Permissible values for org are as
described above.
sysmailbox(logname, access_mode, org) -> sdev [procedure]
(VMS Only) Returns a system device for a temporary VMS mailbox
(i.e. a virtual device that can be used to send data between VMS
processes). When a mailbox is created, it is given a 'real'
device name which is something like 'MBAxx', but access to the
mailbox is usually through a logical name whose translation is
the real name.
The string logname is the logical name of the mailbox; two
situations can occur:
(a) logname already translates to a mailbox name -- in this
case that mailbox is simply opened;
(b) logname has no translation, in which case a mailbox is
created and opened, logname being entered into the job
logical name table with translation the real name of
the mailbox (i.e. MBAxx or whatever).
The access mode access_mode and the org argument are as for
syscreate, except that org may only have the values false,
"line" or "record". If false, newline is taken as end of record;
if "line" or "record", every syswrite to the mailbox is a
separate record.
VMS mailboxes support special `end of file' records. In Poplog,
these are read as 0-byte records (i.e. a sysread returns 0, and
a character repeater for the mailbox returns termin). For a
mailbox open for writing, an end of file record is written when
the device is closed (and can also be written by a syswrite for
0 bytes).
(Note that a temporary mailbox exists only while one or more VMS
processes have it open -- if all processes have closed it, the
mailbox will be deleted along with the entry in the job logical
name table.)
sysclose(dev) [procedure]
Closes the (system or user) device dev (note that all garbage
collected system device records are closed automatically, as are
all system devices on system exit).
------------------
3 Reading Devices
------------------
sysread(dev, bsub, bytestruct, nbytes) -> nread [procedure]
sysread(dev, bytestruct, nbytes) -> nread
Reads up to nbytes bytes from the device dev into the structure
bytestruct starting at byte subscript bsub, and returns as
result the actual number nread of bytes read.
In general, nread will be nbytes for disk/tape (except possibly
near or at end-of-file); for terminals and pipes/mailboxes it
will be whatever is available, depending on the value of the org
argument when the device was opened. A result of 0 bytes read
indicates end-of-file.
The structure bytestruct must be 'byte accessible', for a full
explanation of which see REF * DATA. The bytes are read into the
structure bytestruct starting at byte subscript bsub, the first
applicable byte of the structure having subscript 1 (which as
explained in REF * DATA is the first byte at the structure's
pointer).
This means that if bytestruct is any kind of vector (like a
string), the bytes are read in starting at the 1st component; if
bytestruct is a record the bytes will occupy fields from the
pointer position onwards. In all cases, the structure must be
large enough to contain all bytes read.
The second form of the call with bsub omitted is the same as
sysread(dev, 1, bytestruct, nbytes)
i.e. bsub defaults to 1.
getc(dev) -> char [procedure]
Uses sysread to read a single byte char from the device dev,
which must be open for reading. termin is returned at end of
file.
sys_read_lines(file, l1, l2) [procedure]
-> (line_l1, ..., line_l2, nread)
sys_read_lines(file, l1, l2, bool)
-> (line_l1, ..., line_l2, nread)
Extracts the lines numbered l1 through l2 from the file file,
which should either be the name of a file, or a device record
opened for reading (with org false or "line"). If the optional
boolean argument bool is supplied and true, the procedure
vedfile_line_repeater is used to read the specified lines,
otherwise the lines are read with sysread. The lines are
returned as strings on the stack (without terminating newline
characters), followed by an integer (nread) signifying the
number of lines read (which should be equal to l2 - l1 + 1). An
error is signalled if there are too few lines in the file.
Note that sys_read_lines uses an internal buffer of size 255, so
file should not contain lines longer than this.
See also REF * line_repeater, REF * vedfile_line_repeater, and
REF * vedreadin
popprompt -> string_or_p [variable]
string_or_p -> popprompt
The value of this variable determines the prompt characters
output by sysread when reading from a terminal in normal line
mode (i.e. device opened with org argument false). It may be
either an actual prompt string, or a procedure p of no arguments
returning one, i.e.
p() -> string
pop_timeout_secs -> false_or_int [variable]
false_or_int -> pop_timeout_secs
Holds an integer or false, to control timing-out of all terminal
read requests with sysread. If the value is a integer >= 0, then
any terminal read operation will be timed-out after that number
of seconds, the variable procedure pop_timeout being called when
this happens. (Default value false.)
pop_timeout() [procedure variable]
The procedure in this variable is called whenever a terminal
read operation is timed-out with pop_timeout_secs. The procedure
is called inside sysread; if it returns normally, the read
operation is restarted. (Default value identfn).
sys_input_waiting(dev) -> N_or_false [procedure]
sys_input_waiting(dev_list1) -> dev_list2 (Unix Only)
For a readable `interactive'-type device (i.e. a terminal or a
pipe/mailbox), returns an integer count N of the number of input
characters currently available to be read on the given device;
false is returned if none are available (and a read on the
device would hang waiting for input).
For all other kinds of input device (which can't hang up on a
read), returns the number of characters currently in Poplog's
input buffer for the device (which could be 0).
The second (Unix only) form is the same as
sys_device_wait(dev_list1, [], [], false) -> (dev_list2, , );
i.e. takes a list of readable devices and returns a list of
those for which input is available (see * sys_device_wait
below).
sys_clear_input(dev) [procedure]
For a readable `interactive'-type device (terminal or
pipe/mailbox), clears any input characters currently available
to be read on the device (e.g. including typeahead on a
terminal). If dev is also writeable, any buffered output is
written out first.
For all other kinds of input device, it just writes out any
buffered output (if the device is also writeable).
------------------
4 Writing Devices
------------------
syswrite(dev, bsub, bytestruct, nbytes) [procedure]
syswrite(dev, bytestruct, nbytes)
Writes nbytes bytes from the structure bytestruct to the device
dev, starting at byte bsub after the structure's key, or byte 1
if bsub is absent Thus syswrite is similar to sysread except
that bytes are written rather than read, and no result is
returned.
In addition for syswrite, the bytestruct argument may be a word:
in this case, bytes are written out from the string held in the
word record.
pop_buffer_charout -> bool [variable]
bool -> pop_buffer_charout
This boolean variable (default true) controls whether write
operations to normal line-mode terminals or pipes/mailboxes
(i.e. device opened with org argument false) are buffered. If
true, then characters are only actually written out when a
control character (ASCII value < 32, e.g. newline) is
encountered; otherwise, all characters are written out
immediately. (Note that all other devices are buffered by
default -- use sysflush to force data to be written out.)
sysflush(dev) [procedure]
sysflush(dev, sync_file)
For any writeable device dev, flushes (i.e. writes out) any
bytes outstanding in Poplog's buffer.
sync_file is an optional boolean argument (which is ignored in
VMS). For a disk file in Unix, this argument being true means
'sync' the file, i.e. force any data buffered by the operating
system to be written to disk (if sync_file is absent or false,
the current state of the file is therefore not necessarily
reflected on disk).
pop_file_write_error(dev) [procedure variable]
If a write error occurs while writing to a disk or tape device
with syswrite (usually, with disk files, due to a full disk or
exceeded quota), the device is immediately closed. The device is
then given as argument to this variable procedure, which should
take appropriate action with the partly-written file (e.g.
delete it with sysdelete(device_full_name(dev)) ). (Default
value erase).
-------------------------------
5 Line Repeaters and Consumers
-------------------------------
The following utility procedures operate on files at a line level:
line_repeater(file, int_or_string) -> line_rep [procedure]
Returns a `line repeater' procedure for the file. The file
argument can be a file name, or a device record opened for
reading (with org false or "line"). If the second argument is an
integer it is taken as the maximum length of any line in the
file; if a string, it is used as the input buffer for sysread
(the string length should be one more than the expected maximum
line length).
line_rep is a procedure of the form:
line_rep() -> string_or_termin
i.e. each time line_rep is called it returns the next line from
the file (without the terminating newline character), or
termin if it has reached end of file.
See also REF * sys_read_lines, * vedfile_line_repeater
postscript_line_consumer(file) -> line_cons [procedure]
postscript_line_consumer(file, arg_list) -> line_cons
postscript_line_consumer(file, arg_list, font_name, font_height,
font_pixel_height, line_pixel_height,
colour_vec, X_width_p) -> line_cons
Takes a filename or output device file, and returns a line
consumer, i.e. a procedure which takes strings and dstrings (see
Display Strings in REF * STRINGS) and writes them to file
encoded as ASCII PostScript instructions suitable for printing
on PostScript printers.
file is given to * discout to create an output device, and so
can be any argument suitable for that procedure.
The returned line_cons is a procedure of the form
line_cons(string_or_termin)
which each time it is called with a string as argument writes
the PostScript code for printing the string to file. Each string
is a separate line. If the given string is a dstring, line_cons
generates the appropriate PostScript code to print the string
using its character attributes. Calling line_cons(termin) will
generate the PostScript code to eject the current page, and also
closes the device (either the one supplied or the one created).
All Ved character attributes are translated appropriately,
including bold, italic, underline etc. For coloured text, the
consumer will print foreground and background using the
following grey-levels (0% = black, 100% = white):
Colour Fg Bg Colour Fg Bg
------ -- -- ------ -- --
0 0 100 1 100 0
2 50 100 3 0 80
4 70 100 5 100 30
6 30 100 7 30 80
The following Ved extended characters are also dealt with (See
REF * ITEMISE):
Ved Graphics Characters
Ved Special Space Characters
ISOLatin1 characters
Optional Arguments
If supplied, arg_list must be a list of argument strings of the
form
'keyword=value'
where the following keywords are allowed:
font Controls the set of fonts and the font and line
heights. value must be of the form
font_name:font_height:line_height
where font_name selects the set of fonts to be used,
font_height is the height to be used for the actual
characters, and line_height is the height of each
line. Both heights are measured in points, and may
be either an integer or a float. The :line_height
part may be omitted, in which case it defaults to
11/10 * font_height. For example
font=helvetica:14.2
The default is
font=courier:11
(i.e. 11 point courier, with 12.1 line height). See
LIB * postscript_line_consumer for a list of the
possible font names (but note that courier is the
only fixed-width font available).
paper Specifies the paper size -- possible values are a3,
a4, a5, a6 and letter. The default is 'paper=a4'.
hmargin Point size for the horizontal margins. The default
is 'hmargin=25'.
vmargin Point size for the vertical margins. The default is
'vmargin=25'.
margin Point size for both vertical and horizontal margins.
(N.B. 1 point is approximately 1/72 of an inch.)
The last form of the call includes another 6 arguments in
addition to arg_list. These are used by * ved_print to enable
text to be laid out identically to an XVed window in variable
width mode (including replication of the window colours).
See also * vedfile_line_consumer and HELP * ved_print
--------------------------
6 File Control Operations
--------------------------
sysseek(dev, fileptr, mode, true) -> pos [procedure]
sysseek(dev, fileptr, mode)
For a device dev, controls at which byte in the file the next
read or write will operate, dependent on the integers fileptr
and mode as follows:
Mode Meaning
---- -------
0 fileptr is an absolute byte position within the file
(1st byte = 0)
1 fileptr is a byte offset (possibly negative)
relative to the current byte (i.e. the next one that
would be read or written).
2 fileptr is a byte offset relative to the byte
immediately after the last byte in the file.
With an optional 4th argument of true, sysseek returns the
absolute byte position pos within the file after the seek.
(In VMS, sysseek can only be used on files opened for block I/O,
i.e. with org argument true.)
sys_io_control(sdev, request, bytestruct) -> bool [procedure]
sys_io_control(sdev, request) -> bool
(Unix ONLY) This procedure provides an interface to the Unix
ioctl system call, and has essentially the same arguments as the
latter. sdev is a system device, request is an integer
specifying the desired operation to be performed, and bytestruct
is an (optional) byte-accessible structure argument through
which data is passed or returned (see REF * DATA for a
definition of byte-accessible structures).
In all cases, a call of sys_io_control performs a straight ioctl
system call for the file descriptor allocated to sdev, with
request value as supplied and with bytestruct passed as the
address of its byte data (or 0 if bytestruct is omitted). The
result bool is true if the call succeeds, false if not.
For terminal devices, sys_io_control does additional work to
keep the stored device parameters in step with the terminal
state. Every device representing a terminal in Poplog maintains
a full set of terminal parameters which are set on the terminal
whenever that device is used (unless it is already set for that
device). In this way multiple devices with different
characteristics can be made to work for the same underlying
terminal, with automatic switching between different settings as
appropriate. To maintain this relationship, sys_io_control sets
the terminal state according to the stored device parameters
before the ioctl system call is made, and then updates the
device parameters from the (possibly changed) terminal state if
the call returns successfully. The new parameters will then be
set automatically on any subsequent use of the device.
sys_link_tty_params(dev_list) [procedure]
(Unix Only) This procedure is used to make two or more devices
which represent the same actual terminal share terminal
parameters, so that changing any one of them with sys_io_control
automatically affects the other(s).
The argument dev_list is a list of devices; for each set of
system devices in the list which represent the same actual
terminal, all members of that set are changed permanently to use
the parameter structure of the first-occurring member of the
set. Non-terminal (or user) devices in the list are ignored.
set_process_entry_term() [procedure]
(Unix Only) If the standard input of the Poplog process is a
terminal, resets the terminal characteristics to be what they
were on entry to the Poplog system (otherwise, does nothing).
-------------------
7 File Information
-------------------
sys_file_stat(file, fvec) -> fvec [procedure]
sys_file_stat(file, fvec, follow_symlinks) -> fvec
Where file is either a string naming a file, or a system device
record for an open file, puts information about the file in the
standard full vector fvec, returning fvec as the result; false
is returned if the file is nonexistent or is not a disk or tape
file, or cannot be opened due to a protection violation.
The optional boolean argument follow_symlinks says whether a
named file should be dereferenced if it is a Unix symbolic link
(default true). (This argument is ignored in VMS.)
For Unix Poplog, the information returned in each subscript
position of the vector fvec is as follows (UNIX * stat for
further details):
Subscript Information Returned
--------- --------------------
1 Size of file in bytes
2 Last modified time (MTIME)
3 Group id of owner
4 User id of owner
5 Mode flags
6 Number of links
7 Major/minor device
8 I-node number
9 Last accessed time (ATIME)
10 Last status change time (CTIME)
In VMS Poplog, the information returned is
Subscript Information Returned
--------- --------------------
1 Size of file in bytes
2 Creation date
3 Group number of owner
4 Member number of owner
5 Protection bits
Note that for compatibility with Unix Poplog, fvec(2) is an
integer in Unix time, i.e. a number of seconds since 00:00
January 1 1970. (This can be converted to an ASCII string date
with
sys_convert_date(fvec(2), true)
See REF * TIMES.)
All values returned in fvec are integers or bigintegers. fvec
may be any length (including 0); if its length is less than the
maximum, only the information that will fit in is given, e.g. if
the length is 1 only the size, if 2 then the size and the last
modified time/creation date, etc.
sys_file_exists(file) -> bool [procedure]
Returns true if the file named by file exists, and false
otherwise. Uses sys_file_stat.
sysfilesize(file) -> nbytes [procedure]
Returns the size in bytes nbytes of the file represented by the
system device or file name string file (which must be either a
disk or tape file). Same as fvec(1) from sys_file_stat.
sysmodtime(file) -> modtime [procedure]
Returns the Unix last-modified time or VMS creation date of the
file represented by the system device or file name string file
(which must be either a disk or tape file). Same as fvec(2) from
sys_file_stat.
sysfileowner(file) -> uid [procedure]
uid -> sysfileowner(file)
Returns an integer denoting the user id (Unix) or member number
(VMS) of the owner of file. The updater can be used to change
the ownership of file (subject to normal operating system
restrictions). Unix users can use sysgetpasswdentry to convert a
user id to a user name string.
sysfileinode(file) -> inode [procedure]
(Unix ONLY) Returns the inode number of file. If inaccessible,
returns false. Same as fvec(8) from sys_file_stat.
------------------------
8 Predicates on Devices
------------------------
isdevice(item) -> bool [procedure]
Returns true if item is a device, false if not.
systrmdev(dev) -> bool [procedure]
Returns true if the device dev is a terminal (including user
`logical terminal' devices), false if not.
In Berkeley Unix, termin is returned if the device is a (real)
terminal, but the Poplog process is backgrounded with respect to
it (i.e. an attempt to read from it will cause the process to
stop).
isclosed(dev_or_char_rep) -> bool [procedure]
For dev_or_char_rep a device, returns true if the device is
closed (i.e. has had sysclose applied to it), false if it is
still open. This procedure is also applicable to character
repeaters produced by discin, see REF * CHARIO
---------------------
9 Device Information
---------------------
device_open_name(dev) -> string [procedure]
Returns the open name string of the device dev, i.e. the name
with which the device was opened/created.
device_full_name(dev) -> full_name [procedure]
full_name -> device_full_name(dev)
Returns or updates the `full name' of the device dev. Updating
is only allowed for user devices.
For a device produced by syspipe, device_full_name will be
false, but for all other kinds of system devices it is a full
absolute pathname string, with any environment variable/logical
name components etc translated (and in Unix, symbolic links
dereferenced).
If dev is a user device, full_name is whatever was given to the
call of consdevice that created it, or whatever was assigned to
it with device_full_name.
device_os_channel(dev) -> int_or_false [procedure]
For a system device dev, returns the Unix file descriptor/VMS
channel number associated with dev (an integer). For a user
device, returns false.
device_user_data(dev) -> user_data_or_false [procedure]
For a system device dev, returns false. For a user device,
returns the user_data argument supplied to consdevice when the
device was constructed. (Note that since a user_data value
cannot be false, the truthvalue of device_user_data can be used
to distinguish user and system devices.)
--------------------
10 Standard Devices
--------------------
pop_charin_device -> dev [variable]
dev -> pop_charin_device
pop_charout_device -> dev [variable]
dev -> pop_charout_device
pop_charerr_device -> dev [variable]
dev -> pop_charerr_device
The devices held by these (active) variables represent the
current `logical' standard input, output and error channels, and
are used by the procedures charin, charout and charerr
respectively to perform character stream I/O (see REF * CHARIO).
Depending on the context, they may contain either system or user
devices. On system startup, they contain the same devices as
popdevin, popdevout and popdeverr respectively (i.e. the
standard input, output and error of the Poplog process). In the
Ved editor, e.g. during compilation and in `immediate mode',
they contain user devices which read from or write to Ved
buffers.
Always use these devices rather than popdevin, popdevout or
popdeverr unless your program specifically wants to deal with
the standard I/O of the Poplog process (i.e. where interaction
with the operating system is involved).
poprawdevin -> dev [variable]
dev -> poprawdevin
poprawdevout -> dev [variable]
dev -> poprawdevout
When either the standard input or standard output of the Poplog
process is a terminal, these (active) variables are set up
initially to hold reading and writing devices respectively for
that terminal, opened with org argument true, to give terminal
input and output in `raw' mode (as described above). (In Unix,
the two devices have their terminal parameters linked by
sys_link_tty_params, see above.)
If neither standard channel is a terminal, the value of both
these variables is an undef record, <undef poprawdevin> and
<undef poprawdevout> (which will produce the mishap 'DEVICE
NEEDED' if an attempt is made to use them for I/O). It is
therefore advisable to test with isdevice first if your program
might attempt to use them in this situation.
poprawdevin is used by rawcharin, and poprawdevout is used by
rawcharout and rawsubstringout, which procedures are used by the
Ved editor for screen I/O. See REF * CHARIO
popdevin -> sdev [variable]
sdev -> popdevin
popdevout -> sdev [variable]
sdev -> popdevout
popdeverr -> sdev [variable]
sdev -> popdeverr
These (active) variables hold system device records for the
standard input, output and error channels respectively of the
operating-system Poplog process (corresponding to Unix file
descriptors 0, 1, and 2, or VMS logical names sys$input,
sys$output, sys$error).
The devices are opened initially with org argument false, giving
normal line mode I/O for terminals, etc. (In Unix, when any two
or all three of these devices represent the same terminal, their
terminal parameters are linked together with sys_link_tty_params
(see above), which means that changing the characteristics of
one automatically affects the other(s).)
You can only assign system devices to these variables, not user
ones; in Unix, assigning a new system device to one will
redirect the standard channel for the Poplog process (this could
be done e.g. after a sys_fork, see REF * SYSUTIL).
You should only use these variables at all if your program
specifically wants to deal with the standard I/O of the Poplog
process, i.e. where interaction with the operating system is
involved. When this is not the case, use pop_charin_device,
pop_charout_device or pop_charerr_device instead.
pop_null_device -> dev [constant]
The standard "null" device. If read, always at EOF. If written
to, output is discarded. Other device operations (test input,
clear input, flush, seek, and close) have no effect. Useful for
programs that wish to temporarily disable terminal i/o.
-----------------------------
11 Constructing User Devices
-----------------------------
consdevice(open_name, full_name, user_data, flags, [procedure]
methods_vec) -> udev
Constructs and returns a user device udev. The arguments to this
procedure are as follows:
open_name
A string giving the name under which the device was
`opened'; it is returned by device_open_name applied to the
device.
full_name
This is supposed to be the `full name' of the device, but
can actually be anything; it is returned by device_full_name
applied to the device. (Note that the class_print of a
device record prints it as <device item>, where item is its
device_full_name if this is non-false, or its
device_open_name otherwise.)
user_data
This argument allows any necessary user information
pertaining to the `internal state' of the device to be held
in the record, and can be accessed from udev with
device_user_data. It may be anything except false, since
false is returned by device_user_data when applied to a
system device. (Note that user_data should generally be a
structure; device_user_data does not have an updater on the
assumption that you will update information in the user_data
structure, not the device_user_data field itself.)
flags
An integer, the bits in which specify special attributes for
the device. Currently, only bit 0 (flags = 1) is meaningful:
Bit Meaning
--- -------
0 If set, the device is a logically a `terminal'
(i.e. interfaces to a human user), and systrmdev
will return true for it.
methods_vec
A full vector giving the `methods' (procedures) to be used
by the relevant system procedures when applied to the
device. Currently this has 4 elements,
read_vec, write_vec, seek_p, close_p
where each element may be either false, or a single
procedure/vector of procedures, as follows:
read_vec
A full vector of `read' methods for a readable (i.e.
input) device, or false if the device is not readable.
If a vector, it must contain 3 procedures, namely
read_p, test_input_p, clear_input_p
read_p
This procedure will be called by a sysread on the
device, as
read_p(udev, bsub, bytestruct, nbytes) -> nread
It should read up to nbytes into the buffer
bytestruct starting at byte subscript bsub, and
return nread, the number of bytes actually read (a
zero return indicates end of file).
test_input_p
This procedure will be called by a sys_input_waiting
on the device, as follows
test_input_p(udev) -> n_or_false
It should return false if a sysread on the device
would `block', i.e. hang-up waiting for input.
Otherwise, the result must be an integer N >= 0
indicating how many bytes are available to read (0
if the actual number is not known, or not relevant).
clear_input_p
This procedure will be called by a sys_clear_input
on the device, i.e.
clear_input_p(udev)
It should discard any `buffered' input on the
device, as appropriate.
write_vec
A full vector of `write' methods for a writeable (i.e.
output) device, or false if the device is not writeable.
If a vector, it must contain 2 procedures, namely
write_p, flush_p
write_p
This procedure will be called by a syswrite on the
device, as
write_p(udev, bsub, bytestruct, nbytes)
It should write out nbytes bytes from the bytestruct
buffer starting at byte subscript bsub.
flush_p
This procedure will be called by a sysflush on the
device, as
flush_p(udev)
It should write out any `buffered' output on the
device, as appropriate.
seek_p
A procedure for a `seekable' device, or false if the
device is not seekable. If a procedure, it will be
called by a sysseek on the device as
seek_p(udev, fileptr, mode) -> pos
See sysseek above for an explanation of the arguments
(note that unlike sysseek itself, seek_p always takes 3
arguments and must return the pos result).
close_p
A procedure to be called by a sysclose on the device, or
false if no action is required on closing. If a
procedure, it will be called as
close_p(udev)
(Note that unlike system devices, user devices are NOT
closed automatically when garbage collected. If you
require this, you should set up a destroy action on the
device after creating it, e.g.
sysclose -> sys_destroy_action(udev)
See REF * PROPS.)
-----------------
12 Miscellaneous
-----------------
sys_device_wait(in_devs, out_devs, except_devs, wait) [procedure]
-> (in_ready, out_ready, except_ready)
(Unix Only) Provides an interface to the Unix select system call
for multiplexing device I/O.
Each of in_devs, out_devs and except_devs are either single
devices or lists of them (possibly []). All in_devs and
except_devs devices must be readable, and all out_devs devices
writeable.
sys_device_wait returns three results in_ready, out_ready and
except_ready, indicating which devices are respectively ready
for reading, writing, or have an exception condition pending
(the last applies only to out-of-band data on sockets).
Each result is either [], a single device, or a list of them; a
single device is returned only if the corresponding argument was
one. (I.e, a list argument will always give a list result. To
avoid creating unnecessary garbage, list results may be
reclaimed with * sys_grbg_list when no longer required.)
How long sys_device_wait waits for ready conditions is
controlled by the wait argument, which can take the following
values:
¤ false, meaning don't wait. Return is immediate with the
three results reflecting which devices are ready now.
¤ true, meaning wait until one or more devices are ready.
¤ An integer timeout value usec in microseconds. If no devices
are ready after usec microseconds have elapsed,
sys_device_wait returns, but with false for all three
results to indicate timeout.
(Note that all three device arguments may be []. With wait a
timeout this is equivalent to a syssleep for the given time;
with wait true it is equivalent to
repeat syshibernate() endrepeat;
i.e. the system just processes interrupts, X events etc.)
sys_async_io(sdev, condition) -> ast_p_or_false [procedure]
ast_p_or_false -> sys_async_io(sdev, condition)
This procedure allows the association of an asynchronous trap
procedure ast_p with a device sdev to handle a specified 'I/O
ready' condition on the device.
Possible condition values (corresponding to the three device
arguments to sys_device_wait) are:
condition Meaning
--------- -------
0 Input waiting
1 Output possible
2 Exception condition pending (applies only to
out-of-band data on sockets)
(Note however that VMS Poplog currently supports only the value
of 0 for condition, i.e. input waiting.)
If ast_p_or_false is not false, asynchronous processing is
enabled; if false, asynchronous processing is disabled. When
enabled, the ast_p procedure is called asynchronously (i.e.
inside whatever other procedures the system is current
executing) when the specified condition occurs. (See
Asynchronous Trap Procedures in REF * ASYNC for full details of
the ast_p argument, which may also be a pair whose front is the
procedure.)
Input Waiting
A trap procedure for condition 0 is called when input becomes
available on sdev and there is no outstanding sysread for it.
This happens at most once between reads, i.e. once ast_p has
been called, it will not be invoked again until after a sysread
on the device.
A trap procedure will normally read and process input from the
device. Note that to avoid unwanted interactions which could
lead to the procedure being called when no input is actually
available, it is sensible to guard the read with a
sys_input_waiting test. Moreover, the mechanism for activating
trap procedures does not take into account buffering inside
Poplog devices, so that it may also be sensible to process all
available input each time the procedure is called, i.e. the
ast_p procedure should contain something like
while sys_input_waiting(sdev) do
sysread(sdev, ...)
...
endwhile;
etc.
Output possible
A trap procedure for condition 1 is called when output becomes
possible on sdev after a blocking condition (i.e. after the O/S
output buffer was full). Thus the ast_p procedure should contain
something like
while have-data-to-output and output_possible(sdev) do
syswrite(sdev, ...)
...
endwhile;
where have-data-to-output is some appropriate test for whether
the program has data to write to the device, and output_possible
is defined as
define lconstant output_possible(dev);
lvars dev, ready;
sys_device_wait([], dev, [], false) -> (, ready, );
return(ready /== []);
enddefine;
The program itself must call ast_p when have-data-to-output
first becomes true; thereafter, if output is blocked (i.e.
output_possible returns false), the ast_p procedure will be
called asynchronously when the blocking is removed.
sysstring -> string [constant]
sysstringlen -> int [constant]
sysstring is a string of length sysstringlen, which libraries
and other programs can use as a character buffer to give to
routines such as sysread and syswrite (set up in
LIB * SYSSTRING).
device_key -> key [constant]
This constant holds the key structure for device records (see
REF * KEYS).
Additional facilities, notably pipein and pipeout are described in
HELP * PIPEUTILS
+-+ C.all/ref/sysio
+-+ Copyright University of Sussex 1999. All rights reserved.