Updated manual.

This commit is contained in:
shivers 1997-03-11 02:49:52 +00:00
parent 230263ee0d
commit 5e85d401b9
9 changed files with 10298 additions and 9463 deletions

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,8 @@
\parskip = 3pt plus 3pt
\sloppy
%\includeonly{syscalls}
\input{decls}
\makeindex
%%% End preamble

View File

@ -187,8 +187,8 @@ There are three basic {\Scheme} forms that use extended process forms:
\ex{exec-epf}, \cd{&}, and \ex{run}.
\dfn {exec-epf} {. \var{epf}} {\noreturn} {syntax}
\dfnx {\&} {. \var{epf}} {\integer} {syntax}
\dfnx {run} {. \var{epf}} {\integer} {syntax}
\dfnx {\&} {. \var{epf}} {proc} {syntax}
\dfnx {run} {. \var{epf}} {proc} {syntax}
\begin{desc}
\index{exec-epf} \index{\&} \index{run}
The \ex{(exec-epf . \var{epf})} form nukes the current process: it establishes
@ -257,7 +257,9 @@ to capture the output of processes as {\Scheme} data.
\dfnx{run/sexps} {. \var{epf}} {list} {syntax}
\begin{desc}
These forms all fork off subprocesses, collecting the process' output
to stdout in some form or another.
to stdout in some form or another.
The subprocess runs with file descriptor 1 and the current output port
bound to a pipe.
\begin{desctable}{0.7\linewidth}
\ex{run/port} & Value is a port open on process's stdout.
Returns immediately after forking child. \\

View File

@ -31,6 +31,8 @@ There are four possible choices for a \ex{handle-delim} parameter:
\hline
\end{tabular}
\end{inset}
The first case, \ex{'trim}, is the standard default for all the routines
described in this section.
The last three cases allow the programmer to distinguish between strings
that are terminated by a delimiter character, and strings that are
terminated by an end-of-file.
@ -68,7 +70,7 @@ See section~\ref{sec:char-sets} for information on character set manipulation.
\begin{desc}
Read until we encounter one of the chars in \var{char-set} or eof.
The \var{handle-delim} parameter determines how the terminating character
is handled. It is described above, and defaults to \ex{'peek}.
is handled. It is described above, and defaults to \ex{'trim}.
The \var{char-set} argument may be a charset, a string, a character, or a
character predicate; it is coerced to a charset.
@ -94,7 +96,7 @@ See section~\ref{sec:char-sets} for information on character set manipulation.
If an integer is returned (\ie, the read is successfully terminated by
reading a delimiter character), then the \var{handle-delim} parameter
determines how the terminating character is handled.
It is described above, and defaults to \ex{'peek}.
It is described above, and defaults to \ex{'trim}.
\end{desc}
@ -137,3 +139,10 @@ the procedure call.
% fills up, %READ-DELIMITED! will peek at one more character from the
% input stream to determine if it terminates the input. If so, that
% is returned, not #f.
\begin{defundesc} {skip-char-set} {skip-chars [port]} {\integer}
Skip characters occurring in the set \var{skip-chars};
return the number of characters skipped.
The \var{skip-chars} argument may be a charset, a string, a character, or a
character predicate; it is coerced to a charset.
\end{defundesc}

View File

@ -181,6 +181,7 @@ where
& \ex{-ds} & Do script. \\
\\
\var{end-option:} & \ex{-s} \var{script} \\
& \ex{-sfd} \var{num} \\
& \ex{-c} \var{exp} \\
& \ex{--}
\end{tabular}
@ -297,6 +298,14 @@ The following switches and end options are defined:
by the switch-scanner and are passed through to the program as
the tail of the command-line list.
\Item{-sfd \var{num}}
Loads the script from file descriptor \var{num}.
This switch is like the \ex{-s} switch,
except that the script is loaded from one of the process' open input
file descriptors.
For example, to have the script loaded from standard input, specify
\ex{-sfd 0}.
\Item{--}
Terminate argument scanning and start up scsh in interactive mode.
If the argument list just runs out, without either a terminating
@ -418,17 +427,19 @@ The only special characters are space, tab, newline, and backslash.
six space characters, but you really have a tab character,
and \emph{vice-versa}.
\item The newline character terminates the sequence of arguments,
and will also terminate a final non-empty argument.
(However, a newline following a space does not introduce a final
empty-string argument; it only terminates the argument list.)
\item The newline character terminates an argument, like the space character,
and also terminates the argument sequence.
This means that an empty line parses to the singleton list whose one
element is the empty string: \ex{("")}.
The grammar doesn't admit the empty list.
\item The backslash character is the escape character.
It escapes backslash, space, tab, and newline, turning off their
special functions, and allowing them to be included in arguments.
The {\Ansi} C escape sequences, such as \verb|\n| and \verb|\t| are
also supported; these also produce argument-constituents---\verb|\n|
doesn't act like a terminating newline.
The {\Ansi} C escape sequences (\verb|\b|, \verb|\n|, \verb|\r|
and \verb|\t|) are also supported;
these also produce argument-constituents---\verb|\n| doesn't act
like a terminating newline.
The escape sequence \verb|\|\emph{nnn} for \emph{exactly} three
octal digits reads as the character whose {\Ascii} code is \emph{nnn}.
It is an error if backslash is followed by just one or two octal digits:
@ -555,7 +566,9 @@ sort foo bar
{\evalto} /usr/local/bin/scsh \\ sort foo bar
{\evalto} /usr/local/bin/scsh -dm -m sort-toplevel -e top -s sort foo bar\end{centercode}}
An alternate method would have used a \ex{-n -o sort-toplevel}
An alternate method would have used a
\begin{code}
-n #f -o sort-toplevel\end{code}
sequence of switches to specify a top-level package.
\end{itemize}
@ -580,8 +593,9 @@ If these computations terminate with no errors, the scsh process
exits with an exit code of 0.
To return a specific exit status, use the \ex{exit} procedure explicitly, \eg,
\codex{scsh -c "(exit (run (| (fmt) (mail shivers@lcs.mit.edu))))"}
\begin{tightcode}
scsh -c \\
"(exit (status:exit-val (run (| (fmt) (mail shivers)))))"\end{tightcode}
\section{The scsh virtual machine}
To run the {\scm} implementation of scsh, you run a specially modified

View File

@ -39,11 +39,19 @@ The code uses Henry Spencer's regular expression package.
Returns the start position of the match denoted by \var{match-number}.
The whole regexp is 0. Each further number represents positions
enclosed by \ex{(\ldots)} sections. \var{Match-number} defaults to 0.
If the regular expression matches as a whole,
but a particular parenthesized sub-expression does not match, then
\ex{match:start} returns {\sharpf}.
\end{defundesc}
\begin{defundesc} {match:end} {match [match-number]} \fixnum
Returns the end position of the match denoted by \var{match-number}.
\var{Match-number} defaults to 0 (the whole match).
If the regular expression matches as a whole,
but a particular parenthesized sub-expression does not match, then
\ex{match:end} returns {\sharpf}.
\end{defundesc}
\begin{defundesc} {match:substring} {match [match-number]} \str
@ -51,10 +59,6 @@ The code uses Henry Spencer's regular expression package.
\var{Match-number} defaults to 0 (the whole match).
\end{defundesc}
\oops{Scsh regex matching doesn't currently flag un-matched subexpressions
in the \ex{match:begin}, \ex{match:end}, and \ex{match:substring} functions.
This needs to be fixed.}
Regular expression matching compiles patterns into special data
structures which can be efficiently used to match against strings.
The overhead of compiling patterns that will be used for multiple
@ -74,20 +78,6 @@ searches can be avoided by these lower-level routines:
otherwise {\sharpf}. \var{Start} defaults to 0.
\end{defundesc}
\begin{remarkenv}
The truth: S48 doesn't have the facilities for extending the garbage
collector to malloc'd C storage (unlike elk). So we do not really export
regular expression compilation. What we currently do is this:
\begin{tightcode}
(define regexp? string?)
(define (make-regexp str) str)
(define (regexp-exec regexp str [start])
(string-match regexp str [start]))\end{tightcode}
%
This could be improved upon in another implementation (like elk).
\end{remarkenv}
\defun{regexp-quote}{str}{\str}
\begin{desc}
Returns a regular expression that matches the string \var{str} exactly.

View File

@ -32,7 +32,7 @@ packet, it is \emph{not} accessed through a global variable.
For reference purposes, the {\Unix} \ex{errno} numbers
are bound to the variables \ex{errno/perm}, \ex{errno/noent}, {\etc}
System calls never return \ex{error/intr}---they
automatically retry. (Currently only true for I/O calls.)
automatically retry.
\begin{dfndesc}
{errno-error}{errno syscall .\ data}{\noreturn}{procedure}
@ -111,10 +111,6 @@ the \ex{errno/intr} exception is never raised.
If the programmer wishes to abort a system call on an interrupt, he
should have the interrupt handler explicitly raise an exception or
invoke a stored continuation to throw out of the system call.
\remark{This is not strictly true in the current implementation---only
some of the i/o syscalls loop.
But BSD variants never return \ex{EINTR} anyway, unless you explicitly
request it, so we'll live w/it for now.}
\end{dfndescx}
@ -195,13 +191,13 @@ These procedures alter the dynamic binding of the current I/O port procedures
to new values.
\end{desc}
\defun {close} {port/fd} {\boolean}
\defun {close} {fd/port} {\boolean}
\begin{desc}
Close the port or file descriptor.
If \var{port/fd} is a file descriptor, and it has a port allocated to it,
If \var{fd/port} is a file descriptor, and it has a port allocated to it,
the port is shifted to a new file descriptor created with \ex{(dup
port/fd)} before closing \ex{port/fd}. The port then has its revealed
fd/port)} before closing \ex{fd/port}. The port then has its revealed
count set to zero. This reflects the design criteria that ports are not
associated with file descriptors, but with open files.
@ -238,9 +234,9 @@ to new values.
descriptors.
It is exactly equivalent to the series of assignments
\begin{code}
(set-current-input-port! (fdes->inport 0))
(set-current-output-port! (fdes->inport 1))
(set-error-output-port! (fdes->inport 2))\end{code}
(set-current-input-port! (fdes->inport 0))
(set-current-output-port! (fdes->outport 1))
(set-error-output-port! (fdes->outport 2))\end{code}
However, you are more likely to find the dynamic-extent variant,
\ex{with-stdio-ports*}, below, to be of use in general programming.
\end{desc}
@ -275,7 +271,7 @@ interface described herein may be liable to change.
\end{desc}
\defun {make-string-output-port} {} {\port}
\defunx {string-output-port-output} {port} {\port}
\defunx {string-output-port-output} {port} {\str}
\begin{desc}
A string output port is a port that collects the characters given to it into
a string.
@ -369,7 +365,7 @@ are used to shift back and forth between file descriptors and ports. When
\ex{port->fdes} reveals a port's file descriptor, it increments the port's
\var{revealed} field. When the user is through with the file descriptor, he
can call \ex{(release-port-handle \var{port})}, which decrements the count.
The function \ex{(call/fdes fdes/port \var{proc})} automates this protocol.
The function \ex{(call/fdes fd/port \var{proc})} automates this protocol.
\ex{call/fdes} uses \ex{dynamic-wind} to enforce the protocol.
If \var{proc} throws out of the \ex{call/fdes} application,
the unwind handler releases the descriptor handle;
@ -523,20 +519,20 @@ Decrement the port's revealed count.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{{\Unix} I/O}
\defun {dup} {port/fd [newfd]} {port/fd}
\defunx{dup->inport} {port/fd [newfd]} {port}
\defunx{dup->outport} {port/fd [newfd]} {port}
\defunx{dup->fdes} {port/fd [newfd]} {fd}
\defun {dup} {fd/port [newfd]} {fd/port}
\defunx{dup->inport} {fd/port [newfd]} {port}
\defunx{dup->outport} {fd/port [newfd]} {port}
\defunx{dup->fdes} {fd/port [newfd]} {fd}
\begin{desc}
These procedures provide the functionality of C's \ex{dup()} and \ex{dup2()}.
The different routines return different types of values:
\ex{dup->inport}, \ex{dup->outport}, and \ex{dup->fdes} return
input ports, output ports, and integer file descriptors, respectively.
\ex{dup}'s return value depends on on the type of
\var{port/fd}---it maps fd$\rightarrow$fd and port$\rightarrow$port.
\var{fd/port}---it maps fd$\rightarrow$fd and port$\rightarrow$port.
These procedures use the {\Unix} \ex{dup()} syscall to replicate
the file descriptor or file port \var{port/fd}.
the file descriptor or file port \var{fd/port}.
If a \var{newfd} file descriptor is given, it is used as the target of
the dup operation, \ie, the operation is a \ex{dup2()}.
In this case, procedures that return a port (such as \ex{dup->inport})
@ -587,26 +583,17 @@ this is dependent on the OS implementation.
\begin{defundesc} {open-file} {fname flags [perms]} {\port}
\var{Perms} defaults to \cd{#o666}.
\var{Flags} is an integer bitmask, composed by or'ing together the following
constants:
\begin{code}\codeallowbreaks
open/read ; You may only
open/write ; choose one
open/read+write ; of these three
open/no-control-tty
open/nonblocking
open/append
open/create
open/truncate
open/exclusive
. ; Your Unix may have
. ; a few more.\end{code}
\var{Flags} is an integer bitmask, composed by or'ing together constants
listed in table~\ref{table:fdes-status-flags}
(page~\pageref{table:fdes-status-flags}).
You must use exactly one of the \ex{open/read}, \ex{open/write}, or
\ex{open/read+write} flags.
%
Returns a port. The port is an input port if the \var{flags} permit it,
otherwise an output port. \R4RS/\scm/scsh do not have input/output ports,
so it's one or the other. This should be fixed. (You can hack simultaneous
i/o on a file by opening it r/w, taking the result input port,
and duping it to an output port with \ex{dup->outport}.)
The returned port is an input port if the \var{flags} permit it,
otherwise an output port. \R4RS/\scm/scsh do not have input/output ports,
so it's one or the other. This should be fixed. (You can hack simultaneous
i/o on a file by opening it r/w, taking the result input port,
and duping it to an output port with \ex{dup->outport}.)
\end{defundesc}
\defun{open-input-file}{fname [flags]}\port
@ -626,6 +613,89 @@ and duping it to an output port with \ex{dup->outport}.)
Returns a file descriptor.
\end{defundesc}
\defun{fdes-flags}{fd/port}{\integer}
\begin{defundescx}{set-fdes-flags}{fd/port \integer}{\undefined}
These procedures allow reading and writing of an open file's flags.
The only such flag defined by {\Posix} is \ex{fdflags/close-on-exec};
your {\Unix} implementation may provide others.
These procedures should not be particularly useful to the programmer,
as the scsh runtime already provides automatic control of the close-on-exec
property.
Unrevealed ports always have their file descriptors marked
close-on-exec, as they can be closed when the scsh process execs a new program.
Whenever the user reveals or unreveals a port's file descriptor,
the runtime automatically sets or clears the flag for the programmer.
Programmers that manipulate this flag should be aware of these extra, automatic
operations.
\end{defundescx}
\defun{fdes-status}{fd/port}{\integer}
\begin{defundescx}{set-fdes-status}{fd/port \integer}{\undefined}
These procedures allow reading and writing of an open file's status flags
(table~\ref{table:fdes-status-flags}).
%
\begin{table}
\begin{center}
\begin{tabular}{@{}rp{1.5in}>{\ttfamily}l@{}}
& Allowed operations & Status flag \\ \cline{2-3}
\textbf{Open+Get+Set} &
\parbox[t]{1.5in}{\raggedright
These flags can be used in \ex{open-file}, \ex{fdes-status},
and \ex{set-fdes-status} calls.} &
%
\begin{tabular}[t]{@{}>{\ttfamily}l@{}}
%% These are gettable and settable
open/append \\
open/non-blocking \\
open/async \textrm{(Non-\Posix)} \\
open/fsync \textrm{(Non-\Posix)}
\end{tabular}
\\\cline{2-3}
\textbf{Open+Get} &
\parbox[t]{1.5in}{\raggedright
These flags can be used in \ex{open-file} and \ex{fdes-status} calls,
but are ignored by \ex{set-fdes-status}.\strut} &
%
\begin{tabular}[t]{@{}>{\ttfamily}l@{}}
%% These are gettable, not settable
open/read \\
open/write \\
open/read+write \\
open/access-mask
\end{tabular}
\\\cline{2-3}
\textbf{Open} &
\parbox[t]{1.5in}{\raggedright
These flags are only relevant in
\ex{open-file} calls;
they are ignored by \ex{fdes-status} and \ex{set-fdes-status} calls.} &
%
\begin{tabular}[t]{@{}>{\ttfamily}l@{}}
%% These are neither gettable nor settable.
open/create \\
open/exclusive \\
open/no-control-tty \\
open/truncate
\end{tabular}
\end{tabular}
\end{center}
\caption{Status flags for \texttt{open-file},
\texttt{fdes-status} and \texttt{set-fdes-status}.
Only {\Posix} flags are guaranteed to be present;
your operating system may define others.
The \texttt{open/access-mask} value is not an actual flag,
but a bit mask used to select the field for the \texttt{open/read},
\texttt{open/write} and \texttt{open/read+write} bits.
}
\label{table:fdes-status-flags}
\end{table}
Note that this file-descriptor state is shared between file descriptors
created by \ex{dup}---if you create port \var{b} by applying \ex{dup}
to port \var{a}, and change {\var{b}}'s status flags, you will also have
changed {\var{a}}'s status flags.
\end{defundescx}
\begin{defundesc}{pipe}{} {[\var{rport} \var{wport}]}
Returns two ports, the read and write end-points of a {\Unix} pipe.
@ -702,8 +772,8 @@ Returns two ports, the read and write end-points of a {\Unix} pipe.
of any particular read operation.
\end{desc}
\defun {select }{rvec wvec evec [timeout]}{rvec' wvec' evec'}
\defunx{select!}{rvec wvec evec [timeout]}{nr nw ne}
\defun {select }{rvec wvec evec [timeout]}{[rvec' wvec' evec']}
\defunx{select!}{rvec wvec evec [timeout]}{[nr nw ne]}
\begin{desc}
The \ex{select} procedure allows a process to block and wait for events on
multiple I/O channels.
@ -849,14 +919,14 @@ buffering is turned off
$\var{policy} = \ex{bufpol/none}$).
\end{defundesc}
\begin{defundesc}{force-output} {[fd/port]}{\noreturn}
\begin{defundesc}{force-output} {[fd/port]}{\undefined}
This procedure does nothing when applied to an integer file descriptor
or unbuffered port.
It flushes buffered output when applied to a buffered port,
and raises a write-error exception on error. Returns no value.
\end{defundesc}
\begin{defundesc}{flush-all-ports} {}{\noreturn}
\begin{defundesc}{flush-all-ports} {}{\undefined}
This procedure flushes all open output ports with buffered data.
\end{defundesc}
@ -877,6 +947,11 @@ not with associated open file descriptors.
Once a process locks a file, using some file descriptor \var{fd},
the next time \emph{any} file descriptor referencing that file is closed,
all associated locks are released.
This severely limits the utility of {\Posix} advisory file locks,
and we'd recommend caution when using them.
It is not without reason that the FreeBSD man pages refer to {\Posix}
file locking as ``completely stupid.''
Scsh moves Scheme ports from file descriptor to file descriptor with
\ex{dup()} and \ex{close()} as required by the runtime,
so it is impossible to keep file locks open across one of these shifts.
@ -892,6 +967,7 @@ associated file descriptor.
NeXTSTEP users should also note that even minimalist {\Posix} file locking
is not supported for NFS-mounted files in NeXTSTEP; NeXT claims they will
fix this in NS release 4.
We'd appreciate hearing from users when and if this happens.
}
{\Posix} allows the user to lock a region of a file with either
@ -903,14 +979,18 @@ Locked regions are described by the \emph{lock-region} record:
start
len
whence
pid)\end{code}
\index{lock-region?}
\index{lock-region:exclusive?} \index{lock-region:whence}
\index{lock-region:start} \index{lock-region:end}
\index{lock-region:len} \index{lock-region:pid}
proc)\end{code}%
\index{lock-region?}%
\index{lock-region:exclusive?} \index{lock-region:whence}%
\index{lock-region:start} \index{lock-region:end}%
\index{lock-region:len} \index{lock-region:proc}%
%
\begin{itemize}
\item
The \ex{exclusive?} field is true if the lock is exclusive;
false if it is shared.
\item
The \ex{whence} field is one of the values from the \ex{seek} call:
\ex{seek/set}, \ex{seek/delta}, or \ex{seek/end},
and determines the interpretation of the \ex{start} field:
@ -923,9 +1003,15 @@ file descriptor's current position in the file.
end of the file.
\end{itemize}
The region of the file being locked is given by the \ex{start} and \ex{len}
fields.
The \ex{pid} field gives the process id of the process holding the region
fields;
if \ex{len} is zero, it means ``infinity,'' that is, the region extends
from the starting point through the end of the file, even as the file is
extended by subsequent write operations.
\item
The \ex{proc} field gives the process object for the process holding the region
lock, when relevant (see \ex{get-lock-region} below).
\end{itemize}
\begin{defundesc}{make-lock-region}{exclusive? start len [whence]}{lock-region}
This procedure makes a lock-region record.
@ -940,14 +1026,24 @@ These procedures lock a region of the file referenced by file descriptor
The \ex{lock-region} procedure blocks until the lock is granted;
the non-blocking variant returns a boolean indicating whether or not
the lock was granted.
To take an exclusive (write) lock, you must have the file descriptor
open with write access;
to take a shared (read) lock, you must have the file descriptor
open with read access.
\end{desc}
\begin{defundesc}{get-lock-region}{fdes lock}{lock-region or \sharpf}
Return the first lock region on \var{fdes} that overlaps with
the lock region \var{lock}.
If there is no such lock, return false.
This procedure fills out the \ex{pid} field of the returned lock region,
Return the first lock region on \var{fdes} that would conflict with
lock region \var{lock}.
If there is no such lock region, return false.
This procedure fills out the \ex{proc} field of the returned lock region,
and is the only procedure that has anything to do with this field.
(See section~\ref{sec:proc-objects} for a description of process objects.)
Note that if you apply this procedure to a file system that is shared
across multiple operating systems (\ie, an NFS file system), the \ex{proc}
field may be ambiguous.
We note, again, that {\Posix} advisory file locking is not a terribly useful
or well-designed facility.
\end{defundesc}
\begin{defundesc}{unlock-region}{fdes lock}{\undefined}
@ -1705,7 +1801,7 @@ Suspend the current process with a SIGSTOP signal.
\begin{code}
(fork (\l{} (fork/pipe a) (b)))\end{code}
%
which returns the pid of \ex{b}'s process.
which returns the process object for \ex{b}'s process.
To create a background three-process pipe \ex{a | b | c}, we write:
%
@ -1714,7 +1810,7 @@ Suspend the current process with a SIGSTOP signal.
(fork/pipe b)
(c)))\end{code}
%
which returns the pid of \ex{c}'s process.
which returns the process object for \ex{c}'s process.
Note that these procedures affect file descriptors, not ports.
That is, the pipe is allocated connecting the child's file descriptor
@ -1844,18 +1940,22 @@ values \ex{'early}, \ex{'late}, or {\sharpf} (\ie, no autoreap).
\begin{description}
\item [early]
The child is reaped from the {\Unix} kernel's process table
into scsh as soon as possible after it dies. In the current
release of scsh, this happens at the next call to
\ex{wait}---when scsh is asked to wait for a particular
child to exit, it will reap \emph{all} outstanding zombies.
When signal handlers are added to a future release of scsh,
early autoreaping will use the \ex{SIGCHLD} signal to reap
zombies with minimum delay.
into scsh as soon as it dies. This is done by having a
signal handler for the \ex{SIGCHLD} signal reap the process.
\emph{
If a scsh program sets its own handler for the \ex{SIGCHLD}
signal, the handler must reap dead children
by calling \ex{wait}, \ex{wait-any}, or \ex{reap-zombies}.}
We deprecate interrupt-driven code, and hope to provide
alternative tools in a future, multi-threaded release of scsh.
\item [late]
The child is not autoreaped until it dies \emph{and} the scsh program
drops all pointers to its process object. That is, the process
table is cleaned out during garbage collection.
\oops{The \ex{late} policy is not supported under the current
release of scsh. It requires more sophisticated gc hooks than
we can get from the release of {\scm} that we use.}
\item [\sharpf]
If autoreaping is turned off, process reaping is completely under
@ -2043,8 +2143,8 @@ Otherwise, this function returns false.
\defun {umask}{} \fixnum
\defunx {set-umask} {perms} \undefined
\defunx {with-umask*} {perms thunk} {values of thunk}
\dfnx {with-umask} {perms . body} {values of body} {syntax}
\defunx {with-umask*} {perms thunk} {value(s) of thunk}
\dfnx {with-umask} {perms . body} {value(s) of body} {syntax}
\begin{desc}
The process' current umask is retrieved with \ex{umask}, and set with
\ex{(set-umask \var{perms})}. Calling \ex{with-umask*} changes the umask
@ -2080,20 +2180,20 @@ The special form \ex{with-cwd} is simply syntactic sugar for \ex{with-cwd*}.
\defun {pid}{} \fixnum
\defunx {parent-pid}{} \fixnum
\defunx {process-group} {} \fixnum
\defunx {set-process-group} {[proc] pgrp} \undefined % [not implemented]
\defunx {set-process-group} {[proc/pid] pgrp} \undefined % [not implemented]
\begin{desc}
\ex{(pid)} and \ex{(parent-pid)} retrieve the process id for the
current process and its parent.
\ex{(process-group)} returns the process group of the current process.
A process' process-group can be set with \ex{set-process-group};
the value \var{pid} specifies the affected process. It may be either
the value \var{proc/pid} specifies the affected process. It may be either
a process object or an integer process id, and defaults to the current
process.
\end{desc}
\defun {set-priority} {which who priority} \undefined %; priority stuff unimplemented
\defunx {priority} {which who} \fixnum % ; not implemented
\defunx {nice} {[pid delta]} \undefined %; not implemented
\defunx {nice} {[proc/pid delta]} \undefined %; not implemented
\begin{desc}
These procedures set and access the priority of processes.
I can't remember how \ex{set-priority} and \ex{priority} work, so no
@ -2279,7 +2379,8 @@ fully-qualified domain name such as ``solar.csie.ntu.edu.tw.''
\section{Signal system}
Signal numbers are bound to the variables \ex{signal/hup}, \ex{signal/int},
\ldots
\ldots. See tables~\ref{table:signals-and-interrupts} and
\ref{table:uncatchable-signals} for the full list.
\defun {signal-process} {proc sig} \undefined
\defunx {signal-process-group} {prgrp sig} \undefined
@ -2290,24 +2391,194 @@ The \var{proc} and \var{prgrp} arguments are either processes
or integer process ids.
\end{desc}
I haven't done signal handlers yet. Should be straightforward: a mechanism
to assign procedures to signals.
\defun{itimer}{???} \undefined
\defunx{pause-until-interrupt}{} \undefined
\defun{sleep}{secs} \undefined
\defunx{sleep-until}{time}\undefined
\begin{desc}
Sleeping is defined, but we don't offer a way to sleep for a more precise
interval (\eg, a microsecond timer), as this is not in {\Posix}.
The \ex{sleep} procedure causes the process to sleep for \var{secs} seconds.
The \ex{sleep-until} procedure causes the process to sleep until \var{time}
(see section~\ref{sec:time}).
\end{desc}
\subsubsection{Interrupt handlers}
Scsh interrupt handlers are complicated by the fact that scsh is implemented on
top of the {\scm} virtual machine, which has its own interrupt system,
independent of the Unix signal system.
This means that {\Unix} signals are delivered in two stages: first,
{\Unix} delivers the signal to the {\scm} virtual machine, then
the {\scm} virtual machine delivers the signal to the executing Scheme program
as a {\scm} interrupt.
This ensures that signal delivery happens between two vm instructions,
keeping individual instructions atomic.
The {\scm} machine has its own set of interrupts, which includes the
asynchronous {\Unix} signals (table~\ref{table:signals-and-interrupts}).
\begin{table}
\begin{minipage}{\textwidth}
\begin{center}
\newcommand{\kwd}[1]{\index{\texttt{#1}}\texttt{#1}}
\begin{tabular}{lll}\hline
Interrupt & Unix signal & OS Variant \\ \hline\hline
\kwd{interrupt/alrm}\footnote{Also bound to {\scm} interrupt
\kwd{interrupt/alarm}.}
& \kwd{signal/alrm} & \Posix \\
%
\kwd{interrupt/int}\footnote{Also bound to {\scm} interrupt
\kwd{interrupt/keyboard}.}
& \kwd{signal/int} & \Posix \\
%
\kwd{interrupt/memory-shortage} & N/A & \\
\kwd{interrupt/chld} & \kwd{signal/chld} & \Posix \\
\kwd{interrupt/cont} & \kwd{signal/cont} & \Posix \\
\kwd{interrupt/hup} & \kwd{signal/hup} & \Posix \\
\kwd{interrupt/quit} & \kwd{signal/quit} & \Posix \\
\kwd{interrupt/term} & \kwd{signal/term} & \Posix \\
\kwd{interrupt/tstp} & \kwd{signal/tstp} & \Posix \\
\kwd{interrupt/usr1} & \kwd{signal/usr1} & \Posix \\
\kwd{interrupt/usr2} & \kwd{signal/usr2} & \Posix \\
\\
\kwd{interrupt/info} & \kwd{signal/info} & BSD only \\
\kwd{interrupt/io} & \kwd{signal/io} & BSD + SVR4 \\
\kwd{interrupt/poll} & \kwd{signal/poll} & SVR4 only \\
\kwd{interrupt/prof} & \kwd{signal/prof} & BSD + SVR4 \\
\kwd{interrupt/pwr} & \kwd{signal/pwr} & SVR4 only \\
\kwd{interrupt/urg} & \kwd{signal/urg} & BSD + SVR4 \\
\kwd{interrupt/vtalrm} & \kwd{signal/vtalrm} & BSD + SVR4 \\
\kwd{interrupt/winch} & \kwd{signal/winch} & BSD + SVR4 \\
\kwd{interrupt/xcpu} & \kwd{signal/xcpu} & BSD + SVR4 \\
\kwd{interrupt/xfsz} & \kwd{signal/xfsz} & BSD + SVR4 \\
\end{tabular}
\end{center}
\caption{{\scm} virtual-machine interrupts and related {\Unix} signals.
Only the {\Posix} signals are guaranteed to be defined; however,
your implementation and OS may define other signals and
interrupts not listed here.}
\end{minipage}
\label{table:signals-and-interrupts}
\end{table}
%
\begin{table}
\newcommand{\kwd}[1]{\index{\texttt{#1}}\texttt{#1}}
\begin{center}
\begin{tabular}{lll}\hline
Unix signal & Type & OS Variant \\ \hline\hline
\kwd{signal/stop} & Uncatchable & \Posix \\
\kwd{signal/kill} & Uncatchable & \Posix \\
\\
\kwd{signal/abrt} & Synchronous & \Posix \\
\kwd{signal/fpe} & Synchronous & \Posix \\
\kwd{signal/ill} & Synchronous & \Posix \\
\kwd{signal/pipe} & Synchronous & \Posix \\
\kwd{signal/segv} & Synchronous & \Posix \\
\kwd{signal/ttin} & Synchronous & \Posix \\
\kwd{signal/ttou} & Synchronous & \Posix \\
\\
\kwd{signal/bus} & Synchronous & BSD + SVR4 \\
\kwd{signal/emt} & Synchronous & BSD + SVR4 \\
\kwd{signal/iot} & Synchronous & BSD + SVR4 \\
\kwd{signal/sys} & Synchronous & BSD + SVR4 \\
\kwd{signal/trap} & Synchronous & BSD + SVR4 \\
\end{tabular}
\end{center}
\caption{Uncatchable and synchronous {\Unix} signals. While these signals
may be sent with \texttt{signal-process} or
\texttt{signal-process-group},
there are no corresponding scsh interrupt handlers.
Only the {\Posix} signals are guaranteed to be defined; however,
your implementation and OS may define other signals not listed
here.}
\label{table:uncatchable-signals}
\end{table}
Note that scsh does \emph{not} support signal handlers for ``synchronous''
{\Unix} signals, such as \ex{signal/ill} or \ex{signal/pipe}
(see table~\ref{table:uncatchable-signals}).
Synchronous occurrences of these signals are better handled by raising
a Scheme exception.
We recommend you avoid using signal handlers unless you absolutely have
to; we intend to provide a better, higher-level interface to {\Unix}
signals after scsh has been ported to a multi-threaded platform.
\begin{defundesc}{signal->interrupt}{\integer}{\integer}
The programmer maps from {\Unix} signals to {\scm} interrupts with the
\ex{signal->interrupt} procedure.
If the signal does not have a defined {\scm} interrupt, an errror is signaled.
\end{defundesc}
\begin{defundesc}{interrupt-set}{\zeroormore{\integer}}{\integer}
This procedure builds interrupt sets from its interrupt arguments.
A set is represented as an integer using a two's-complement representation of
the bit set.
\end{defundesc}
\defun{enabled-interrupts}{}{interrupt-set}
\defunx{set-enabled-interrupts}{interrupt-set}{interrupt-set}
\begin{desc}
Get and set the value of the enabled-interrupt set.
Only interrupts in this set have their handlers called when delivered.
When a disabled interrupt is delivered to the {\scm} machine, it is
held pending until it becomes enabled, at which time its handler is invoked.
Interrupt sets are represented as integer bit sets (constructed with
the \ex{interrupt-set} function).
The \ex{set-enabled-interrupts} procedure returns the previous value of
the enabled-interrupt set.
\end{desc}
\dfn {with-enabled-interrupts} {interrupt-set . body} {value(s) of body} {syntax}
\defunx{with-enabled-interrupts*}{interrupt-set thunk} {value(s) of thunk}
\begin{desc}
Run code with a given set of interrupts enabled.
Note that ``enabling'' an interrupt means enabling delivery from
the {\scm} vm to the scsh program.
Using the {\scm} interrupt system is fairly lightweight, and does not involve
actually making a system call.
Note that enabling an interrupt means that the assigned interrupt handler
is allowed to run when the interrupt is delivered.
Interrupts not enabled are held pending when delivered.
Interrupt sets are represented as integer bit sets (constructed with
the \ex{interrupt-set} function).
\end{desc}
\begin{defundesc}{set-interrupt-handler}{interrupt handler}{old-handler}
Assigns a handler for a given interrupt,
and returns the interrupt's old handler.
The \var{handler} argument is \ex{\#f} (ignore), \ex{\#t} (default), or a
procedure taking an integer argument;
the return value follows the same conventions.
Note that the \var{interrupt} argument is an interrupt value,
not a signal value.
An interrupt is delivered to the {\scm} machine by (1) blocking all interrupts,
and (2) applying the handler procedure to the set of interrupts
that were enabled prior to the interrupt delivery.
If the procedure returns normally (\ie, it doesn't throw to a continuation),
the set of enabled interrupts will be returned to its previous value.
(To restore the enabled-interrupt set before throwing out of an interrupt
handler, see \ex{set-enabled-interrupts})
\note{If you set a handler for the \ex{interrupt/chld} interrupt,
you may break scsh's autoreaping process machinery. See the
discussion of autoreaping in section~\ref{sec:proc-objects}.}
\end{defundesc}
\begin{defundesc}{interrupt-handler}{interrupt}{handler}
Return the handler for a given interrupt.
Note that the argument is an interrupt value, not a signal value.
A handler is either \ex{\#f} (ignore), \ex{\#t} (default), or a
procedure taking an integer argument.
\end{defundesc}
% %set-unix-signal-handler
% %unix-signal-handler
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Time}
\label{sec:time}
This time package does not currently work with NeXTSTEP, as NeXTSTEP
does not provide a {\Posix}-compliant time library that will even link.
Scsh's time system is fairly sophisticated, particularly with respect
to its careful treatment of time zones.
@ -2316,6 +2587,9 @@ all of the complexity is optional,
and defaulting all the optional arguments reduces the system
to a simple interface.
\remark{This time package does not currently work with NeXTSTEP, as NeXTSTEP
does not provide a {\Posix}-compliant time library that will even link.}
\subsection{Terminology}
``UTC'' and ``UCT'' stand for ``universal coordinated time,'' which is the
official name for what is colloquially referred to as ``Greenwich Mean

View File

@ -61,6 +61,18 @@ each operating system inevitably has non-standard extensions.
While a particular scsh implementation may provide these extensions,
they are not portable, and so are not documented here.
\subsection{Miscellaneous procedures}
\defun{tty?}{fd/port}{\boolean}
\begin{desc}
Return true if the argument is a tty.
\end{desc}
\defun{tty-file-name}{fd/port}{\str}
\begin{desc}
The argument \var{fd/port} must be a file descriptor or port open on a tty.
Return the file-name of the tty.
\end{desc}
\subsection{The tty-info record type}
The primary data-structure that describes a terminal's mode is
@ -317,14 +329,14 @@ If the scsh process already has a control terminal, the results are undefined.
To arrange for the process to have no control terminal prior to calling
this procedure, use the \ex{become-session-leader} procedure.
\oops{The control terminal code was added just before release time
for scsh release 0.4. Control terminals are one of the less-standardised
elements of Unix. We can't guarantee that the terminal is definitely
attached as a control terminal; we were only able to test this out
on HP-UX. If you intend to use this feature on your OS, you should
test it out first. If your OS requires the use of the \ex{TIOCSCTTY}
\ex{ioctl}, uncomment the appropriate few lines of code in the
file \ex{tty1.c} and send us email.}
%\oops{The control terminal code was added just before release time
% for scsh release 0.4. Control terminals are one of the less-standardised
% elements of Unix. We can't guarantee that the terminal is definitely
% attached as a control terminal; we were only able to test this out
% on HP-UX. If you intend to use this feature on your OS, you should
% test it out first. If your OS requires the use of the \ex{TIOCSCTTY}
% \ex{ioctl}, uncomment the appropriate few lines of code in the
% file \ex{tty1.c} and send us email.}
\end{desc}
\defun{become-session-leader}{}{\integer}
@ -352,6 +364,16 @@ This pair of procedures gets and sets the process group of a given
terminal.
\end{desc}
\defun{control-tty-file-name}{}{\str}
\begin{desc}
Return the file-name of the process' control tty.
On every version of Unix of which we are aware, this is just the string
\ex{"/dev/tty"}.
However, this procedure uses the official Posix interface, so it is more
portable than simply using a constant string.
\end{desc}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Pseudo-terminals}
Scsh implements an interface to Berkeley-style pseudo-terminals.

View File

@ -4,7 +4,7 @@
\documentclass[twoside]{report}
\usepackage{code,boxedminipage,draftfooters,makeidx,palatino,ct,
headings,mantitle,array,matter,mysize10,a4wide}
headings,mantitle,array,matter,a4}
% Style issues
\parskip = 3pt plus 3pt