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