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.

13.1  Library Functions

¤ Scheme_Object *scheme_read(Scheme_Object *port)

Reads the next S-expression from the given input port.

¤ void scheme_write(Scheme_Object *obj, Scheme_Object *port)

writes the Scheme value obj to the given output port.

¤ void scheme_write_w_max(Scheme_Object *obj, Scheme_Object *port, int n)

Like scheme_write, but the printing is truncated to n bytes. (If printing is truncated, the last bytes are printed as ``.''.)

¤ void scheme_display(Scheme_Object *obj, Scheme_Object *port)

displays the Scheme value obj to the given output port.

¤ void scheme_display_w_max(Scheme_Object *obj, Scheme_Object *port, int n)

Like scheme_display, but the printing is truncated to n bytes. (If printing is truncated, the last three bytes are printed as ``.''.)

¤ void scheme_write_byte_string(char *str, long len, Scheme_Object *port)

Writes len bytes of str to the given output port.

¤ void scheme_write_char_string(mzchar *str, long len, Scheme_Object *port)

Writes len characters of str to the given output port.

¤ long scheme_put_byte_string(const char *who, Scheme_Object *port,
    char *str, long d, long len,
    int rarely_block)

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.

¤ long scheme_put_char_string(const char *who, Scheme_Object *port,
    char *str, long d, long len)

Like scheme_put_byte_string, but for a mzchar string, and without the non-blocking option.

¤ char *scheme_write_to_string(Scheme_Object *obj, long *len)

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.

¤ void scheme_write_to_string_w_max(Scheme_Object *obj, long *len, int n)

Like scheme_write_to_string, but the string is truncated to n bytes. (If the string is truncated, the last three bytes are ``.''.)

¤ char *scheme_display_to_string(Scheme_Object *obj, long *len)

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.

¤ void scheme_display_to_string_w_max(Scheme_Object *obj, long *len, int n)

Like scheme_display_to_string, but the string is truncated to n bytes. (If the string is truncated, the last three bytes are ``.''.)

¤ void scheme_debug_print(Scheme_Object *obj)

Prints the Scheme value obj using write to the main thread's output port.

¤ void scheme_flush_output(Scheme_Object *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.

¤ int scheme_get_byte(Scheme_Object *port)

Get the next byte from the given input port. The result can be EOF.

¤ 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 EOF.

¤ int scheme_peek_byte(Scheme_Object *port)

Peeks the next byte from the given input port. The result can be EOF.

¤ 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 EOF.

¤ int scheme_peek_byte_skip(Scheme_Object *port, Scheme_Object *skip)

Like scheme_peek_byte, but with a skip count. The result can be EOF.

¤ int scheme_peekc_skip(Scheme_Object *port, Scheme_Object *skip)

Like scheme_peekc, but with a skip count. The result can be EOF.

¤ 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 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.

¤ long scheme_get_char_string(const char *who, Scheme_Object *port,
   char *buffer, int offset, long size,
   int peek, Scheme_Object *peek_skip)

Like scheme_get_byte_string, but for characters (by decoding bytes as UTF-8), and without the non-blocking option.

¤ long scheme_get_bytes(Scheme_Object *port, long size, char *buffer, int offset)

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.

¤ void scheme_ungetc(int ch, Scheme_Object *port)

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.

¤ int scheme_byte_ready(Scheme_Object *port)

Returns 1 if a call to scheme_get_byte is guaranteed not to block for the given input port.

¤ int scheme_char_ready(Scheme_Object *port)

Returns 1 if a call to scheme_getc is guaranteed not to block for the given input port.

¤ void scheme_need_wakeup(Scheme_Object *port, void *fds)

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 section 8.4.1.)

¤ 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.

¤ 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.

¤ 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.

¤ 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.

¤ void scheme_close_input_port(Scheme_Object *port)

Closes the given input port.

¤ void scheme_close_output_port(Scheme_Object *port)

Closes the given output port.

¤ int scheme_get_port_file_descriptor(Scheme_Object *port, long *fd)

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.

¤ int scheme_get_port_socket(Scheme_Object *port, long *s)

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.

¤ Scheme_Object *scheme_make_port_type(char *name)

Creates a new port subtype.

¤ 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 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).

The functions are as follows:

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 *.

¤ 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 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.

The functions are as follows:

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 *.

¤ 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.

¤ Scheme_Object *scheme_open_input_file(const char *filename, const char *who)

Opens filename for reading. In an exception is raised, the exception message uses who as the name of procedure that raised the exception.

¤ 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 name argument is used as the port's name.

¤ Scheme_Object *scheme_open_output_file(const char *filename, const char *who)

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.

¤ 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.

¤ Scheme_Object *scheme_make_fd_input_port(int fd, Scheme_Object *name,
    int regfile, int win_textmode)

Creates a Scheme input port for a file descriptor fd. Under Windows, fd can be a HANDLE for a stream, and it should never be a file descriptor from the C library or a WinSock socket.

The name object is used for the port's name. Specify a non-zero value for regfile only if the file descriptor corresponds to a regular file (which implies that reading never blocks, for example).

Under Windows, win_textmode can be non-zero to make trigger auto-conversion (at the byte level) of CRLF combinations to LF.

Closing the resulting port closes the file descriptor.

Instead of calling both scheme_make_fd_input_port and scheme_make_fd_output_port on the same file descriptor, call scheme_make_fd_output_port with a non-zero last argument. Otherwise, closing one of the ports causes the other to be closed as well.

¤ Scheme_Object *scheme_make_fd_output_port(int fd, Scheme_Object *name,
    int regfile, int win_textmode, int read_too)

Creates a Scheme output port for a file descriptor fd. Under Windows, fd can be a HANDLE for a stream, and it should never be a file descriptor from the C library or a WinSock socket.

The name object is used for the port's name. Specify a non-zero value for regfile only if the file descriptor corresponds to a regular file (which implies that reading never blocks, for example).

Under Windows, win_textmode can be non-zero to make trigger auto-conversion (at the byte level) of CRLF combinations to LF.

Closing the resulting port closes the file descriptor.

If read_too is non-zero, the function produces multiple values (see section 6.3) instead of a single port. The first result is an input port for fd, and the second is an output port for fd. These ports are connected in that the file descriptor is closed only when both of the ports are closed.

¤ Scheme_Object *scheme_make_byte_string_input_port(char *str)

Creates a Scheme input port from a byte string; successive read-chars on the port return successive bytes in the string.

¤ 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 scheme_get_byte_string_output.

¤ 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.)

¤ 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 *len with the length of the string in bytes (not including the nul terminator).

¤ void scheme_pipe(Scheme_Object **read, Scheme_Object **write)

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,

¤ void scheme_pipe_with_limit(Scheme_Object **read, Scheme_Object **write, int limit)

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.

¤ int scheme_file_exists(char *name)

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.

¤ int scheme_directory_exists(char *name)

Returns 1 if a directory by the given name exists, 0 otherwise. The name should be already expanded.

¤ char *scheme_expand_filename(const char *name, int len, const char *where, int *expanded,
    int checks)

Expands the pathname name, resolving relative paths with respect to the current directory parameter. Under Unix, this expands ``~'' into a user's home directory. 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 section 15) 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.

¤ char *scheme_expand_string_filename(Scheme_Object *name, const char *where, int *expanded,
    int checks)

Like scheme_expand_string, but given a name that can be a character string or a path value.

¤ Scheme_Object *scheme_char_string_to_path(Scheme_Object *s)

Converts a Scheme character string into a Scheme path value.

¤ Scheme_Object *scheme_path_to_char_string(Scheme_Object *s)

Converts a Scheme path value into a Scheme character string.

¤ Scheme_Object *scheme_make_path(char *bytes)

Makes a path value given a byte string. The bytes string is copied.

¤ Scheme_Object *scheme_make_path_without_copying(char *bytes)

Like scheme_make_path, but the string is not copied.

¤ Scheme_Object *scheme_make_sized_path(char *bytes, long len, int copy)

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.

¤ Scheme_Object *scheme_make_sized_path(char *bytes, long d, long len, int copy)

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.

¤ char *scheme_build_mac_filename(FSSpec *spec, int isdir)

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.

¤ int scheme_mac_path_to_spec(const char *filename, FSSpec *spec, long *type)

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.

¤ char *scheme_os_getcwd(char *buf, int buflen, int *actlen, int noexn)

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.

¤ 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 noexn is not 0, then an exception is raised if the operation fails.

¤ char *scheme_format(mzchar *format, int flen, int argc, Scheme_Object **argv, long *rlen)

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.

¤ void scheme_printf(char *format, int flen, int argc, Scheme_Object **argv)

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.

¤ char *scheme_format_utf8(char *format, int flen, int argc, Scheme_Object **argv, long *rlen)

Like scheme_format, but takes a UTF-8-encoding byte string.

¤ void scheme_printf_utf8(char *format, int flen, int argc, Scheme_Object **argv)

Like scheme_printf, but takes a UTF-8-encoding byte string.

¤ int scheme_close_should_force_port_closed()

This function must be called by the close function for a port created with scheme_make_output_port.