Scsh cheat sheet Olin Shivers November 1994 This cheat sheet is intentionally kept brief and minimalist. It is intended to function as an ASCII-format reminder for the full manual, not as the definition. It can be read using GNU Emacs's outline mode. ------------------------------------------------------------------------------- * High-level forms Extended process form: (PF [REDIR1 ...]) Redirection: (< [FDES] FILE-NAME) (> [FDES] FILE-NAME) (<< [FDES] OBJECT) (= FDES FDES/PORT) (- FDES/PORT) stdports Subforms are implicitly backquoted. Process form: (| PF1 ...) ; pipeline (|+ CONNECT-LIST PF1 ...) ; complex pipeline (begin . BODY) ; Scheme form (epf . EPF) ; Embedded extended process form (PROG ARG1 ... ARGn) ; Exec a program Subforms are implicitly backquoted. Using process forms in Scheme: (exec-epf . EPF) ; Nuke the current process. (& . EPF) ; Fork process in background. Return pid. (run . EPF) ; Run process. Return exit code. (& . EPF) = (fork (lambda () (exec-epf . EPF))) (run . EPF) = (wait (& . EPF)) Interfacing to subprocess I/O: (run/port . EPF) -> port (run/file . EPF) -> string (run/string . EPF) -> string (run/strings . EPF) -> string list (run/sexp . EPF) -> object (run/sexps . EPF) -> list There are procedural equivalents for each of these, e.g., run/port* and run/file*, that take thunk arguments for the subprocess. (port->string PORT) -> string Read until EOF on PORT, return data as a string. (port->string-list PORT) -> string list Repeatedly apply READ-LINE to PORT until EOF. Return list of lines read. (port->sexp-list PORT) -> list Repeatedly apply READ to PORT until EOF. Return list of items read. (port->list READER PORT) Repeatedly apply READER to PORT until EOF. Return list of items read. (reduce-port PORT READER OP . SEEDS) Evaluate (OP (READER PORT) . SEEDS) to get a new set of seeds (OP must return as many values as there are SEEDS). When a port read returns EOF, the current set of seed values are returned as multiple values. (run/port+pid . EPF) -> [port fixnum] (run/port+pid* THUNK) -> [port fixnum] (run/collecting FDS . EPF) -> [port ...] (run/collecting* FDS THUNK) -> [port ...] RUN/COLLECTING implicitly backquotes FDS. (|| PF1 ... PFn) (&& PF1 ... PFn) Conditionally execute processes. (char-filter filter) -> procedure (string-filter filter [buflen]) -> procedure * System calls ** Errors (errno-error errno SYSCALL . DATA) (with-errno-handler* HANDLER THUNK) -> value of thunk HANDLER is called on two arguments: (HANDLER ERRNO PACKET) where PACKET is a list of the form (ERRNO-MSG SYSCALL . DATA) If HANDLER returns at all, the handler search continues upwards. (with-errno-handler HANDLER-SPEC . BODY) HANDLER-SPEC is of the form ((ERRNO PACKET) CLAUSE ...) ERRNO and PACKET are variables bound to the errno error being raised. There are two forms for handler clauses: ((ERRNO ...) . BODY) (else . BODY) ERRNO are expressions evaluating to errno integers. ** I/O *** Port Manipulation (close-after PORT CONSUMER) -> value(s) of consumer (error-output-port) -> port (with-current-input-port port . body) -> value(s) of body (with-current-output-port port . body) -> value(s) of body (with-error-output-port port . body) -> value(s) of body (with-current-input-port* port thunk) -> value(s) of thunk (with-current-output-port* port thunk) -> value(s) of thunk (with-error-output-port* port thunk) -> value(s) of thunk (close port/fd) (stdports->stdio) (stdio->stdports) (with-stdio-ports* thunk) -> value(s) of thunk (with-stdio-ports . body) -> value(s) of body (make-string-input-port) -> port (string-output-port-output port) -> port (call-with-string-output-port proc) -> str ** Port and file descriptors (fdes->inport fd) -> port (fdes->outport fd) -> port (port->fdes port) -> fixnum Increment port's revealed count. (port-revealed port) -> integer or #f (release-port-handle port) (call/fdes fd/port consumer) -> value(s) of consumer (move->fdes fd/port target-fd) -> port or fdes ** Unix I/O (dup port/fd [newfd]) -> port/fd (dup->inport port/fd [newfd]) -> port (dup->outport port/fd [newfd]) -> port (dup->fdes port/fd [newfd]) -> fd (file-seek fd/port offset whence) (open-file fname flags [perms]) -> port (open-input-file fname [flags]) -> port (open-output-file fname [flags perms]) -> port (open-fdes fname flags [perms]) -> integer Open flags: 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 (pipe) -> [rport wport] (read-line [fd/port retain-newline?]) -> string or eof-object (read-string nbytes [fd/port]) -> string or #f (read-string! str [fd/port start end]) -> [nread or #f] (read-string/partial nbytes [fd/port]) -> string or #f (read-string!/partial str [fd/port start end]) -> [nread or #f] (write-string string [fd/port start end]) (write-string/partial string [fd/port start end]) -> nwritten (force-output [fd/port]) ** File system (create-directory fname [perms override?]) (create-fifo fname [perms override?]) (create-hard-link oldname newname [override?]) OVERRIDE? one of {#f, QUERY, other true value} (delete-directory fname) (delete-file fname) (delete-filesys-object fname) (read-symlink fname) -> string (rename-file old-fname new-fname [override?]) (set-file-mode fname/fd/port mode) (set-file-owner fname/fd/port uid) (set-file-group fname/fd/port gid) (sync-file fd/port) (sync-file-system) (truncate-file fname/fd/port len) (file-attributes fname/fd/port [chase?]) -> file-info (define-record file-info type ; {block-special, char-special, directory, ; fifo, regular, socket, symlink} device ; Device file resides on. inode ; File's inode. mode ; File's permission bits. nlinks ; Number of hard links to this file. uid ; Owner of file. gid ; File's group id. size ; Size of file, in bytes. atime ; Last access time. mtime ; Last status-change time. ctime) ; Creation time. Derived procedures: file-type type file-inode inode file-mode mode file-nlinks nlinks file-owner uid file-group gid file-size size file-last-access atime file-last-mod mtime file-last-status-change ctime (file-not-readable? fname) -> boolean (file-not-writable? fname) -> boolean (file-not-executable? fname) -> boolean Returns one of #f Access permitted SEARCH-DENIED Can't stat---a protected directory is blocking access. PERMISSION Permission denied. NO-DIRECTORY Some directory doesn't exist. NONEXISTENT File doesn't exist. (file-readable? fname) -> boolean (file-writable? fname) -> boolean (file-executable? fname) -> boolean (file-not-exists? fname [chase?]) -> boolean #f Exists. SEARCH-DENIED Some protected directory is blocking the search. #t Doesn't exist. (file-exists? fname [chase?]) -> boolean (directory-files [dir dotfiles?]) -> string list (glob pat1 ...) -> string list (glob-quote string) -> string (file-match root dot-files? pat1 ...) -> string list (create-temp-file [prefix]) -> string (temp-file-iterate maker [template]) -> [object ...] TEMPLATE defaults to the value of *TEMP-FILE-TEMPLATE*. (temp-file-channel) -> [inport outport] ** Processes (exec prog arg1 ...) (exec-path prog arg1 ...) (exec/env prog env arg1 ...) (exec-path/env prog env arg1 ...) (%exec prog arglist env) (exec-path-search fname pathlist) -> string (exit [status]) (%exit [status]) (suspend) (fork [thunk]) -> pid or #d (%fork [thunk]) -> pid or #f (fork/pipe [thunk]) -> pid or #f (%fork/pipe [thunk]) -> pid or #f (fork/pipe+ conns [thunk]) pid or #f (%fork/pipe+ conns [thunk]) pid or #f (wait [pid]) -> status [pid] (call-terminally thunk) ** Process state (umask) -> fixnum (set-umask perms) (with-umask* perms thunk) -> values of thunk (with-umask perms . body) -> values of body (chdir [fname]) (cwd) -> string (with-cwd* fname thunk) -> value(s) of thunk (with-cwd fname . body) -> value(s) of body (pid) -> fixnum (parent-pid) -> fixnum (process-group [pid]) -> fixnum (set-process-group [pid] pgrp) (user-login-name) -> string (user-uid) -> fixnum (user-effective-uid) -> fixnum (user-gid) -> fixnum (user-effective-gid) -> fixnum (user-supplementary-gids) -> fixnum list (set-uid uid) (set-gid gid) (process-times) -> [ucpu scpu uchildren schildren] ** User and group db access (user-info uid-or-name) -> user-info (define-record user-info name uid gid home-dir shell) (->uid uid/name) -> fixnum (->username uid/name) -> string (group-info gid-or-name) -> record (define-record group-info name gid members) ; List of uids (->gid gid/name) -> fixnum (->group gid/name) -> string ** Accessing command-line arguments command-line-arguments Does not include program name (command-line) -> string list Includes program name in list. (arg arglist n [default]) -> string (arg* arglist n [default-thunk]) -> string (argv n [default]) -> string ARG is 1-based access to ARGLIST ARGV is 0-based access to prog + args ** System parameters (system-name) -> string ** Signal system (signal-process pid sig) (signal-procgroup prgrp sig) (pause-until-interrupt) (sleep secs) ** Time (define-record date seconds minute hour month-day month year tz-name tz-secs summer? week-day year-day) (make-date sec min hour mday month year [tz-name tz-secs summer? wday yday]) (time+ticks) (ticks/sec) (date [time tz]) (time [date]) (date->string date) (format-date fmt date) ** Environment variables (setenv var val) (getenv var) -> string (env->alist) -> string->string alist (alist->env alist) (alist-delete key alist) -> alist (alist-update key val alist) -> alist (alist-compress alist) -> alist (with-env* env-alist-delta thunk) -> value(s) of thunk (with-total-env* env-alist thunk) -> value(s) of thunk (with-env env-alist-delta . body) -> value(s) of body (with-total-env env-alist . body) -> value(s) of body (add-before elt before list) -> list (add-after elt after list) -> list ** $USER $HOME, and $PATH home-directory exec-path-list * Networking ** High Level Socket Routines *** clients (socket-connect protocol-family/internet socket-type name port) -> socket (socket-connect protocol-family/unix socket-type pathname) -> socket *** server (bind-listen-accept-loop protocol-family/internet proc port) -> does-not-return (bind-listen-accept-loop protocol-family/unix proc pathname) -> does-not-return proc is a procedure of two arguments: a socket and a socket-address ** Sockets (create-socket protocol-family type [protocol]) -> socket (create-socket-pair type) -> [socket1 socket2] (close-socket socket) -> undefined protocol-family/unix protocol-family/internet socket-type/stream socket-type/datagram for protocol see protocol-info (define-record socket family inport outport) ** Socket Addresses (define-record socket-address family) (unix-address->socket-address pathname) -> socket-address (internet-address->socket-address host-address service-port)-> socket-address internet-address/any internet-address/loopback internet-address/broadcast (socket-address->unix-address socket-address) -> pathname (socket-address->internet-address socket-address) -> [host-address service-port] ** Low Level Socket Routines (connect-socket socket socket-address) -> undefined (bind-socket socket socket-address) -> undefined (listen-socket socket backlog) -> undefined (accept-connection socket) -> [new-socket socket-address] (socket-local-address socket) -> socket-address (socket-remote-address socket) -> socket-address (shutdown-socket socket how-to) -> undefined how-to: shutdown/receives shutdown/sends shutdown/sends+receives ** Socket Specific I/O see read-string/write-string for info on arguments (receive-message socket length [flags]) -> [string-or-#f socket-address] (receive-message! socket string [start] [end] [flags]) -> [count-or-#f socket-address] (receive-message/partial socket length [flags]) -> [string-or-#f socket-address] (receive-message!/partial socket string [start] [end] [flags]) -> [count-or-#f socket-address] (send-message socket string [start] [end] [flags] [socket-address] -> undefined (send-message/partial socket string [start] [end] [flags] [socket-address]) -> count ** Socket Options (socket-option socket level option) -> value (set-socket-option socket level option value) -> undefined boolean: socket/debug socket/accept-connect socket/reuse-address socket/keep-alive socket/dont-route socket/broadcast socket/use-loop-back socket/oob-inline socket/use-privileged socket/cant-signal tcp/no-delay value: socket/send-buffer socket/receive-buffer socket/send-low-water socket/receive-low-water socket/error socket/type ip/time-to-live tcp/max-segment socket/linger is #f or integer seconds real number with microsecond resolution: socket/send-timeout socket/receive-timeout ** Database-information entries (host-info name-or-socket-address) -> host-info (network-info name-or-socket-address) -> network-info (service-info name-or-number [protocol-name]) -> service-info (protocol-info name-or-number) -> protocol-info (define-record host-info name aliases addresses) (define-record network-info name aliases net) (define-record service-info name aliases port protocol) (define-record protocol-info name aliases number) * String manipulation ** Regular expressions (string-match regexp string [start]) -> match or false (regexp-match obj) -> boolean (match:start match [match-number]) -> fixnum (match:end match [match-number]) -> fixnum (match:substring match [match-number]) -> string (make-regexp str) -> re (regexp? obj) -> boolean (regexp-exec regexp str [start]) -> match or false (regexp-quote str) -> string ** Other string manipulation facilities (index string char [start]) -> fixnum or false (rindex string char [start]) -> fixnum or false (substitute-env-vars fname) -> string ** Manipulating file-names ** Record I/O and field parsing (read-delimited char-set [port]) -> string or eof (read-delimited! char-set buf [port start end]) -> nchars or #f or eof ((record-reader [delims elide-delims? handle-delim]) [port]) -> string or eof HANDLE-DELIM one of {trim, split, concat} (read-paragraph [port delimiter?]) ** Parsing fields (field-splitter [regexp num-fields]) -> parser (infix-splitter [delim num-fields handle-delim]) -> parser (suffix-splitter [delim num-fields handle-delim]) -> parser (sloppy-suffix-splitter [delim num-fields handle-delim]) -> parser Where (parser string [start]) HANDLE-DELIM one of {trim, concat, split} (join-strings strings [delimiter grammar]) GRAMMAR one of {infix, suffix} ** Field readers (field-reader [field-parser record-reader]) * Awk (awk [] . . ) * Miscellaneous routines ** Integer bitwise ops (arithmetic-shift i j) -> integer (bitwise-and i j) -> integer (bitwise-ior i j) -> integer (bitwise-not i) -> integer (bitwise-xor i j) -> integer ** ASCII encoding (char->ascii \character) -> integer (ascii->char \integer) -> character ** Top level (repl) * Running scsh scsh [end-option arg1 ...] end-option: -s script -- scshvm [meta-arg] [vm-options] [end-option arg1 ...] meta-arg: \ vm-options: -h heap-size -s stack-size -o object-file end-option: -i image-file -- (dump-scsh-program main fname) ** File locations /usr/local/bin/scsh /usr/local/lib/scsh/ scshvm scsh scsh.image doc/