This document describes how to use Guile-Syscalls (alpha releases), a set of modules that expose to Guile 1.4.x a selection of the operating system programming interface (known as the syscalls).
Guile-Syscalls is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.
Guile-Syscalls is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
System calls are, by definition, specific to each system. By system, we mean the latter part of the tuple displayed by the config.guess shell script.
The following two procedures, with a network socket as outfd, do “zero-copy TCP”, useful for web- and other file-dishing servers.
Call sendfile(2) with args outfd, infd, offset and count, all non-negative integers. Return the number of bytes actually written.
Call sendfile(2) with args outfd, infd, offset and count, all non-negative integers. Loop until all bytes are sent (or error).
Other fast-I/O is based on the struct iovec, as defined
when you #include <sys/uio.h>:
/* Structure for scatter/gather I/O. */
struct iovec
{
void *iov_base; /* Pointer to data. */
size_t iov_len; /* Length of data. */
};
We use a smob for that. The iovec also includes information on
the start-offset to support iteration due to incomplete operation
without having to cons up another iovec object.
Return an iovec derived from sequence, a list or vector. This object is suitable for passing to
readvandwritev. Each element of sequence must be a string.NOTE: Avoid modifying the elements while the iovec is live.
Read from fdes data specified by iovec using readv(2). Return number of bytes successfully read, or
#fif there are problems, or there is no more space to read into. Update the starting position of iovec by side-effect. Optional arg count specifies how many elements of iovec to process (default is “remaining count”).
Write to fdes data specified by iovec using writev(2). Return number of bytes successfully written, or
#fif there are problems, or there is nothing more to be written. Update the starting position of iovec by side-effect. Optional arg count specifies how many elements of iovec to process (default is “remaining count”).
Here is a simple example that emulates the shell command `cat *', limited to “regular” files (symlinks and directories ignored).
(use-modules (ice-9 accumulate)
(scripts slurp))
(define (regular-file-contents dir)
(let ((dir (opendir dir))
(acc (accumulator/one-only)))
(define (next)
(readdir dir))
(let loop ((filename (next)))
(cond ((eof-object? filename))
((not (eq? 'regular (stat:type (stat filename))))
(loop (next)))
(else
(acc filename)
(loop (next)))))
(map slurp (acc))))
(let ((iov (iovec (regular-file-contents ".")))
(out (fileno (current-output-port))))
(while (writev out iov)))