racket/collects/scribblings/inside/ports.scrbl
2007-12-16 03:10:00 +00:00

919 lines
34 KiB
Racket

#lang scribble/doc
@(require "utils.ss")
@title{Ports and the Filesystem}
Ports are represented as Scheme values with the types
@cppi{scheme_input_port_type} and @cppi{scheme_output_port_type}. The
function @cppi{scheme_read} takes an input port value and returns the
next S-expression from the port. The function @cppi{scheme_write}
takes an output port and a value and writes the value to the
port. Other standard low-level port functions are also provided, such
as @cppi{scheme_getc}.
File ports are created with @cppi{scheme_make_file_input_port} and
@cppi{scheme_make_file_output_port}; these functions take a @cpp{FILE
*} file pointer and return a Scheme port. Strings are read or written
with @cppi{scheme_make_byte_string_input_port}, which takes a
nul-terminated byte string, and
@cppi{scheme_make_byte_string_output_port}, which takes no arguments.
The contents of a string output port are obtained with
@cppi{scheme_get_byte_string_output}.
Custom ports, with arbitrary read/write handlers, are created with
@cppi{scheme_make_input_port} and @cppi{scheme_make_output_port}.
When opening a file for any reason using a name provided from Scheme,
use @cppi{scheme_expand_filename} to normalize the filename and
resolve relative paths.
@function[(Scheme_Object* scheme_read
[Scheme_Object* port])]{
@scheme[read]s the next S-expression from the given input port.}
@function[(void scheme_write
[Scheme_Object* obj]
[Scheme_Object* port])]{
@scheme[write]s the Scheme value @var{obj} to the given output port.}
@function[(void scheme_write_w_max
[Scheme_Object* obj]
[Scheme_Object* port]
[int n])]{
Like @cpp{scheme_write}, but the printing is truncated to @var{n} bytes.
(If printing is truncated, the last bytes are printed as ``.''.)}
@function[(void scheme_display
[Scheme_Object* obj]
[Scheme_Object* port])]{
@scheme[display]s the Scheme value @var{obj} to the given output
port.}
@function[(void scheme_display_w_max
[Scheme_Object* obj]
[Scheme_Object* port]
[int n])]{
Like @cpp{scheme_display}, but the printing is truncated to @var{n} bytes.
(If printing is truncated, the last three bytes are printed as ``.''.)}
@function[(void scheme_write_byte_string
[char* str]
[long len]
[Scheme_Object* port])]{
Writes @var{len} bytes of @var{str} to the given output port.}
@function[(void scheme_write_char_string
[mzchar* str]
[long len]
[Scheme_Object* port])]{
Writes @var{len} characters of @var{str} to the given output port.}
@function[(long scheme_put_byte_string
[const-char* who]
[Scheme_Object* port]
[char* str]
[long d]
[long len]
[int rarely_block])]{
Writes @var{len} bytes of @var{str}, starting with the @var{d}th
character. Bytes are written to the given output port, and errors are
reported as from @var{who}.
If @var{rarely_block} is @cpp{0}, the write blocks until all @var{len}
bytes are written, possibly to an internal buffer. If
@var{rarely_block} is @cpp{2}, the write never blocks, and written
bytes are not buffered. If @var{rarely_block} is @cpp{1}, the write
blocks only until at least one byte is written (without buffering) or
until part of an internal buffer is flushed.
Supplying @cpp{0} for @var{len} corresponds to a buffer-flush
request. If @var{rarely_block} is @cpp{2}, the flush request is
non-blocking, and if @var{rarely_block} is @cpp{0}, it is blocking.
(A @var{rarely_block} of @cpp{1} is the same as @cpp{0} in this case.)
The result is @cpp{-1} if no bytes are written from @var{str} and
unflushed bytes remain in the internal buffer. Otherwise, the return
value is the number of written characters.}
@function[(long scheme_put_char_string
[const-char* who]
[Scheme_Object* port]
[char* str]
[long d]
[long len])]{
Like @cpp{scheme_put_byte_string}, but for a @cpp{mzchar} string, and
without the non-blocking option.}
@function[(char* scheme_write_to_string
[Scheme_Object* obj]
[long* len])]{
Prints the Scheme value @var{obj} using @scheme[write] to a newly
allocated string. If @var{len} is not @cpp{NULL}, @cpp{*@var{len}} is
set to the length of the bytes string.}
@function[(void scheme_write_to_string_w_max
[Scheme_Object* obj]
[long* len]
[int n])]{
Like @cpp{scheme_write_to_string}, but the string is truncated to
@var{n} bytes. (If the string is truncated, the last three bytes are
``.''.)}
@function[(char* scheme_display_to_string
[Scheme_Object* obj]
[long* len])]{
Prints the Scheme value @var{obj} using @scheme[display] to a newly
allocated string. If @var{len} is not @cpp{NULL}, @cpp{*@var{len}} is
set to the length of the string.}
@function[(void scheme_display_to_string_w_max
[Scheme_Object* obj]
[long* len]
[int n])]{
Like @cpp{scheme_display_to_string}, but the string is truncated to
@var{n} bytes. (If the string is truncated, the last three bytes are
``.''.)}
@function[(void scheme_debug_print
[Scheme_Object* obj])]{
Prints the Scheme value @var{obj} using @scheme[write] to the main
thread's output port.}
@function[(void scheme_flush_output
[Scheme_Object* port])]{
If @var{port} is a file port, a buffered data is written to the file.
Otherwise, there is no effect. @var{port} must be an output port.}
@function[(int scheme_get_byte
[Scheme_Object* port])]{
Get the next byte from the given input port. The result can be @cpp{EOF}.}
@function[(int scheme_getc
[Scheme_Object* port])]{
Get the next character from the given input port (by decoding bytes as UTF-8).
The result can be @cpp{EOF}.}
@function[(int scheme_peek_byte
[Scheme_Object* port])]{
Peeks the next byte from the given input port. The result can be @cpp{EOF}.}
@function[(int scheme_peekc
[Scheme_Object* port])]{
Peeks the next character from the given input port (by decoding bytes as UTF-8).
The result can be @cpp{EOF}.}
@function[(int scheme_peek_byte_skip
[Scheme_Object* port]
[Scheme_Object* skip])]{
Like @cpp{scheme_peek_byte}, but with a skip count. The result can be @cpp{EOF}.}
@function[(int scheme_peekc_skip
[Scheme_Object* port]
[Scheme_Object* skip])]{
Like @cpp{scheme_peekc}, but with a skip count. The result can be @cpp{EOF}.}
@function[(long scheme_get_byte_string
[const-char* who]
[Scheme_Object* port]
[char* buffer]
[int offset]
[long size]
[int only_avail]
[int peek]
[Scheme_Object* peek_skip])]{
Gets multiple bytes at once from a port, reporting errors with the
name @var{who}. The @var{size} argument indicates the number of
requested bytes, to be put into the @var{buffer} array starting at
@var{offset}. The return value is the number of bytes actually read,
or @cpp{EOF} if an end-of-file is encountered without reading any
bytes.
If @var{only_avail} is @cpp{0}, then the function blocks until
@var{size} bytes are read or an end-of-file is reached. If
@var{only_avail} is @cpp{1}, the function blocks only until at least
one byte is read. If @var{only_avail} is @cpp{2}, the function never
blocks. If @var{only_avail} is @cpp{-1}, the function blocks only
until at least one byte is read but also allows breaks (with the
guarantee that bytes are read or a break is raised, but not both).
If @var{peek} is non-zero, then the port is peeked instead of
read. The @var{peek_skip} argument indicates a portion of the input
stream to skip as a non-negative, exact integer (fixnum or bignum). In
this case, an @var{only_avail} value of @cpp{1} means to continue the
skip until at least one byte can be returned, even if it means
multiple blocking reads to skip bytes.
If @var{peek} is zero, then @var{peek_skip} should be either
@cpp{NULL} (which means zero) or the fixnum zero.}
@function[(long scheme_get_char_string
[const-char* who]
[Scheme_Object* port]
[char* buffer]
[int offset]
[long size]
[int peek]
[Scheme_Object* peek_skip])]{
Like @cpp{scheme_get_byte_string}, but for characters (by decoding
bytes as UTF-8), and without the non-blocking option.}
@function[(long scheme_get_bytes
[Scheme_Object* port]
[long size]
[char* buffer]
[int offset])]{
For backward compatibility: calls @cpp{scheme_get_byte_string} in
essentially the obvious way with @var{only_avail} as @cpp{0}; if
@var{size} is negative, then it reads @var{-size} bytes with
@var{only_avail} as @cpp{1}.}
@function[(void scheme_ungetc
[int ch]
[Scheme_Object* port])]{
Puts the byte @var{ch} back as the next character to be read from the
given input port. The character need not have been read from
@var{port}, and @cpp{scheme_ungetc} can be called to insert up to five
characters at the start of @var{port}.
Use @cpp{scheme_get_byte} followed by @cpp{scheme_ungetc} only when
your program will certainly call @cpp{scheme_get_byte} again to
consume the byte. Otherwise, use @cpp{scheme_peek_byte}, because some
a port may implement peeking and getting differently.}
@function[(int scheme_byte_ready
[Scheme_Object* port])]{
Returns 1 if a call to @cpp{scheme_get_byte} is guaranteed not to
block for the given input port.}
@function[(int scheme_char_ready
[Scheme_Object* port])]{
Returns 1 if a call to @cpp{scheme_getc} is guaranteed not to block
for the given input port.}
@function[(void scheme_need_wakeup
[Scheme_Object* port]
[void* fds])]{
Requests that appropriate bits are set in @var{fds} to specify which
file descriptors(s) the given input port reads from. (@var{fds} is
sortof a pointer to an @cppi{fd_set} struct; see
@secref["blockednonmainel"].)}
@function[(long scheme_tell
[Scheme_Object* port])]{
Returns the current read position of the given input port, or the
current file position of the given output port.}
@function[(long scheme_tell_line
[Scheme_Object* port])]{
Returns the current read line of the given input port. If lines are
not counted, -1 is returned.}
@function[(void scheme_count_lines
[Scheme_Object* port])]{
Turns on line-counting for the given input port. To get accurate line
counts, call this function immediately after creating a port.}
@function[(long scheme_set_file_position
[Scheme_Object* port]
[long pos])]{
Sets the file position of the given input or output port (from the
start of the file). If the port does not support position setting, an
exception is raised.}
@function[(void scheme_close_input_port
[Scheme_Object* port])]{
Closes the given input port.}
@function[(void scheme_close_output_port
[Scheme_Object* port])]{
Closes the given output port.}
@function[(int scheme_get_port_file_descriptor
[Scheme_Object* port]
[long* fd])]{
Fills @cpp{*@var{fd}} with a file-descriptor value for @var{port} if
one is available (i.e., the port is a file-stream port and it is not
closed). The result is non-zero if the file-descriptor value is
available, zero otherwise. Under Windows, a ``file dscriptor'' is a
file @cpp{HANDLE}.}
@function[(long scheme_get_port_fd
[Scheme_Object* port]
[Scheme_Object* port]
[long* s])]{
Fills @cpp{*@var{s}} with a socket value for @var{port} if one is
available (i.e., the port is a TCP port and it is not closed). The
result is non-zero if the socket value is available, zero
otherwise. Under Windows, a socket value has type @cpp{SOCKET}.}
@function[(Scheme_Object* scheme_make_port_type
[char* name])]{
Creates a new port subtype.}
@function[(Scheme_Input_Port* scheme_make_input_port
[Scheme_Object* subtype]
[void* data]
[Scheme_Object* name]
[Scheme_Get_String_Fun get_bytes_fun]
[Scheme_Peek_String_Fun peek_bytes_fun]
[Scheme_Progress_Evt_Fun progress_evt_fun]
[Scheme_Peeked_Read_Fun peeked_read_fun]
[Scheme_In_Ready_Fun char_ready_fun]
[Scheme_Close_Input_Fun close_fun]
[Scheme_Need_Wakeup_Input_Fun need_wakeup_fun]
[int must_close])]{
Creates a new input port with arbitrary control functions. The
@var{subtype} is an arbitrary value to distinguish the port's class.
The pointer @var{data} will be installed as the port's user data,
which can be extracted/set with the @cppi{SCHEME_INPORT_VAL} macro.
The @var{name} object is used as the port's name (for
@scheme[object-name] and as the default source name for
@scheme[read-syntax]).
If @var{must_close} is non-zero, the new port will be registered with
the current custodian, and @var{close_fun} is guaranteed to be called
before the port is garbage-collected.
Although the return type of @cpp{scheme_make_input_port} is
@cppi{Scheme_Input_Port*}, it can be cast into a @cpp{Scheme_Object*}.
The functions are as follows.
@subfunction[(long get_bytes_fun
[Scheme_Input_Port* port]
[char* buffer]
[long offset]
[long size]
[int nonblock]
[Scheme_Object* unless])]{
Reads bytes into @var{buffer}, starting from @var{offset}, up to
@var{size} bytes (i.e., @var{buffer} is at least
@var{offset} plus @var{size} long). If @var{nonblock} is @cpp{0},
then the function can block indefinitely, but it should return
when at least one byte of data is available. If @var{nonblock} is
@cpp{1}, the function should never block. If @var{nonblock} is
@cpp{2}, a port in unbuffered mode should return only bytes
previously forced to be buffered; other ports should treat a
@var{nonblock} of @cpp{2} like @cpp{1}. If @var{nonblock} is
@cpp{-1}, the function can block, but should enable breaks while
blocking. The function should return @cpp{0} if no bytes are ready
in non-blocking mode. It should return @cpp{EOF} if an end-of-file
is reached (and no bytes were read into @var{buffer}). Otherwise,
the function should return the number of read bytes. The function
can raise an exception to report an error.
The @var{unless} argument will be non-@cpp{NULL} only when
@var{nonblocking} is non-zero (except as noted below), and only if
the port supports progress events. If @var{unless} is
non-@cpp{NULL} and @cpp{SCHEME_CDR(@var{unless})} is
non-@cpp{NULL}, the latter is a progress event specific to the
port. The @var{get_bytes_fun} function should return
@cppi{SCHEME_UNLESS_READY} instead of reading bytes if the event
in @var{unless} becomes ready before bytes can be read. In
particular, @var{get_bytes_fun} should check the event in
@var{unless} before taking any action, and it should check the
event in @var{unless} after any operation that may allow Scheme
thread swaps. If the read must block, then it should unblock if
the event in @var{unless} becomes ready.
If @cpp{scheme_progress_evt_via_get} is used for
@var{progress_evt_fun}, then @var{unless} can be non-@cpp{NULL}
even when @var{nonblocking} is @cpp{0}. In all modes,
@var{get_bytes_fun} must call @cpp{scheme_unless_ready} to check
@var{unless_evt}. Furthermore, after any potentially
thread-swapping operation, @var{get_bytes_fun} must call
@cpp{scheme_wait_input_allowed}, because another thread may be
attempting to commit, and @var{unless_evt} must be checked after
@cpp{scheme_wait_input_allowed} returns. To block, the port should
use @cpp{scheme_block_until_unless} instead of
@cpp{scheme_block_until}. Finally, in blocking mode,
@var{get_bytes_fun} must return after immediately reading data,
without allowing a Scheme thread swap.}
@subfunction[(long peek_bytes_fun
[Scheme_Input_Port* port]
[char* buffer]
[long offset]
[long size]
[Scheme_Object* skip]
[int nonblock]
[Scheme_Object* unless_evt])]{
Can be @cpp{NULL} to use a default implementation of peeking that
uses @var{get_bytes_fun}. Otherwise, the protocol is the same as
for @var{get_bytes_fun}, except that an extra @var{skip} argument
indicates the number of input elements to skip (but @var{skip}
does not apply to @var{buffer}). The @var{skip} value will be a
non-negative exact integer, either a fixnum or a bignum.}
@subfunction[(Scheme_Object* progress_evt_fun
[Scheme_Input_Port* port])]{
Called to obtain a progress event for the port, such as for
@scheme[port-progress-evt]. This function can be @cpp{NULL} if the
port does not support progress events. Use
@cpp{progress_evt_via_get} to obtain a default implementation, in
which case @var{peeked_read_fun} should be
@cpp{peeked_read_via_get}, and @var{get_bytes_fun} and
@var{peek_bytes_fun} should handle @var{unless} as described
above.}
@subfunction[(int peeked_read_fun
[Scheme_Input_Port* port]
[long amount]
[Scheme_Object* unless_evt]
[Scheme_Object* target_ch])]{
Called to commit previously peeked bytes, just like the sixth
argument to @scheme[make-input-port]. Use
@cpp{peeked_read_via_get} for the default implementation of
commits when @var{progress_evt_fun} is
@cpp{progress_evt_via_get}.}
@subfunction[(int char_ready_fun
[Scheme_Input_Port* port])]{
Returns @cpp{1} when a non-blocking @var{get_bytes_fun} will
return bytes or an @cpp{EOF}.}
@subfunction[(void close_fun
[Scheme_Input_Port* port])]{
Called to close the port. The port is not considered closed until
the function returns.}
@subfunction[(void need_wakeup_fun
[Scheme_Input_Port* port]
[void* fds])]{
Called when the port is blocked on a read; @var{need_wakeup_fun}
should set appropriate bits in @var{fds} to specify which file
descriptor(s) it is blocked on. The @var{fds} argument is
conceptually an array of three @cppi{fd_set} structs (one for
read, one for write, one for exceptions), but manipulate this
array using @cppi{scheme_get_fdset} to get a particular element of
the array, and use @cppi{MZ_FD_XXX} instead of @cpp{FD_XXX} to
manipulate a single ``@cpp{fd_set}''. Under Windows, the first
``@cpp{fd_set}'' can also contain OS-level semaphores or other
handles via @cpp{scheme_add_fd_handle}.}
}
@function[(Scheme_Output_Port* scheme_make_output_port
[Scheme_Object* subtype]
[void* data]
[Scheme_Object* name]
[Scheme_Write_String_Evt_Fun write_bytes_evt_fun]
[Scheme_Write_String_Fun write_bytes_fun]
[Scheme_Out_Ready_Fun char_ready_fun]
[Scheme_Close_Output_Fun close_fun]
[Scheme_Need_Wakeup_Output_Fun need_wakeup_fun]
[Scheme_Write_Special_Fun write_special_fun]
[Scheme_Write_Special_Evt_Fun write_special_evt_fun]
[Scheme_Write_Special_Fun write_special_fun]
[int must_close])]{
Creates a new output port with arbitrary control functions. The
@var{subtype} is an arbitrary value to distinguish the port's class.
The pointer @var{data} will be installed as the port's user data,
which can be extracted/set with the @cppi{SCHEME_OUTPORT_VAL}
macro. The @var{name} object is used as the port's name.
If @var{must_close} is non-zero, the new port will be registered with
the current custodian, and @var{close_fun} is guaranteed to be called
before the port is garbage-collected.
Although the return type of @cpp{scheme_make_output_port} is
@cppi{Scheme_Output_Port*}, it can be cast into a
@cpp{Scheme_Object*}.
The functions are as follows.
@subfunction[(long write_bytes_evt_fun
[Scheme_Output_Port* port]
[const-char* buffer]
[long offset]
[long size])]{
Returns an event that writes up to @var{size} bytes atomically
when event is chosen in a synchronization. Supply @cpp{NULL} if
bytes cannot be written atomically, or supply
@cppi{scheme_write_evt_via_write} to use the default
implementation in terms of @cpp{write_bytes_fun} (with
@var{rarely_block} as @cpp{2}).}
@subfunction[(long write_bytes_fun
[Scheme_Output_Port* port]
[const-char* buffer]
[long offset]
[long size]
[int rarely_block]
[int enable_break])]{
Write bytes from @var{buffer}, starting from @var{offset}, up to
@var{size} bytes (i.e., @var{buffer} is at least
@var{offset} plus @var{size} long). If @var{rarely_block} is @cpp{0},
then the function can block indefinitely, and it can buffer
output. If @var{rarely_block} is @cpp{2}, the function should
never block, and it should not buffer output. If
@var{rarely_block} is @cpp{1}, the function should not buffer
data, and it should block only until writing at least one byte,
either from @var{buffer} or an internal buffer. The function
should return the number of bytes from @var{buffer} that were
written; when @var{rarely_block} is non-zero and bytes remain in
an internal buffer, it should return @cpp{-1}. The @var{size}
argument can be @cpp{0} when @var{rarely_block} is @cpp{0} for a
blocking flush, and it can be @cpp{0} if @var{rarely_block} is
@cpp{2} for a non-blocking flush. If @var{enable_break} is true,
then it should enable breaks while blocking. The function can
raise an exception to report an error.}
@subfunction[(int char_ready_fun
[Scheme_Output_Port* port])]{
Returns @cpp{1} when a non-blocking @var{write_bytes_fun} will
write at least one byte or flush at least one byte from
the port's internal buffer.}
@subfunction[(void close_fun
[Scheme_Output_Port* port])]{
Called to close the port. The port is not considered closed until
the function returns. This function is allowed to block (usually
to flush a buffer) unless
@cpp{scheme_close_should_force_port_closed} returns a non-zero
result, in which case the function must return without blocking.}
@subfunction[(void need_wakeup_fun
[Scheme_Output_Port* port]
[void* fds])]{
Called when the port is blocked on a write; @var{need_wakeup_fun}
should set appropriate bits in @var{fds} to specify which file
descriptor(s) it is blocked on. The @var{fds} argument is
conceptually an array of three @cppi{fd_set} structs (one for
read, one for write, one for exceptions), but manipulate this
array using @cppi{scheme_get_fdset} to get a particular element of
the array, and use @cppi{MZ_FD_XXX} instead of @cpp{FD_XXX} to
manipulate a single ``@cpp{fd_set}''. Under Windows, the first
``@cpp{fd_set}'' can also contain OS-level semaphores or other
handles via @cpp{scheme_add_fd_handle}.}
@subfunction[(int write_special_evt_fun
[Scheme_Output_Port* port]
[Scheme_Object* v])]{
Returns an event that writes @var{v} atomically when event is
chosen in a synchronization. Supply @cpp{NULL} if specials cannot
be written atomically (or at all), or supply
@cppi{scheme_write_special_evt_via_write_special} to use the
default implementation in terms of @cpp{write_special_fun} (with
@var{non_block} as @cpp{1}).}
@subfunction[(int write_special_fun
[Scheme_Output_Port* port]
[Scheme_Object* v]
[int non_block])]{
Called to write the special value @var{v} for
@scheme[write-special] (when @var{non_block} is @cpp{0}) or
@scheme[write-special-avail*] (when @var{non_block} is
@cpp{1}). If @cpp{NULL} is supplied instead of a function pointer,
then @scheme[write-special] and @scheme[write-special-avail*]
produce an error for this port.}
}
@function[(Scheme_Object* scheme_make_file_input_port
[FILE* fp])]{
Creates a Scheme input file port from an ANSI C file pointer. The file
must never block on reads.}
@function[(Scheme_Object* scheme_open_input_file
[const-char* filename]
[const-char* who])]{
Opens @var{filename} for reading. In an exception is raised, the
exception message uses @var{who} as the name of procedure that raised
the exception.}
@function[(Scheme_Object* scheme_make_named_file_input_port
[FILE* fp]
[Scheme_Object* name])]{
Creates a Scheme input file port from an ANSI C file pointer. The file
must never block on reads. The @var{name} argument is used as the
port's name.}
@function[(Scheme_Object* scheme_open_output_file
[const-char* filename]
[const-char* who])]{
Opens @var{filename} for writing in @scheme['truncate/replace] mode. If
an exception is raised, the exception message uses @var{who} as the
name of procedure that raised the exception.}
@function[(Scheme_Object* scheme_make_file_output_port
[FILE* fp])]{
Creates a Scheme output file port from an ANSI C file pointer. The
file must never block on writes.}
@function[(Scheme_Object* scheme_make_fd_input_port
[int fd]
[Scheme_Object* name]
[int regfile]
[int win_textmode]
[int fd]
[Scheme_Object* name]
[int regfile]
[int win_textmode]
[int read_too]
[long s]
[const-char* name]
[int close]
[Scheme_Object** inp]
[Scheme_Object** outp]
[char* str])]{
Creates a Scheme input port from a byte string; successive
@scheme[read-char]s on the port return successive bytes in the
string.}
@function[(Scheme_Object* scheme_make_byte_string_output_port)]{
Creates a Scheme output port; all writes to the port are kept in a byte string,
which can be obtained with @cpp{scheme_get_byte_string_output}.}
@function[(char* scheme_get_byte_string_output
[Scheme_Object* port])]{
Returns (in a newly allocated byte string) all data that has been
written to the given string output port so far. (The returned string
is nul-terminated.)}
@function[(char* scheme_get_sized_byte_string_output
[Scheme_Object* port]
[long* len])]{
Returns (in a newly allocated byte string) all data that has been
written to the given string output port so far and fills in
@cpp{*len} with the length of the string in bytes (not including the
nul terminator).}
@function[(void scheme_pipe
[Scheme_Object** read]
[Scheme_Object** write])]{
Creates a pair of ports, setting @cpp{*@var{read}} and
@cpp{*@var{write}}; data written to @cpp{*@var{write}} can be read
back out of @cpp{*@var{read}}. The pipe can store arbitrarily many
unread characters,}
@function[(void scheme_pipe_with_limit
[Scheme_Object** read]
[Scheme_Object** write]
[int limit])]{
Like @cpp{scheme_pipe} is @var{limit} is @cpp{0}. If @var{limit} is
positive, creates a pipe that stores at most @var{limit} unread
characters, blocking writes when the pipe is full.}
@function[(Scheme_Input_Port* scheme_input_port_record
[Scheme_Object* port])]{
Returns the input-port record for @var{port}, which may be either a
raw-port object with type @cpp{scheme_input_port_type} or a structure
with the @scheme[prop:input-port] property.}
@function[(Scheme_Output_Port* scheme_output_port_record
[Scheme_Object* port])]{
Returns the output-port record for @var{port}, which may be either a
raw-port object with type @cpp{scheme_output_port_type} or a structure
with the @scheme[prop:output-port] property.}
@function[(int scheme_file_exists
[char* name])]{
Returns 1 if a file by the given name exists, 0 otherwise. If
@var{name} specifies a directory, FALSE is returned.
The @var{name} should be already expanded.}
@function[(int scheme_directory_exists
[char* name])]{
Returns 1 if a directory by the given name exists, 0 otherwise. The
@var{name} should be already expanded.}
@function[(char* scheme_expand_filename
[const-char* name]
[int len]
[const-char* where]
[int* expanded]
[int checks])]{
Cleanses the pathname @var{name} (see @scheme[cleanse-path]) and
resolves relative paths with respect to the current directory
parameter. The @var{len} argument is the length of the input string;
if it is -1, the string is assumed to be null-terminated. The
@var{where} argument is used to raise an exception if there is an
error in the filename; if this is @cpp{NULL}, an error is not reported
and @cpp{NULL} is returned instead. If @var{expanded} is not
@cpp{NULL}, *@var{expanded} is set to 1 if some expansion takes place,
or 0 if the input name is simply returned.
If @var{guards} is not @cpp{0}, then @cpp{scheme_security_check_file}
(see @secref["security"]) is called with @var{name}, @var{where}, and
@var{checks} (which implies that @var{where} should never be
@cpp{NULL} unless @var{guards} is @cpp{0}). Normally, @var{guards}
should be @cpp{SCHEME_GUARD_FILE_EXISTS} at a minimum. Note that a
failed access check will result in an exception.}
@function[(char* scheme_expand_string_filename
[Scheme_Object* name]
[const-char* where]
[int* expanded]
[int checks])]{
Like @cpp{scheme_expand_string}, but given a @var{name} that can be a
character string or a path value.}
@function[(Scheme_Object* scheme_char_string_to_path
[Scheme_Object* s])]{
Converts a Scheme character string into a Scheme path value.}
@function[(Scheme_Object* scheme_path_to_char_string
[Scheme_Object* s])]{
Converts a Scheme path value into a Scheme character string.}
@function[(Scheme_Object* scheme_make_path
[char* bytes])]{
Makes a path value given a byte string. The @var{bytes} string is copied.}
@function[(Scheme_Object* scheme_make_path_without_copying
[char* bytes])]{
Like @cpp{scheme_make_path}, but the string is not copied.}
@function[(Scheme_Object* scheme_make_sized_path
[char* bytes]
[long len]
[int copy])]{
Makes a path whose byte form has size @var{len}. A copy of @var{bytes}
is made if @var{copy} is not 0. The string @var{bytes} should contain
@var{len} bytes, and if @var{copy} is zero, @var{bytes} must have a
nul terminator in addition. If @var{len} is negative, then the
nul-terminated length of @var{bytes} is used for the length.}
@function[(Scheme_Object* scheme_make_sized_offset_path
[char* bytes]
[long d]
[long len]
[int copy])]{
Like @cpp{scheme_make_sized_path}, except the @var{len} bytes start
from position @var{d} in @var{bytes}. If @var{d} is non-zero, then
@var{copy} must be non-zero.}
@function[(char* scheme_build_mac_filename
[FSSpec* spec]
[int isdir])]{
Mac OS X only: Converts an @cppi{FSSpec} record (defined by Mac OS X)
into a pathname string. If @var{spec} contains only directory
information (via the @cpp{vRefNum} and @cpp{parID} fields),
@var{isdir} should be @cpp{1}, otherwise it should be @cpp{0}.}
@function[(int scheme_mac_path_to_spec
[const-char* filename]
[FSSpec* spec]
[long* type])]{
Mac OS X only: Converts a pathname into an @cppi{FSSpec} record
(defined by Mac OS X), returning @cpp{1} if successful and @cpp{0}
otherwise. If @var{type} is not @cpp{NULL} and @var{filename} is a
file that exists, @var{type} is filled with the file's four-character
Mac OS X type. If @var{type} is not @cpp{NULL} and @var{filename} is
not a file that exists, @var{type} is filled with @cpp{0}.}
@function[(char* scheme_os_getcwd
[char* buf]
[int buflen]
[int* actlen]
[int noexn])]{
Gets the @as-index{current working directory} according to the
operating system. This is separate from MzScheme's current directory
parameter.
The directory path is written into @var{buf}, of length @var{buflen},
if it fits. Otherwise, a new (collectable) string is allocated for the
directory path. If @var{actlen} is not @cpp{NULL}, *@var{actlen} is
set to the length of the current directory path. If @var{noexn} is
no 0, then an exception is raised if the operation fails.}
@function[(int scheme_os_setcwd
[char* buf]
[int noexn])]{
Sets the current working directory according to the operating system. This
is separate from MzScheme's current directory parameter.
If @var{noexn} is not 0, then an exception is raised if the operation
fails.}
@function[(char* scheme_format
[mzchar* format]
[int flen]
[int argc]
[Scheme_Object** argv]
[long* rlen])]{
Creates a string like MzScheme's @scheme[format] procedure, using the
format string @var{format} (of length @var{flen}) and the extra
arguments specified in @var{argc} and @var{argv}. If @var{rlen} is not
@cpp{NULL}, @cpp{*@var{rlen}} is filled with the length of the
resulting string.}
@function[(void scheme_printf
[char* format]
[int flen]
[int argc]
[Scheme_Object** argv])]{
Writes to the current output port like MzScheme's @scheme[printf]
procedure, using the format string @var{format} (of length @var{flen})
and the extra arguments specified in @var{argc} and @var{argv}.}
@function[(char* scheme_format_utf8
[char* format]
[int flen]
[int argc]
[Scheme_Object** argv]
[long* rlen])]{
Like @cpp{scheme_format}, but takes a UTF-8-encoding byte string.}
@function[(void scheme_printf_utf8
[char* format]
[int flen]
[int argc]
[Scheme_Object** argv])]{
Like @cpp{scheme_printf}, but takes a UTF-8-encoding byte string.}
@function[(int scheme_close_should_force_port_closed)]{
This function must be called by the close function for a port created
with @cpp{scheme_make_output_port}.}