| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Gauche supports most of POSIX.1 functions and other system functions popular among Unix variants as built-in procedures.
Lots of Scheme implementations provide some sort of system interface
under various APIs. Some are just called by different names
(e.g, delete-file or remove-file or unlink to delete
a file), some do more abstraction introducing new Scheme objects.
Instead of just picking one of such interfaces, I decided to implement
Gauche's system interface API in two layers; the lower level layer,
described in this section, follows the operating system's API
as close as possible. On top of that, the higher-level APIs are
provided, with considering compatibility to the existing systems.
The low level system interface has the name sys-name
and usually correspond to the system call name.
I tried to keep the interface similar whenever reasonable.
Gauche restarts a system call after it is interrupted by a signal. See Signal for the details.
If you are familiar with system programming in C, see also C to Scheme mapping, which shows correspondence between C standard library functions and Gauche procedures.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Gauche has a few ways to terminate itself (other than returning
from main). The exit procedure is a graceful way
with all proper cleanups. sys-exit and sys-abort
may be used in emergency where proper cleanup is impossible.
[POSIX]
Terminates the current process with the exit code code.
Code must be zero or positive exact integer.
When a string is given to fmtstr, it is passed to
format (See section Output), with the rest arguments args,
to produce a message to the standard error port
(not the current error port; see Common port operations).
In fact, the exitting procedure is a bit more complicated. The precise steps of exitting is as follow.
exit-handler is checked.
If it is not #f, the value is called as a procedure
with three arguments: code, fmtstr, and a list of rest
arguments. It is the default procedure of exit-handler
that prints out the message to the standard error port.
If an error occurs within exit handler, it is captured and
discarded. Other exceptions are not caught.
Scm_AddCleanupHandler
are invoked. These are usually responsible for under-the-hood cleanup
jobs for each application that embeds Gauche. From the Scheme world
there's not much to care.
exit(3).
The exit-handler mechanism allows the application to hook its
exit operation. Note that it is not for simple cleanup jobs;
dynamic-wind, guard or unwind-protect are more appropriate.
exit-handler is for more specific use just upon application exit.
For example, GUI applications may want to post a dialog
instead of printing to stderr.
For this reason, the library code shouldn't change exit-handler;
only the application knows what to do when it exits.
Another useful case is when you
want to call a third-party code which calls exit inside. In
that case you may swap the exit-handler for the one
that raises a non-error exception while calling the third-party code.
Non-error exception isn't caught in exit, effectivelly
interrupts the steps explained above. (Yet the after thunks
of dynamic handlers are processed just like normal exception
handling case.)
Your appication code can then capture the exception.
You can use parameterize
to swap exit-handler dynamically
and thread-safely (See section gauche.parameter - Parameters).
(guard (e [(eq? e 'exit-called) (handle-exit-as-desired)])
(parameterize ((exit-handler (lambda (c f a) (raise 'exit-called))))
(call-third-party-library)))
|
Generally, calling exit while other threads are running
should be avoided, since it only rewinds the dynamic handlers active
in the calling threads, and other threads will be killed abruptly.
If you have to do so for some reason,
you may be able to use exit-handler to tell to other threads
that the application is exitting. (There's no general way, and
Gauche doesn't even have a list of all running threads; it's application's
responsibility).
Note on design: Some languages integrates exit handling
into exception handling, treating exit as a kind of exception.
It is a tempting idea, so much that we've tried it. It didn't
work out well in Gauche; a big annoyance was that when
an after thunk raised an exception during
rewinding dynamic-winds, it shadowed the original
exit exception.
When called without argument, returns the value of the current exit
handler. When called with an argument, sets new-handler as the
value of the exit handler, and returns the previous value of the
exit handler. new-handler must be a procedure that takes
three arguments, or #f.
The value of exit handler is thread-specific, and the default value
is inherited from the value of the current exit handler of the parent
thread. exit-handler can be used as if it's a parameter
in the parameterize macro (See section gauche.parameter - Parameters).
[POSIX]
Terminates the current process with the exit code code.
Code must be zero or positive exact integer.
This procedure calls _exit(2) directly.
No cleanup is done. Unflushed file output is discarded.
[POSIX] Calls POSIX abort(). This usually terminates the running process and dumps core. No cleanup is done.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[POSIX]
Returns the value of the environment variable name as a string,
or #f if the environment variable is not defined.
Returns the current environment as a list of strings. Each string
is a form of NAME=VALUE, where NAME is the name of
the environment variable and VALUE is its value. NAME
never contains a character #\=. This is useful when you want
to obtail the all enviroment variables of the current process.
Use sys-getenv if you want to query a specific environment
variable.
A convenience procedure for sys-environ. When the list of
environment strings (like what sys-environ returns) is given
to envlist, this procedure splits name and value of
each environment variable and returns an assoc list.
When envlist is omitted, this procedure calls sys-environ
to get the current environment variables.
(sys-environ->alist '("A=B" "C=D=E"))
=> (("A" . "B") ("C" . "D=E"))
|
Add environment variable name with value to the current process's environment. If the system doesn't support putenv(3), this function signals an error.
These functions returns a string that tells information about Gauche interpreter itself.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
System calls that deal with filesystems.
See also file.util - Filesystem utilities, which defines high-level APIs
on top of the procedures described here.
| 6.22.3.1 Directories | ||
| 6.22.3.2 Directory manipulation | ||
| 6.22.3.3 Pathnames | ||
| 6.22.3.4 File stats | ||
| 6.22.3.5 Other file operations |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
See also Directory utilities for high-level API.
path must be a string that denotes valid pathname of an existing directory. This function returns a list of strings of the directory entries. The returned list is not sorted. An error is signalled if path doesn't exists or is not a directory.
Provides a traditional Unix glob(3) functionality; returns a list of pathnames that matches the given pattern.
This feature used to be a wrapper of system-provided glob function,
hence it was named sys-glob. However, as of Gauche version 0.8.12,
it was reimplemented in Scheme on top of other system calls, to overcome
incompatibilies between platforms and for the opportunity to put
more functionalities. So we renamed it glob.
The old name sys-glob is kept for compatibility, but new
programs should use glob.
The pattern argument may be a single glob pattern, or a list of glob patterns. If a list is given, pathnames that matches any one of the pattern are returned. If you're a unix user, you already know how it works.
gosh> (glob "*.scm")
("test.scm" "ext.scm")
gosh> (glob "src/*.[ch]")
("src/ext.c" "src/ext.h")
gosh> (glob '("*.scm" "src/*.c"))
("src/ext.c" "test.scm" "ext.scm")
|
Unlike shell's glob, if there's no matching pathnames, () is returned.
In fact, globbing is a very useful tool to search hierarchical
data structure in general, not limited to the filesystems.
So the glob function is implemented separately from
the filesystem. Using keyword arguments,
you can glob from any kind of tree data structure.
It is just that their default values are set to look at
the filesystems.
The separator argument should be a char-set, and used
to split the pattern into components. Its default is
#[/]. It is not used to the actual pathnames to match.
The folder is a procedure that walks through the data structure. It is called with five arguments:
(folder proc seed parent regexp non-leaf?) |
proc is a procedure that takes two arguments. The folder
should call proc with every node in the parent whose
component name matches regexp, passing around the seed value
just like fold. It should return the final value returned
by proc. For example, if cons is given to proc
and () is given to seed, the return value of the folder
is a list of nodes that matches the regexp.
The representation of a node is up to the implementation of
folder. It can be a
pathname, or some sort of objects, or anything. The glob
procedure does not care what it is; the glob procedure
merely passes the node to subsequent call to folder as
parent argument, or returns a list of nodes as the result.
The parent argument is basically a node, and
folder traverses its children to find the match.
The exception is the initial call of folder—
at the beginning glob knows nothing about each node.
When glob needs to match an absolute path, it
passes #t, and when glob needs to match a relative path,
it passes #f, as the initial parent value.
The regexp argument is used to filter the child nodes.
It should be matched against the component name of the child,
not including its directory names. As a special case, it can
be a symbol dir; if that's the case, the folder should
return node itself, but it may indicate node
as a directory; e.g. if node is represented as a pathname,
the folder returns a pathname with trailing directory separator.
As special cases,
if node is a boolean value and regexp is dir,
the folder should return the node representing root node or
current node, respectively; e.g. if node is represented
as a pathname, the folder may return "/" and "./"
for those cases.
The non-leaf argument is a boolean flag. If it is true, the filter should omit the leaf nodes from the result (e.g. only include the directories).
Now, here's the precise spec of glob pattern matching.
Each glob pattern is a string to match pathname-like strings.
A pathname-like string is a string consists of one or more
components, separated by separators.
The default separator is #[/]; you can change it
with separator keyword argument.
A component cannot contain separators, and cannot
be a null string. Consecutive separators are
regarded as a single separator. A pathname-like
string optionally begins with, and/or ends with a separator character.
A glob pattern is also consists of components and separator characters. In a component, following characters/syntax have special meanings.
*When it appears at the beginning of a component, it matches
zero or more characters except a period (.). And it
won't match if the component of the input string begins with
a period.
Otherwise, it matches zero or more sequence of any characters.
**If a component is just **, it matches zero or more
number of components that match *. For example, src/**/*.h
matches all of the following patterns.
src/*.h src/*/*.h src/*/*/*.h src/*/*/*/*.h ... |
?When it appears at the beginning of a component, it matches
a character except a period (.). Othewrise, it matches
any single character.
[chars]Specifies a character set. Matches any one of the set.
The syntax of chars is the same as Gauche's character set
syntax (See section Character Set). For the compatibility of the
traditional glob, the ! character can be used to complement
the character set, e.g. [!abc] is the same as [^abc].
This is actually a low-level construct of the glob function. Actually, glob is simply written like this:
(define (glob patterns . opts) (apply glob-fold patterns cons '() opts)) |
The meaning of pattern, separator and folder is the same as explained above.
For each pathname that matches pattern, glob-fold
calls proc with the pathname and a seed value. The initial
seed value is seed, and the value proc returns becomes
the next seed value. The result of the last call to proc
becomes the result of glob-fold. If there's no matching
pathnames, proc is never called and seed is returned.
This is a utility function to generate a procedure suitable to
pass the folder keyword argument of glob-fold and glob.
Without arguments, this returns the same procedure which is used
in glob-fold and glob by default.
The keyword arguments root-path and current-path specify
the paths where glob-fold starts to search.
gosh> (glob "/tmp/*.scm")
("/tmp/x.scm" "/tmp/y.scm")
gosh> (glob "/*.scm"
:folder (make-glob-fs-fold :root-path "/tmp"))
("/tmp/x.scm" "/tmp/y.scm")
gosh> (glob "*.scm"
:folder (make-glob-fs-fold :current-path "/tmp"))
("/tmp/x.scm" "/tmp/y.scm")
|
See section File stats, to check if a path is actually a directory.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[POSIX] If filename is a file it is removed. On some systems this may also work on an empty directory, but portable scripts shouldn't depend on it.
[POSIX] Renames a file old to new. The new name can be in different directory from the old name, but both paths must be on the same device.
[POSIX]
Creates a file name which is supposedly unique, and returns it.
This is in POSIX, but its use is discouraged because of potential
security risk. Use sys-mkstemp below if possible.
Creates and opens a file that has unique name, and returns two values; opened port and the created filename. The file is created exclusively, avoiding race conditions. tmpname is used as the prefix of the file. Unlike Unix's mkstemp, you don't need padding characters. The file is opened for writing, and its permission is set to 600.
[POSIX] Creates a hard link named new to the existing file existing.
[POSIX]
Removes pathname. It can't be a directory.
Returns #t if it is successfully removed, or
#f if pathname doesn't exist.
An error is signalled otherwise.
Creates a symbolic link named new to the pathname existing. On systems that doesn't support symbolic links, this function is unbound.
If a file specified by path is a symbolic link, its content is returned. If path doesn't exist or is not a symbolic link, an error is signalled. On systems that don't support symbolic links, this function is unbound.
[POSIX]
Makes a directory pathname with mode mode.
(Note that mode is masked by the current umask;
see sys-umask below).
The parent directory of pathname must exist and be writable
by the process. To create intermediate directories at once, use
make-directory* in file.util (Directory utilities).
[POSIX]
Removes a directory pathname. The directory must be empty.
To remove a directory with its contents, use remove-directory*
in file.util (Directory utilities).
[POSIX]
Sets umask setting to mode. Returns previous umask setting.
If mode is omitted or #f, just returns the current umask without
changing it.
See man umask for more details.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
See also Pathname utilities, for high-level APIs.
Converts pathname according to the way specified by keyword arguments. More than one keyword argument can be specified.
absoluteIf this keyword argument is given and true, and pathname is not an absolute pathname, it is converted to an absolute pathname by appending the current working directory in front of pathname.
expand If this keyword argument is given and true, and pathname begins
with `~', it is expanded as follows:
~”, or begins
with “~/”, then the character “~” is replaced
for the pathname of the current user's home directory.
~' until either `/' or
the end of pathname are taken as a user name, and the user's
home directory is replaced in place of it. If there's no such
user, an error is signalled.
canonicalize Tries to remove pathname components “.” and “..”.
The pathname interpretation is done purely in textural level, i.e.
it doesn't access filesystem to see the conversion reflects the
real files. It may be a problem if there's a symbolic links to
other directory in the path.
sys-basename returns a basename, that is the last component of
pathname. sys-dirname returns the components of pathname
but the last one. If pathname has a trailing `/',
it is simply ignored.
(sys-basename "foo/bar/bar.z") ⇒ "bar.z" (sys-basename "coo.scm") ⇒ "coo.scm" (sys-basename "x/y/") ⇒ "y" (sys-dirname "foo/bar/bar.z") ⇒ "foo/bar" (sys-dirname "coo.scm") ⇒ "." (sys-dirname "x/y/") ⇒ "x" |
These functions doesn't check if pathname really exists.
Some boundary cases:
(sys-basename "") ⇒ "" (sys-dirname "") ⇒ "." (sys-basename "/") ⇒ "" (sys-dirname "/") ⇒ "/" |
Note: The above behavior is the same as Perl's basename and
dirname. On some implementations, the command basename
may return "/" for the argument "/", and
"." for the argument ".".
sys-realpath returns an absolute pathname of pathname
that does not include “.”, “..” or symbolic links.
If the system does not support realpath(3), this function signals an
error.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
See also File attribute utilities, for high-level APIs.
Returns true if path exists, is a regular file, or is a directory, respectively. The latter two returns false if path doesn't exist at all.
These functions are built on top of primitive system interfaces described below; I provide these for convenience and compatibility (STk has the same functions).
An object that represents struct stat, attributes of an
entry in the filesystem. It has the following read-only slots.
A symbol represents the type of the file.
| a regular file |
| a directory |
| a character device |
| a block device |
| a fifo |
| a symbolic link |
| a socket |
If the file type is none of the above, #f is returned.
Note: Some operating systems don't have the socket file type
and returns fifo for socket files. Portable programs should
check both possibilities to see if the given file is a socket.
An exact integer for permission bits of struct stat.
It is the same as lower 9-bits of "mode" slot; provided for the convenience.
An exact integer for those information of struct stat.
A number of seconds since Unix Epoch for those information of struct stat.
[POSIX]
Returns a <sys-stat> object of path, or
the underlying file of port-or-fd, which
may be a port or a positive exact integer file descriptor, respectively.
If path is a symbolic link, a stat of the file the link points
to is returned from sys-stat.
If port-or-fd is not associated to a file, sys-fstat returns
#f.
Like sys-stat, but it returns a stat of a symbolic link
if path is a symbolic link.
gosh> (describe (sys-stat "gauche.h")) #<<sys-stat> 0x815af70> is an instance of class <sys-stat> slots: type : regular perm : 420 mode : 33188 ino : 845140 dev : 774 rdev : 0 nlink : 1 uid : 400 gid : 100 size : 79549 atime : 1020155914 mtime : 1020152005 ctime : 1020152005 |
Deprecated.
Use slot-ref to access information of <sys-stat> object.
[POSIX] Returns a boolean value of indicating whether access of pathname is allowed in amode. This procedure signals an error if used in a suid/sgid program (see the note below). amode can be a combinations (logical or) of following predefined flags.
R_OKChecks whether pathname is readable by the current user.
W_OKChecks whether pathname is writable by the current user.
X_OKChecks whether pathname is executable (or searchable in case pathname is a directory) by the current user.
F_OKChecks whether pathname exists or not, regardless of the access permissions of pathname. (But you need to have access permissions of the directories containing pathname).
Note: Access(2) is known to be a security hole if used in suid/sgid program to check the real user's priviledge of accessing the file.
Change the mode of the file named path or an opened file specified by port-or-fd to mode. mode must be a small positive integer whose lower 9 bits specifies POSIX style permission.
Change the owner and/or group of the file named path to owner-id and group-id respectively. owner-id and group-id must be an exact integer. If either of them is -1, the corresponding ownership is not changed.
Change the file's access time and modification time to atime
and mtime, respectively. If atime and mtime is
omitted, they are set to the current time.
See also touch-file (See section File operations).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[POSIX]
An interface to chdir(2).
See also current-directory (See section Directory utilities).
[POSIX] Creates a pipe, and returns two ports. The first returned port is an input port and the second is an output port. The data put to the output port can be read from the input port.
Buffering can be :full, :line or :none,
and specifies the buffering mode of the ports opened on the pipe.
See section File ports, for details of the buffering mode.
The default mode is sufficient for typical cases.
(receive (in out) (sys-pipe) (display "abc\n" out) (flush out) (read-line in)) ⇒ "abc" |
Note: the returned value is changed from version 0.3.15, in which
sys-pipe returned a list of two ports.
[POSIX] creates a fifo (named pipe) with a name path and mode mode. Mode must be a positive exact integer to represent the file mode.
[POSIX] port-or-fd may be a port or an integer file descriptor.
Returns #t if the port is connected to the console, #f
otherwise.
[POSIX] port-or-fd may be a port or an integer file descriptor.
Returns the name of the terminal connected to the port,
or #f if the port is not connected to a terminal.
[POSIX] Truncates a regular file named by path or referenced by port-or-fd to a size of length bytes. If the file is larger than length bytes, the extra data is discarded. If the file is smaller than that, zero is padded.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Unix group information. Has following slots.
Group name.
Group id.
Group password.
List of user names who are in this group.
[POSIX]
Returns <sys-group> object from an integer group id gid
or a group name name, respectively.
If the specified group doesn't exist, #f is returned.
Convenience function to convert between group id and group name.
Unix user information. Has following slots.
User name.
User ID.
User's primary group id.
User's (encrypted) password. If the system uses the shadow password file, you just get obscure string like "x".
Gecos field.
User's home directory.
User's login shell.
User's class (only available on some systems).
[POSIX]
Returns <sys-passwd> object from an integer user id uid
or a user name name, respectively.
If the specified user doesn't exist, #f is returned.
Convenience functions to convert between user id and user name.
This is the interface to crypt(3). Key and salt
must be a string, and an encrypted string is returned.
On systems where crypt(3) is not available, call to this
function signals an error.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[POSIX]
Sets the locale of the category category to the locale locale.
category must be an exact integer; the following pre-defined
variables are available. locale must be a string locale name.
Returns the locale name on success, or #f if the system
couldn't change the locale.
Predefined variables for possible category value of
sys-setlocale.
[POSIX] Returns an assoc list of various information for formatting numbers in the current locale.
An example session. It may differ on your system settings.
(sys-localeconv)
⇒
((decimal_point . ".") (thousands_sep . "")
(grouping . "") (int_curr_symbol . "")
(currency_symbol . "") (mon_decimal_point . "")
(mon_thousands_sep . "") (mon_grouping . "")
(positive_sign . "") (negative_sign . "")
(int_frac_digits . 127) (frac_digits . 127)
(p_cs_precedes . #t) (p_sep_by_space . #t)
(n_cs_precedes . #t) (n_sep_by_space . #t)
(p_sign_posn . 127) (n_sign_posn . 127))
(sys-setlocale LC_ALL "fr_FR")
⇒ "fr_FR"
(sys-localeconv)
⇒
((decimal_point . ",") (thousands_sep . "")
(grouping . "") (int_curr_symbol . "FRF ")
(currency_symbol . "F") (mon_decimal_point . ",")
(mon_thousands_sep . " ") (mon_grouping . "\x03\x03")
(positive_sign . "") (negative_sign . "-")
(int_frac_digits . 2) (frac_digits . 2)
(p_cs_precedes . #f) (p_sep_by_space . #t)
(n_cs_precedes . #f) (n_sep_by_space . #t)
(p_sign_posn . 1) (n_sign_posn . 1))
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Gauche can send out operating system's signals to the other processes (including itself) and can handle the incoming signals.
In multithread environment, all threads share the signal handlers, and each thread has its own signal mask. See Signals and threads, for details.
When a system call is interrupted by a signal, and a programmer defines a handler for the signal that doesn't transfer control to other context, the system call is restarted after the handler returns.
| 6.22.6.1 Signals and signal sets | ||
| 6.22.6.2 Sending signals | ||
| 6.22.6.3 Handling signals | ||
| 6.22.6.4 Masking and waiting signals | ||
| 6.22.6.5 Signals and threads |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Each signal is referred by its signal number (a small integer) defined on the underlying operating system. Variables are pre-defined to the system's signal number. System's signal numbers may be architecture dependent, so you should use those variables rather than using literal integers.
These variables are bound to the signal numbers of POSIX signals.
These variables are bound to the signal numbers of system-dependent signals. Not all of them may be defined on some systems.
Besides each signal numbers, you can refer to a set of signals
using a <sys-sigset> object.
It can be used to manipulate the signal mask, and to install a signal
handler to a set of signals at once.
A set of signals. An empty sigset can be created by
(make <sys-sigset>) ⇒ #<sys-sigset []> |
Creates and returns an instance of <sys-sigset>
with members signal …. Each signal
may be either a signal number, another <sys-sigset>
object, or #t for all available signals.
(sys-sigset SIGHUP SIGINT) ⇒ #<sys-sigset [HUP|INT]> |
Sigset must be a <sys-sigset> object.
Those procedures adds and removes the specified signals from
sigset respectively, and returns the result. sigset itself
is also modified.
signal may be either a signal number, another <sys-sigset>
object, or #t for all available signals.
Fills sigset by all available signals, or empties sigset.
Returns the human-readable name of the given signal number. (Note that signal numbers are system-dependent.)
(sys-signal-name 2) ⇒ "SIGINT" |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To send a signal, you can use sys-kill which works like
kill(2).
[POSIX] Sends a signal sig to the specified process(es). Sig must be a positive exact integer. pid is an exact integer and specifies the target process(es):
There's no Scheme equivalence for raise(), but you can use
(sys-kill (sys-getpid) sig).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
You can register signal handling procedures in Scheme. (In multithread environment, signal handlers are shared by all threads; see Signals and threads for details).
When a signal is delivered to the Scheme process, the VM just records it and processes it later at a 'safe point' where the state of VM is consistent. We call the signal is pending when it is registered by the VM but not processed yet.
(Note that this makes handling of some signals such as SIGILL
useless, for the process can't continue sensible execution after
recording the signal).
If the same signal is delivered more than once before VM processes the first one, the second one and later have no effect. (This is consistent to the traditioncal Unix signal model.) In other words, for each VM loop a signal handler can be invoked at most once per each signal.
When too many signals of the same kind are pending,
Gauche assumes something has
gone wrong (e.g. infinite loop inside C-routine) and aborts the
process. The default of this limit is set rather low (3), to allow
unresponsive interactive script to be terminated by typing Ctrl-C
three times. Note that the counter is individual for each signal;
Gauche won't abort if one SIGHUP and two SIGINTs are
pending, for example. You can change this limit by
set-signal-pending-limit described below.
When you're using the gosh interpreter, the default
behavior for each signal is as in the following table.
SIGABRT, SIGILL, SIGKILL, SIGCONT, SIGSTOP, SIGSEGV, SIGBUSCannot be handled in Scheme. Gosh follows the system's
default behavior.
SIGCHLD, SIGTSTP, SIGTTIN, SIGTTOU, SIGWINCHNo signal handles are installed for these signals by gosh,
so the process follows the system's default behavior.
Scheme programs can install its own signal handler if necessary.
SIGHUP, SIGQUIT, SIGTERMGosh installs a signal handler for these signals
that exits from the application with code 0.
SIGPWR, SIGXCPU, SIGUSR1, SIGUSR2On Linux platforms with thread support, these signals are used by the system and not available for Scheme. On other systems, these signals behaves the same as described below.
other signalsGosh installs the default signal handler, which raises
<unhandled-signal-error> condition (see Conditions).
Scheme programs can override it by its own signal handler.
If you're using Gauche embedded in some other application, it may redefine the default behavior.
Use the following procedures to get/set signal handlers from Scheme.
Signals may be a single signal number or a <sys-sigset>
object, and handler should be either #t, #f
or a procedure that takes one argument.
If handler is a procedure, it will be called when the process
receives one of specified signal(s), with the received signal
number as an argument.
By default, the signals in signals are blocked
(in addition to the signal mask in effect at that time) during
handler is executed, so that handler won't be
reentered by the same signal(s). You can provide
a <sys-sigset> object to the sigmask arg
to specify the signals to be blocked explicitly.
Note that the signal mask
is per-thread; if more than one thread unblocks a signal, the handler
may still be invoked during execution of the handler (in other thread)
even if you specify sigmask. You have to set the threads'
signal mask properly to avoid such situation.
It is safe to do anything in handler, including throwing an error or invoking continuation captured elsewhere. (However, continuations captured inside handler will be invalid once you return from handler).
If handler is #t, the operating system's default
behavior is set to the specified signal(s). If handler
is #f, the specified signals(s) will be ignored.
Note that signal handler setting is shared among threads in multithread enviornment. The handler is called from the thread which is received the signal. See Signals and threads for details.
Returns the handler setting, or signal mask setting, of a signal signum, respectively.
Returns an associative list of all signal handler settings.
Car of each element of returned list is a <sys-sigset> object,
and cdr of it is the handler (a procedure or a boolean value)
of the signals in the set.
Gets/sets the maximum number of pending signals per each signal type. If the number of pending signals exceeds this limit, Gauche aborts the process. See the explanation at the beginning of this section for the details. Limit must be a nonnegative exact integer. In the current implementaiton the maximum number of limit is 255. Setting limit to zero makes the number of pending signals unlimited.
A convenience macro to install signal handlers temporarily during execution of thunk. (Note: though this is convenient, this has certain dangerous properties described below. Use with caution.)
Each Handler-clause may be one of the following forms.
(signals expr …)Signals must be an expression that will yield either a signal,
a list of signals, or a <sys-sigset> object.
Installs a signal handler for signals that evaluates
expr … when one of the signals in signals is delivered.
(signals => handler)This form sets the handler of signals to handler,
where handler should be either #t, #f
or a procedure that takes one argument.
If handler is a procedure, it will be called when the process
receives one of specified signal(s), with the received signal
number as an argument.
If handler is #t, the operating system's default
behavior is set to the specified signal(s). If handler
is #f, the specified signals(s) will be ignored.
When the control exits from thunk, the signal handler setting
before with-signal-handlers are recovered.
CAVEAT: If you're setting more than one signal handlers,
they are installed in serial. If a signal is delivered before
all the handlers are installed, the signal handler state may be
left inconsistent. Also note that the handler setting is a global state;
you can't set "thread local" handler by with-signal-handlers,
although the form may be misleading.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A Scheme program can set a signal mask, which is a set of signals to be blocked from delivery. If a signal is delivered which is completely blocked in the process, the signal becomes "pending". The pending signal may be delivered once the signal mask is changed not to block the specified signal. (However, it depends on the operating system whether the pending signals are queued or not.)
In multithread environment, each thread has its own signal mask.
Modifies the current thread's signal mask, and returns the previous
signal mask. Mask should be a <sys-sigset> object
to specify the new mask, or #f if you just want to query
the current mask without modifying one.
If you give <sys-sigset> object to mask,
how argument should be one of the following
integer constants:
SIG_SETMASKSets mask as the thread's signal mask.
SIG_BLOCKAdds signals in mask to the thread's signal mask.
SIG_UNBLOCKRemoves signals in mask from the thread's signal mask.
Atomically sets thread's signal mask to mask and
suspends the calling thread. When a signal that is not blocked
and has a signal handler installed is delivered, the associated
handler is called, then sys-sigsuspend returns.
[POSIX]
Mask must be a <sys-sigset> object.
If any of signals in mask is/are pending in the OS,
atomically clears one of them and returns the signal number
of the cleared one. If there's no signal in mask
pending, sys-sigwait blocks until any of the signals
in mask arrives.
You have to block all signals in mask in all threads
before calling sys-sigwait. If there's a thread
that doesn't block the signals, the behavior of
sys-sigwait is undefined.
Note: Sys-sigwait uses system's sigwait function,
whose behavior is not defined if there's a signal
handler on the signals it waits. To avoid complication,
sys-sigwait resets the handlers set to the signals
included in mask before calling sigwait to SIG_DFL,
and restores them after sigwait returns. If another thread
changes signal handlers while sys-sigwait is waiting,
the behavior is undefined; you shouldn't do that.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The semantics of signals looks a bit complicated in the multithread environment. Nevertheless, it is pretty comprehensible once you remember a small number of rules. Besides, Gauche sets up the default behavior easy to use, while allowing programmers to do tricky stuff.
If you don't want to be bothered by the details, just remember one thing, with one sidenote. By default, signals are handled by the primordial (main) thread. However, if the main thread is suspended on mutex or condition variable, the signal may not be handled at all, so be careful.
Now, if you are curious about the details, here are the rules:
Now, these rules have several implications.
If there are more than one thread that don't block a particular signal, you can't know which thread receives the signal. Such a situation is much less useful in Gauche than C programs because of the fact that the signal handling can be delayed indefinitely if the receiver thread is waiting on mutex or condition variable. So, it is recommended to make sure, for each signal, there is only one thread that can receive it.
In Gauche, all threads created by make-thread
(See section Thread procedures) blocks all the signals by default
(except the reserved ones). This lets all the signals
to be directed to the primordial (main) thread.
Another strategy is to create a thread dedicated for handling
signals. To do so, you have to block the signals in the
primordial thread, then create the signal-handling thread,
and within that thread you unblock all the signals.
Such a thread can just loop on sys-pause.
(thread-start!
(make-thread
(lambda ()
(sys-sigmask SIG_SETMASK (make <sys-sigset>)) ;;empty mask
(let loop () (sys-pause) (loop)))))
|
Complicated application may want to control per-thread signal handling precisely. You can do so, just make sure that at any moment only the designated thread unblocks the desired signal.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[POSIX] Returns a list of five elements,
(sysname nodename release version machine).
Returns the host name. If the system doesn't have gethostname(),
the second element of the list returned by sys-uname is used.
Returns the domain name. If the system doesn't have getdomainname(),
"localdomain" is returned.
[POSIX] Returns the current working directory by a string.
If the current working directory couldn't be obtained from the system,
an error is signalled. See also sys-chdir
(See section Other file operations), current-directory
(See section Directory utilities).
[POSIX] Returns integer value of real and effective group id of the
current process, respectively.
Use sys-gid->group-name or sys-getgrgid to obtain
the group's name and other information associated to the returned
group id (See section Unix groups and users).
[POSIX] Sets the effective group id of the current process.
[POSIX] Returns integer value of real and effective user id of the
current process, respectively.
Use sys-uid->user-name or sys-getpwuid to obtain
the user's name and other information associated to the returned
user id (See section Unix groups and users).
[POSIX] Sets the effective user id of the current process.
[POSIX] Returns a list of integer ids of supplementary groups.
[POSIX] Returns a string of the name of the user logged in on the
controlling terminal of the current process.
If the system can't determine the information, #f is returned.
[POSIX] Returns a process group id of the current process.
Returns a process group id of the process specified by pid. If pid is zero, the current process is used.
Note that getpgid() call is not in POSIX. If the system
doesn't have getpgid(), sys-getpgid still works if
pid is zero (it just calls sys-getpgrp), but signals
an error if pid is not zero.
[POSIX] Sets the process group id of the process pid to pgid.
If pid is zero, the process ID of the
current process is used. If pgid is zero, the process ID
of the process specified by pid is used. (Hence
sys-setpgid(0, 0) sets the process group id of the
current process to the current process id).
[POSIX] Creates a new session if the calling process is not a process group leader.
[POSIX] Returns the current process id and the parent process id, respectively.
[POSIX]
[POSIX] Returns the name of the controlling terminal of the process.
This may be just a "/dev/tty". See also sys-ttyname.
[POSIX] Get and set resource limits respectively.
Resource is an integer constant to specify the resource
of concern. The following constants are defined.
(The constants marked as bsd and/or linux indicates that they
are not defined in POSIX but defined in BSD and/or Linux.
Other systems may or may not have them. Consult getrlimit
manpage of your system for the details.)
RLIMIT_AS RLIMIT_CORE RLIMIT_CPU RLIMIT_DATA RLIMIT_FSIZE RLIMIT_LOCKS RLIMIT_MEMLOCK (bsd/linux) RLIMIT_MSGQUEUE (linux) RLIMIT_NICE (linux) RLIMIT_NOFILE RLIMIT_NPROC (bsd/linux) RLIMIT_RSS (bsd/linux) RLIMIT_RTPRIO (linux) RLIMIT_SIGPENDING (linux) RLIMIT_SBSIZE RLIMIT_STACK RLIMIT_OFILE |
Errno must be an exact nonnegative integer representing a system error number. This function returns a string describing the error.
To represent errno, the following constants are defined. Each constant is bound to an exact integer representing the system's error number. Note that the actual value may differ among systems, and some of these constants may not be defined on some systems.
E2BIG EHOSTDOWN ENETDOWN ENXIO EACCES EHOSTUNREACH ENETRESET EOPNOTSUPP EADDRINUSE EIDRM ENETUNREACH EOVERFLOW EADDRNOTAVAIL EILSEQ ENFILE EPERM EADV EINPROGRESS ENOANO EPFNOSUPPORT EAFNOSUPPORT EINTR ENOBUFS EPIPE EAGAIN EINVAL ENOCSI EPROTO EALREADY EIO ENODATA EPROTONOSUPPORT EBADE EISCONN ENODEV EPROTOTYPE EBADF EISDIR ENOENT ERANGE EBADFD EISNAM ENOEXEC EREMCHG EBADMSG EKEYEXPIRED ENOKEY EREMOTE EBADR EKEYREJECTED ENOLCK EREMOTEIO EBADRQC EKEYREVOKED ENOLINK ERESTART EBADSLT EL2HLT ENOMEDIUM EROFS EBFONT EL2NSYNC ENOMEM ESHUTDOWN EBUSY EL3HLT ENOMSG ESOCKTNOSUPPORT ECANCELED EL3RST ENONET ESPIPE ECHILD ELIBACC ENOPKG ESRCH ECHRNG ELIBBAD ENOPROTOOPT ESRMNT ECOMM ELIBEXEC ENOSPC ESTALE ECONNABORTED ELIBMAX ENOSR ESTRPIPE ECONNREFUSED ELIBSCN ENOSTR ETIME ECONNRESET ELNRNG ENOSYS ETIMEDOUT EDEADLK ELOOP ENOTBLK ETOOMANYREFS EDEADLOCK EMEDIUMTYPE ENOTCONN ETXTBSY EDESTADDRREQ EMFILE ENOTDIR EUCLEAN EDOM EMLINK ENOTEMPTY EUNATCH EDOTDOT EMSGSIZE ENOTNAM EUSERS EDQUOT EMULTIHOP ENOTSOCK EWOULDBLOCK EEXIST ENAMETOOLONG ENOTTY EXDEV EFAULT ENAVAIL ENOTUNIQ EXFULL EFBIG |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Gauche has two representations of time, one is compatible to POSIX API, and the other is compatible to SRFI-18, SRFI-19 and SRFI-21. Most procedures accept both representations; if not, the representation the procedure accepts is indicated as either 'POSIX time' or 'SRFI time'.
POSIX time is represented by a real number which is a number of seconds
since Unix Epoch (Jan 1, 1970, 0:00:00GMT).
Procedure sys-time, which corresponds to POSIX time(2),
returns this time representation.
SRFI-compatible time is represented by an object of <time> class,
which keeps seconds and nanoseconds, as well as the type of the time
(UTC, TAI, duration, process time, etc).
Current-time returns this representation.
[POSIX] Returns the current time in POSIX time (the time since Epoch (00:00:00 UTC, January 1, 1970), measured in seconds). It may be a non-integral number, depending on the architecture.
Note that POSIX's definition of “seconds since the Epoch” doesn't take leap seconds into account.
Returns two values. The first value is a number of seconds,
and the second value is a fraction in a number of microseconds,
since 1970/1/1 0:00:00 UTC. If the system doesn't have
gettimeofday call, this function calls time();
in that case, microseconds portion is always zero.
Represents struct tm, a calendar date. It has the following slots.
Seconds. 0-61.
Minutes. 0-59.
Hours. 0-23.
Day of the month, counting from 1. 1-31.
Month, counting from 0. 0-11.
Years since 1900, e.g. 102 for the year 2002.
Day of the week. Sunday = 0 .. Saturday = 6.
Day of the year. January 1 = 0 .. December 31 = 364 or 365.
A flag that indicates if the daylight saving time is in effect. Positive if DST is in effect, zero if not, or negative if unknown.
[POSIX] Converts time to <sys-tm> object, represented in GMT
or local timezone, respectively. Time can be either POSIX-time or
SRFI-time.
[POSIX] Converts time to it string representation, using POSIX ctime(). Time can be either POSIX-time or SRFI-time.
[POSIX] Returns the difference of two times in the real number of seconds. Time0 and time1 can be either POSIX-time or SRFI-time.
[POSIX] Converts <sys-tm> object tm to a string representation.
[POSIX] Converts <sys-tm> object tm to a string representation,
according to a format string format.
[POSIX] Converts <sys-tm> object tm, expressed as local time,
to the POSIX-time (number of seconds since Epoch).
(Deprecated function)
The <time> object also represents a point of time.
Indicates time type. time-utc is the default, and that
represents the number of seconds since Unix Epoch.
SRFI-19 (See section srfi-19 - Time data types and procedures) adds more types.
Second part of the time.
Nanosecond part of the time.
[SRFI-18][SRFI-21]
Returns the <time> object representing the current time in
time-utc. See section srfi-19 - Time data types and procedures, for
it redefines current-time to allow optional argument to
specify time type.
[SRFI-18][SRFI-19][SRFI-21]
Returns #t if obj is a time object.
[SRFI-18][SRFI-21]
Converts between time object and the number of seconds (POSIX-time).
Time argument of time->seconds has to be a <time> object.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following procedures provide pretty raw, direct interface
to the system calls.
See also gauche.process - High Level Process Interface, which provides
more convenient process handling on top of these primitives.
[POSIX]
Runs command in a subprocess. command is usually passed
to sh, so the shell metacharacters are interpreted.
This function returns an integer value system() returned.
Since POSIX doesn't define what system() returns, you can't
interpret the returned value in a portable way.
[POSIX]
Fork the current process. Returns 0 if you're in the child process,
and a child process' pid if you're in the parent process.
All the opened file descriptors are shared between the parent and
the child. See fork(2) of your system for details.
If the child process runs some Scheme code and exits instead of
calling sys-exec, it should call sys-exit
instead of exit to terminate itself.
Normal exit call tries to flush the file
buffers, and on some OS it messes up the parent's file buffers.
It should be noted that sys-fork is not safe when
multiple threads are running. Because fork(2) copies
the process' memory image which includes any mutex state,
a mutex which is locked by another thread at the time of sys-fork
remains locked in the child process, nevertheless the child process
doesn't have the thread that unlock it!
(This applies to the internal mutexes as well, so even you don't
use Scheme mutex explicitly, this situation can always happen.)
If what you want is to spawn another program in a multi-threaded application,
use sys-fork-and-exec explained below.
If you absolutely need to run Scheme code in the
child process, a typical technique is that you fork a manager process
at the beginning of application, and whenever you need a new process
you ask the manager process to fork one for you.
[POSIX+] Execute command with args, a list of arguments. The current process image is replaced by command, so this function never returns.
All elements of args must be strings. The first element of
args is used as argv[0], i.e. the program name.
The iomap keyword argument, when provided, specifies how the open file descriptors are treated. It must be the following format:
((to-fd . from-port-or-fd) …) |
To-fd must be an integer, and from-port-or-fd must be an integer file descriptor or a port. Each element of the list makes the file descriptor of from-port-or-fd of the current process be mapped to the file descriptor to-fd in the executed process.
If iomap is provided,
any file descriptors other than specified in the iomap list will be closed
before exec(). Otherwise, all file descriptors in the current
process remain open.
(sys-exec "ls" '("ls" "-l")) ⇒ ;; ls is executed.
(let ((out (open-output-file "ls.out")))
(sys-exec "ls" '("ls" "-l") :iomap `((2 . 1) (1 . ,out)))
⇒
;; ls is executed, with its stderr redirected
;; to the current process's stdout, and its
;; stdout redirected to the file "ls.out".
|
The sigmask keyword argument can be an instance of <sys-sigset>
or #f (See section Signal, for the details of signal masks).
If it is an instance of <sys-sigset>, the signal mask of calling
thread is replaced by it just before exec(2) is called.
It is useful, for example, to run an external program from a thread where
all signals are blocked (which is the default; see Signals and threads).
Without setting sigmask, the execed process inherits
calling thread's signal mask and become a process that blocks all signals,
which is not very convenient in most cases.
When sys-exec
encounters an error, most of the time it raises an error condition.
Once the file descriptors are permuted, however, it would be impractical
to handle errors in reasonable way (you don't even know stderr is still
available!), so Gauche simply exits on the error.
Like sys-exec, but executes fork(2) just before
remapping I/O, altering signal mask and call execvp(2).
Returns child's process id. The meanings of arguments are
the same as sys-exec.
It is strongly recommended to use this procedure instead of
sys-fork and sys-exec combination when you need
to spawn another program while other threads are running.
No memory allocation nor lock acquisition is done between
fork(2) and execvp(2),
so it's pretty safe in the multithreaded environment.
[POSIX] Calls system's wait(2). The process suspends its execution
until one of the child terminates. Returns two exact integer values,
the first one is the child's process id, and the second is a status code.
The status code can be interpreted by the following functions.
[POSIX] This is an interface to waitpid(3), an extended version of
wait.
pid is an exact integer specifying which child(ren) to be waited. If it is a positive integer, it waits fot that specific child. If it is zero, it waits for any member of this process group. If it is -1, it waits for any child process. If it is less than -1, it waits for any child process whose process group id is equal to the absolute value of pid.
If there's no child process to wait, or a specific pid is
given but it's not a child process of the current process,
an error (<system-error>, ECHILD) is signalled.
The calling process suspends until one of those child process is terminated, unless true is specified to the keyword argument nohang.
If true is specified to the keyword argument untraced, the status of stopped child process can be also returned.
The return values are two exact integers, the first one is the child process id, and the second is a status code. If nohang is true and no child process status is available, the first value is zero.
[POSIX]
The argument is an exit status returned as a second value
from sys-wait or sys-waitpid.
sys-wait-exited? returns #t if the child process is
terminated normally. sys-wait-exit-status returns the exit
code the child process passed to exit(2), or the return value
of main().
[POSIX]
The argument is an exit status returned as a second value
from sys-wait or sys-waitpid.
sys-wait-signaled? returns #t if the child process
is terminated by an uncaught signal.
sys-wait-termsig returns the signal number that terminated the child.
[POSIX]
The argument is an exit status returned as a second value
from sys-waitpid.
sys-wait-stopped? returns #t if the child process is
stopped. This status can be caught only by sys-waitpid with
true untraced argument. sys-wait-stopsig returns the
signum number that stopped the child.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The interface functions for select(2).
The higher level interface is provided on top of these
primitives; see gauche.selector - Simple dispatcher.
Represents fd_set, a set of file descriptors. You can make
an empty file descriptor set by make method:
(make <sys-fdset>) |
Creates a new <sys-fdset> instance with file descriptors
specified by elt …. Each elt can be an
integer file descriptor, a port, or a <sys-fdset> instance.
In the last case, the descriptors in the given fdset is copied
to the new fdset.
Gets and sets specific file descriptor bit of fdset.
port-or-fd may be a port or an integer file descriptor.
If port-or-fd is a port that doesn't have associated file descriptor,
sys-fdset-ref returns #f, and sys-fdset-set! doesn't
modify fdset. flag must be a boolean value.
You can use generic setter of sys-fdset-ref as this:
(set! (sys-fdset-ref fdset port-or-fd) flag) ≡ (sys-fdset-set! fdset port-or-fd flag) |
Copies the content of src-fdset into dest-fdset. Returns dest-fdset.
Empties and returns fdset.
Converts an fdset to a list of integer file descriptors and vice versa.
In fact, list->sys-fdset works just like
(lambda (fds) (apply sys-fdset fds)), so it accepts ports
and other fdsets as well as integer file descriptors.
Returns the maximum file descriptor number in fdset.
Waits for a set of file descriptors to change status.
readfds, writefds, and exceptfds are <fdset>
objects to represent a set of file descriptors to watch.
File descriptors in readfds are watched to see if characters
are ready to be read. File descriptors in writefds are
watched if writing to them is ok. File descriptors in exceptfds
are watched for exceptions. You can pass #f to one or more
of those arguments if you don't care about watching the condition.
timeout specifies maximum time sys-select waits for
the condition change. It can be a real number, for number of microseconds,
or a list of two integers, the first is the number of seconds and
the second is the number of microseconds. If you pass #f,
sys-select waits indefinitely.
sys-select returns four values. The first value is a number
of descriptors it detected status change. It may be zero if
timeout expired. The second, third and fourth values are <fdset>
object that contains a set of descriptors that changed status
for reading, writing, and exception, respectively.
If you passed #f to one or more of readfds,
writefds and exceptfds, the corresponding return value
is #f.
sys-select! variant works the same as sys-select, except
it modifies the passed <fdset> arguments.
sys-select creates new <fdset> objects and
doesn't modify its arguments.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
[POSIX] Suspends the process until it receives a signal whose action is to either execute a signal-catching function or to terminate the process. This function only returns when the signal-catching function returns. The returned value is undefined.
Note that just calling pause() doesn't suffice the above semantics
in Scheme-level. Internally this procedure calls sigsuspend()
with the current signal mask.