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 \parskip = 3pt plus 3pt
\sloppy \sloppy
%\includeonly{syscalls}
\input{decls} \input{decls}
\makeindex \makeindex
%%% End preamble %%% 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}. \ex{exec-epf}, \cd{&}, and \ex{run}.
\dfn {exec-epf} {. \var{epf}} {\noreturn} {syntax} \dfn {exec-epf} {. \var{epf}} {\noreturn} {syntax}
\dfnx {\&} {. \var{epf}} {\integer} {syntax} \dfnx {\&} {. \var{epf}} {proc} {syntax}
\dfnx {run} {. \var{epf}} {\integer} {syntax} \dfnx {run} {. \var{epf}} {proc} {syntax}
\begin{desc} \begin{desc}
\index{exec-epf} \index{\&} \index{run} \index{exec-epf} \index{\&} \index{run}
The \ex{(exec-epf . \var{epf})} form nukes the current process: it establishes 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} \dfnx{run/sexps} {. \var{epf}} {list} {syntax}
\begin{desc} \begin{desc}
These forms all fork off subprocesses, collecting the process' output 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} \begin{desctable}{0.7\linewidth}
\ex{run/port} & Value is a port open on process's stdout. \ex{run/port} & Value is a port open on process's stdout.
Returns immediately after forking child. \\ Returns immediately after forking child. \\

View File

@ -31,6 +31,8 @@ There are four possible choices for a \ex{handle-delim} parameter:
\hline \hline
\end{tabular} \end{tabular}
\end{inset} \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 The last three cases allow the programmer to distinguish between strings
that are terminated by a delimiter character, and strings that are that are terminated by a delimiter character, and strings that are
terminated by an end-of-file. terminated by an end-of-file.
@ -68,7 +70,7 @@ See section~\ref{sec:char-sets} for information on character set manipulation.
\begin{desc} \begin{desc}
Read until we encounter one of the chars in \var{char-set} or eof. Read until we encounter one of the chars in \var{char-set} or eof.
The \var{handle-delim} parameter determines how the terminating character 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 The \var{char-set} argument may be a charset, a string, a character, or a
character predicate; it is coerced to a charset. 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 If an integer is returned (\ie, the read is successfully terminated by
reading a delimiter character), then the \var{handle-delim} parameter reading a delimiter character), then the \var{handle-delim} parameter
determines how the terminating character is handled. 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} \end{desc}
@ -137,3 +139,10 @@ the procedure call.
% fills up, %READ-DELIMITED! will peek at one more character from the % fills up, %READ-DELIMITED! will peek at one more character from the
% input stream to determine if it terminates the input. If so, that % input stream to determine if it terminates the input. If so, that
% is returned, not #f. % 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. \\ & \ex{-ds} & Do script. \\
\\ \\
\var{end-option:} & \ex{-s} \var{script} \\ \var{end-option:} & \ex{-s} \var{script} \\
& \ex{-sfd} \var{num} \\
& \ex{-c} \var{exp} \\ & \ex{-c} \var{exp} \\
& \ex{--} & \ex{--}
\end{tabular} \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 by the switch-scanner and are passed through to the program as
the tail of the command-line list. 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{--} \Item{--}
Terminate argument scanning and start up scsh in interactive mode. Terminate argument scanning and start up scsh in interactive mode.
If the argument list just runs out, without either a terminating 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, six space characters, but you really have a tab character,
and \emph{vice-versa}. and \emph{vice-versa}.
\item The newline character terminates the sequence of arguments, \item The newline character terminates an argument, like the space character,
and will also terminate a final non-empty argument. and also terminates the argument sequence.
(However, a newline following a space does not introduce a final This means that an empty line parses to the singleton list whose one
empty-string argument; it only terminates the argument list.) element is the empty string: \ex{("")}.
The grammar doesn't admit the empty list.
\item The backslash character is the escape character. \item The backslash character is the escape character.
It escapes backslash, space, tab, and newline, turning off their It escapes backslash, space, tab, and newline, turning off their
special functions, and allowing them to be included in arguments. special functions, and allowing them to be included in arguments.
The {\Ansi} C escape sequences, such as \verb|\n| and \verb|\t| are The {\Ansi} C escape sequences (\verb|\b|, \verb|\n|, \verb|\r|
also supported; these also produce argument-constituents---\verb|\n| and \verb|\t|) are also supported;
doesn't act like a terminating newline. these also produce argument-constituents---\verb|\n| doesn't act
like a terminating newline.
The escape sequence \verb|\|\emph{nnn} for \emph{exactly} three The escape sequence \verb|\|\emph{nnn} for \emph{exactly} three
octal digits reads as the character whose {\Ascii} code is \emph{nnn}. 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: 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 \\ sort foo bar
{\evalto} /usr/local/bin/scsh -dm -m sort-toplevel -e top -s sort foo bar\end{centercode}} {\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. sequence of switches to specify a top-level package.
\end{itemize} \end{itemize}
@ -580,8 +593,9 @@ If these computations terminate with no errors, the scsh process
exits with an exit code of 0. exits with an exit code of 0.
To return a specific exit status, use the \ex{exit} procedure explicitly, \eg, 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} \section{The scsh virtual machine}
To run the {\scm} implementation of scsh, you run a specially modified 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}. Returns the start position of the match denoted by \var{match-number}.
The whole regexp is 0. Each further number represents positions The whole regexp is 0. Each further number represents positions
enclosed by \ex{(\ldots)} sections. \var{Match-number} defaults to 0. 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} \end{defundesc}
\begin{defundesc} {match:end} {match [match-number]} \fixnum \begin{defundesc} {match:end} {match [match-number]} \fixnum
Returns the end position of the match denoted by \var{match-number}. Returns the end position of the match denoted by \var{match-number}.
\var{Match-number} defaults to 0 (the whole match). \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} \end{defundesc}
\begin{defundesc} {match:substring} {match [match-number]} \str \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). \var{Match-number} defaults to 0 (the whole match).
\end{defundesc} \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 Regular expression matching compiles patterns into special data
structures which can be efficiently used to match against strings. structures which can be efficiently used to match against strings.
The overhead of compiling patterns that will be used for multiple 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. otherwise {\sharpf}. \var{Start} defaults to 0.
\end{defundesc} \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} \defun{regexp-quote}{str}{\str}
\begin{desc} \begin{desc}
Returns a regular expression that matches the string \var{str} exactly. 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 For reference purposes, the {\Unix} \ex{errno} numbers
are bound to the variables \ex{errno/perm}, \ex{errno/noent}, {\etc} are bound to the variables \ex{errno/perm}, \ex{errno/noent}, {\etc}
System calls never return \ex{error/intr}---they System calls never return \ex{error/intr}---they
automatically retry. (Currently only true for I/O calls.) automatically retry.
\begin{dfndesc} \begin{dfndesc}
{errno-error}{errno syscall .\ data}{\noreturn}{procedure} {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 If the programmer wishes to abort a system call on an interrupt, he
should have the interrupt handler explicitly raise an exception or should have the interrupt handler explicitly raise an exception or
invoke a stored continuation to throw out of the system call. 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} \end{dfndescx}
@ -195,13 +191,13 @@ These procedures alter the dynamic binding of the current I/O port procedures
to new values. to new values.
\end{desc} \end{desc}
\defun {close} {port/fd} {\boolean} \defun {close} {fd/port} {\boolean}
\begin{desc} \begin{desc}
Close the port or file descriptor. 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 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 count set to zero. This reflects the design criteria that ports are not
associated with file descriptors, but with open files. associated with file descriptors, but with open files.
@ -238,9 +234,9 @@ to new values.
descriptors. descriptors.
It is exactly equivalent to the series of assignments It is exactly equivalent to the series of assignments
\begin{code} \begin{code}
(set-current-input-port! (fdes->inport 0)) (set-current-input-port! (fdes->inport 0))
(set-current-output-port! (fdes->inport 1)) (set-current-output-port! (fdes->outport 1))
(set-error-output-port! (fdes->inport 2))\end{code} (set-error-output-port! (fdes->outport 2))\end{code}
However, you are more likely to find the dynamic-extent variant, However, you are more likely to find the dynamic-extent variant,
\ex{with-stdio-ports*}, below, to be of use in general programming. \ex{with-stdio-ports*}, below, to be of use in general programming.
\end{desc} \end{desc}
@ -275,7 +271,7 @@ interface described herein may be liable to change.
\end{desc} \end{desc}
\defun {make-string-output-port} {} {\port} \defun {make-string-output-port} {} {\port}
\defunx {string-output-port-output} {port} {\port} \defunx {string-output-port-output} {port} {\str}
\begin{desc} \begin{desc}
A string output port is a port that collects the characters given to it into A string output port is a port that collects the characters given to it into
a string. 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 \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 \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. 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. \ex{call/fdes} uses \ex{dynamic-wind} to enforce the protocol.
If \var{proc} throws out of the \ex{call/fdes} application, If \var{proc} throws out of the \ex{call/fdes} application,
the unwind handler releases the descriptor handle; the unwind handler releases the descriptor handle;
@ -523,20 +519,20 @@ Decrement the port's revealed count.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{{\Unix} I/O} \subsection{{\Unix} I/O}
\defun {dup} {port/fd [newfd]} {port/fd} \defun {dup} {fd/port [newfd]} {fd/port}
\defunx{dup->inport} {port/fd [newfd]} {port} \defunx{dup->inport} {fd/port [newfd]} {port}
\defunx{dup->outport} {port/fd [newfd]} {port} \defunx{dup->outport} {fd/port [newfd]} {port}
\defunx{dup->fdes} {port/fd [newfd]} {fd} \defunx{dup->fdes} {fd/port [newfd]} {fd}
\begin{desc} \begin{desc}
These procedures provide the functionality of C's \ex{dup()} and \ex{dup2()}. These procedures provide the functionality of C's \ex{dup()} and \ex{dup2()}.
The different routines return different types of values: The different routines return different types of values:
\ex{dup->inport}, \ex{dup->outport}, and \ex{dup->fdes} return \ex{dup->inport}, \ex{dup->outport}, and \ex{dup->fdes} return
input ports, output ports, and integer file descriptors, respectively. input ports, output ports, and integer file descriptors, respectively.
\ex{dup}'s return value depends on on the type of \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 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 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()}. the dup operation, \ie, the operation is a \ex{dup2()}.
In this case, procedures that return a port (such as \ex{dup->inport}) 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} \begin{defundesc} {open-file} {fname flags [perms]} {\port}
\var{Perms} defaults to \cd{#o666}. \var{Perms} defaults to \cd{#o666}.
\var{Flags} is an integer bitmask, composed by or'ing together the following \var{Flags} is an integer bitmask, composed by or'ing together constants
constants: listed in table~\ref{table:fdes-status-flags}
\begin{code}\codeallowbreaks (page~\pageref{table:fdes-status-flags}).
open/read ; You may only You must use exactly one of the \ex{open/read}, \ex{open/write}, or
open/write ; choose one \ex{open/read+write} flags.
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}
% %
Returns a port. The port is an input port if the \var{flags} permit it, 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, 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 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, 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}.) and duping it to an output port with \ex{dup->outport}.)
\end{defundesc} \end{defundesc}
\defun{open-input-file}{fname [flags]}\port \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. Returns a file descriptor.
\end{defundesc} \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}]} \begin{defundesc}{pipe}{} {[\var{rport} \var{wport}]}
Returns two ports, the read and write end-points of a {\Unix} pipe. 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. of any particular read operation.
\end{desc} \end{desc}
\defun {select }{rvec wvec evec [timeout]}{rvec' wvec' evec'} \defun {select }{rvec wvec evec [timeout]}{[rvec' wvec' evec']}
\defunx{select!}{rvec wvec evec [timeout]}{nr nw ne} \defunx{select!}{rvec wvec evec [timeout]}{[nr nw ne]}
\begin{desc} \begin{desc}
The \ex{select} procedure allows a process to block and wait for events on The \ex{select} procedure allows a process to block and wait for events on
multiple I/O channels. multiple I/O channels.
@ -849,14 +919,14 @@ buffering is turned off
$\var{policy} = \ex{bufpol/none}$). $\var{policy} = \ex{bufpol/none}$).
\end{defundesc} \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 This procedure does nothing when applied to an integer file descriptor
or unbuffered port. or unbuffered port.
It flushes buffered output when applied to a buffered port, It flushes buffered output when applied to a buffered port,
and raises a write-error exception on error. Returns no value. and raises a write-error exception on error. Returns no value.
\end{defundesc} \end{defundesc}
\begin{defundesc}{flush-all-ports} {}{\noreturn} \begin{defundesc}{flush-all-ports} {}{\undefined}
This procedure flushes all open output ports with buffered data. This procedure flushes all open output ports with buffered data.
\end{defundesc} \end{defundesc}
@ -877,6 +947,11 @@ not with associated open file descriptors.
Once a process locks a file, using some file descriptor \var{fd}, Once a process locks a file, using some file descriptor \var{fd},
the next time \emph{any} file descriptor referencing that file is closed, the next time \emph{any} file descriptor referencing that file is closed,
all associated locks are released. 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 Scsh moves Scheme ports from file descriptor to file descriptor with
\ex{dup()} and \ex{close()} as required by the runtime, \ex{dup()} and \ex{close()} as required by the runtime,
so it is impossible to keep file locks open across one of these shifts. 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 NeXTSTEP users should also note that even minimalist {\Posix} file locking
is not supported for NFS-mounted files in NeXTSTEP; NeXT claims they will is not supported for NFS-mounted files in NeXTSTEP; NeXT claims they will
fix this in NS release 4. 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 {\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 start
len len
whence whence
pid)\end{code} proc)\end{code}%
\index{lock-region?} \index{lock-region?}%
\index{lock-region:exclusive?} \index{lock-region:whence} \index{lock-region:exclusive?} \index{lock-region:whence}%
\index{lock-region:start} \index{lock-region:end} \index{lock-region:start} \index{lock-region:end}%
\index{lock-region:len} \index{lock-region:pid} \index{lock-region:len} \index{lock-region:proc}%
% %
\begin{itemize}
\item
The \ex{exclusive?} field is true if the lock is exclusive; The \ex{exclusive?} field is true if the lock is exclusive;
false if it is shared. false if it is shared.
\item
The \ex{whence} field is one of the values from the \ex{seek} call: The \ex{whence} field is one of the values from the \ex{seek} call:
\ex{seek/set}, \ex{seek/delta}, or \ex{seek/end}, \ex{seek/set}, \ex{seek/delta}, or \ex{seek/end},
and determines the interpretation of the \ex{start} field: 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 of the file.
\end{itemize} \end{itemize}
The region of the file being locked is given by the \ex{start} and \ex{len} The region of the file being locked is given by the \ex{start} and \ex{len}
fields. fields;
The \ex{pid} field gives the process id of the process holding the region 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). lock, when relevant (see \ex{get-lock-region} below).
\end{itemize}
\begin{defundesc}{make-lock-region}{exclusive? start len [whence]}{lock-region} \begin{defundesc}{make-lock-region}{exclusive? start len [whence]}{lock-region}
This procedure makes a lock-region record. 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 \ex{lock-region} procedure blocks until the lock is granted;
the non-blocking variant returns a boolean indicating whether or not the non-blocking variant returns a boolean indicating whether or not
the lock was granted. 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} \end{desc}
\begin{defundesc}{get-lock-region}{fdes lock}{lock-region or \sharpf} \begin{defundesc}{get-lock-region}{fdes lock}{lock-region or \sharpf}
Return the first lock region on \var{fdes} that overlaps with Return the first lock region on \var{fdes} that would conflict with
the lock region \var{lock}. lock region \var{lock}.
If there is no such lock, return false. If there is no such lock region, return false.
This procedure fills out the \ex{pid} field of the returned lock region, 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. 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} \end{defundesc}
\begin{defundesc}{unlock-region}{fdes lock}{\undefined} \begin{defundesc}{unlock-region}{fdes lock}{\undefined}
@ -1705,7 +1801,7 @@ Suspend the current process with a SIGSTOP signal.
\begin{code} \begin{code}
(fork (\l{} (fork/pipe a) (b)))\end{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: 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) (fork/pipe b)
(c)))\end{code} (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. Note that these procedures affect file descriptors, not ports.
That is, the pipe is allocated connecting the child's file descriptor 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} \begin{description}
\item [early] \item [early]
The child is reaped from the {\Unix} kernel's process table The child is reaped from the {\Unix} kernel's process table
into scsh as soon as possible after it dies. In the current into scsh as soon as it dies. This is done by having a
release of scsh, this happens at the next call to signal handler for the \ex{SIGCHLD} signal reap the process.
\ex{wait}---when scsh is asked to wait for a particular \emph{
child to exit, it will reap \emph{all} outstanding zombies. If a scsh program sets its own handler for the \ex{SIGCHLD}
When signal handlers are added to a future release of scsh, signal, the handler must reap dead children
early autoreaping will use the \ex{SIGCHLD} signal to reap by calling \ex{wait}, \ex{wait-any}, or \ex{reap-zombies}.}
zombies with minimum delay. We deprecate interrupt-driven code, and hope to provide
alternative tools in a future, multi-threaded release of scsh.
\item [late] \item [late]
The child is not autoreaped until it dies \emph{and} the scsh program The child is not autoreaped until it dies \emph{and} the scsh program
drops all pointers to its process object. That is, the process drops all pointers to its process object. That is, the process
table is cleaned out during garbage collection. 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] \item [\sharpf]
If autoreaping is turned off, process reaping is completely under If autoreaping is turned off, process reaping is completely under
@ -2043,8 +2143,8 @@ Otherwise, this function returns false.
\defun {umask}{} \fixnum \defun {umask}{} \fixnum
\defunx {set-umask} {perms} \undefined \defunx {set-umask} {perms} \undefined
\defunx {with-umask*} {perms thunk} {values of thunk} \defunx {with-umask*} {perms thunk} {value(s) of thunk}
\dfnx {with-umask} {perms . body} {values of body} {syntax} \dfnx {with-umask} {perms . body} {value(s) of body} {syntax}
\begin{desc} \begin{desc}
The process' current umask is retrieved with \ex{umask}, and set with The process' current umask is retrieved with \ex{umask}, and set with
\ex{(set-umask \var{perms})}. Calling \ex{with-umask*} changes the umask \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 \defun {pid}{} \fixnum
\defunx {parent-pid}{} \fixnum \defunx {parent-pid}{} \fixnum
\defunx {process-group} {} \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} \begin{desc}
\ex{(pid)} and \ex{(parent-pid)} retrieve the process id for the \ex{(pid)} and \ex{(parent-pid)} retrieve the process id for the
current process and its parent. current process and its parent.
\ex{(process-group)} returns the process group of the current process. \ex{(process-group)} returns the process group of the current process.
A process' process-group can be set with \ex{set-process-group}; 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 a process object or an integer process id, and defaults to the current
process. process.
\end{desc} \end{desc}
\defun {set-priority} {which who priority} \undefined %; priority stuff unimplemented \defun {set-priority} {which who priority} \undefined %; priority stuff unimplemented
\defunx {priority} {which who} \fixnum % ; not implemented \defunx {priority} {which who} \fixnum % ; not implemented
\defunx {nice} {[pid delta]} \undefined %; not implemented \defunx {nice} {[proc/pid delta]} \undefined %; not implemented
\begin{desc} \begin{desc}
These procedures set and access the priority of processes. These procedures set and access the priority of processes.
I can't remember how \ex{set-priority} and \ex{priority} work, so no 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} \section{Signal system}
Signal numbers are bound to the variables \ex{signal/hup}, \ex{signal/int}, 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 \defun {signal-process} {proc sig} \undefined
\defunx {signal-process-group} {prgrp 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. or integer process ids.
\end{desc} \end{desc}
I haven't done signal handlers yet. Should be straightforward: a mechanism
to assign procedures to signals.
\defun{itimer}{???} \undefined \defun{itimer}{???} \undefined
\defunx{pause-until-interrupt}{} \undefined \defunx{pause-until-interrupt}{} \undefined
\defun{sleep}{secs} \undefined \defun{sleep}{secs} \undefined
\defunx{sleep-until}{time}\undefined
\begin{desc} \begin{desc}
Sleeping is defined, but we don't offer a way to sleep for a more precise The \ex{sleep} procedure causes the process to sleep for \var{secs} seconds.
interval (\eg, a microsecond timer), as this is not in {\Posix}. The \ex{sleep-until} procedure causes the process to sleep until \var{time}
(see section~\ref{sec:time}).
\end{desc} \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} \section{Time}
\label{sec: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 Scsh's time system is fairly sophisticated, particularly with respect
to its careful treatment of time zones. 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 and defaulting all the optional arguments reduces the system
to a simple interface. 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} \subsection{Terminology}
``UTC'' and ``UCT'' stand for ``universal coordinated time,'' which is the ``UTC'' and ``UCT'' stand for ``universal coordinated time,'' which is the
official name for what is colloquially referred to as ``Greenwich Mean 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, While a particular scsh implementation may provide these extensions,
they are not portable, and so are not documented here. 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} \subsection{The tty-info record type}
The primary data-structure that describes a terminal's mode is 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 To arrange for the process to have no control terminal prior to calling
this procedure, use the \ex{become-session-leader} procedure. this procedure, use the \ex{become-session-leader} procedure.
\oops{The control terminal code was added just before release time %\oops{The control terminal code was added just before release time
for scsh release 0.4. Control terminals are one of the less-standardised % 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 % 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 % 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 % 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} % 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 % \ex{ioctl}, uncomment the appropriate few lines of code in the
file \ex{tty1.c} and send us email.} % file \ex{tty1.c} and send us email.}
\end{desc} \end{desc}
\defun{become-session-leader}{}{\integer} \defun{become-session-leader}{}{\integer}
@ -352,6 +364,16 @@ This pair of procedures gets and sets the process group of a given
terminal. terminal.
\end{desc} \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} \subsection{Pseudo-terminals}
Scsh implements an interface to Berkeley-style pseudo-terminals. Scsh implements an interface to Berkeley-style pseudo-terminals.

View File

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