22 Ports and the Filesystem (BC)

Ports are represented as Racket 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 Racket, use scheme_expand_filename to normalize the filename and resolve relative paths.

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 Racket 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,

 

 

 

 

intptr_t len,

 

 

 

 

Scheme_Object* port)

Writes len bytes of str to the given output port.

void

 

scheme_write_char_string

(

mzchar* str,

 

 

 

 

intptr_t len,

 

 

 

 

Scheme_Object* port)

Writes len characters of str to the given output port.

intptr_t

 

scheme_put_byte_string

(

const char* who,

 

 

 

 

Scheme_Object* port,

 

 

 

 

char* str,

 

 

 

 

intptr_t d,

 

 

 

 

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

intptr_t

 

scheme_put_char_string

(

const char* who,

 

 

 

 

Scheme_Object* port,

 

 

 

 

char* str,

 

 

 

 

intptr_t d,

 

 

 

 

intptr_t 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,

 

 

 

 

intptr_t* len)

Prints the Racket 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,

 

 

 

 

intptr_t* 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,

 

 

 

 

intptr_t* len)

Prints the Racket 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,

 

 

 

 

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

intptr_t

 

scheme_get_byte_string

(

const char* who,

 

 

 

 

Scheme_Object* port,

 

 

 

 

char* buffer,

 

 

 

 

int offset,

 

 

 

 

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

intptr_t

 

scheme_get_char_string

(

const char* who,

 

 

 

 

Scheme_Object* port,

 

 

 

 

char* buffer,

 

 

 

 

int offset,

 

 

 

 

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

intptr_t

 

scheme_get_bytes

(

Scheme_Object* port,

 

 

 

 

intptr_t 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 Callbacks for Blocked Threads.)

intptr_t

 

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.

intptr_t

 

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.

intptr_t

 

scheme_set_file_position

(

Scheme_Object* port,

 

 

 

 

intptr_t 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,

 

 

 

 

intptr_t* 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. On Windows, a “file descriptor” is a file HANDLE.

intptr_t

 

scheme_get_port_fd

(

Scheme_Object* port)

Like scheme_get_port_file_descriptor, but a file descriptor or HANDLE is returned directly, and the result is -1 if no file descriptor or HANDLE is available.

intptr_t

 

scheme_get_port_socket

(

Scheme_Object* port,

 

 

 

 

intptr_t* 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. On 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).

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.

intptr_t

 

get_bytes_fun

(

Scheme_Input_Port* port,

 

 

 

 

char* buffer,

 

 

 

 

intptr_t offset,

 

 

 

 

intptr_t 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 Racket 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 Racket thread swap.

intptr_t

 

peek_bytes_fun

(

Scheme_Input_Port* port,

 

 

 

 

char* buffer,

 

 

 

 

intptr_t offset,

 

 

 

 

intptr_t 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 scheme_progress_evt_via_get to obtain a default implementation, in which case peeked_read_fun should be scheme_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,

 

 

 

 

intptr_t 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 scheme_peeked_read_via_get for the default implementation of commits when progress_evt_fun is scheme_progress_evt_via_get.

The peeked_read_fun function must call scheme_port_count_lines on a successful commit to adjust the port’s position. If line counting is enabled for the port and if line counting uses the default implementation, peeked_read_fun should supply a non-NULL byte-string argument to scheme_port_count_lines, so that character and line counts can be tracked correctly.

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”. On Windows, the first “fd_set” can also contain OS-level semaphores or other handles via scheme_add_fd_handle.

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

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.

intptr_t

 

write_bytes_evt_fun

(

Scheme_Output_Port* port,

 

 

 

 

const char* buffer,

 

 

 

 

intptr_t offset,

 

 

 

 

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

intptr_t

 

write_bytes_fun

(

Scheme_Output_Port* port,

 

 

 

 

const char* buffer,

 

 

 

 

intptr_t offset,

 

 

 

 

intptr_t 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”. On 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.

void

scheme_set_port_location_fun

(

Scheme_Port* port,

 

 

Scheme_Location_Fun location_fun)

Sets the implementation of port-next-location for port, which is used when line counting is enabled for port.

Scheme_Object*

 

location_fun

(

Scheme_Port* port)

Returns three values: a positive exact integer or #f for a line number, a non-negative exact integer or #f for a column (which must be #f if and only if the line number is #f), and a positive exact integer or #f for a character position.

void

scheme_set_port_count_lines_fun

(

Scheme_Port* port,

 

 

Scheme_Count_Lines_Fun count_lines_fun)

Installs a notification callback that is invoked if line counting is subsequently enabled for port.

void

 

count_lines_fun

(

Scheme_Port* port)

void

 

scheme_port_count_lines

(

Scheme_Port* port,

 

 

 

 

const char* buffer,

 

 

 

 

intptr_t offset,

 

 

 

 

intptr_t got)

Updates the position of port as reported by file-position as well as the locations reported by port-next-location when the default implement of character and line counting is used. This function is intended for use by a peek-commit implementation in an input port.

The got argument indicates the number of bytes read from or written to port. The buffer argument is used only when line counting is enabled, and it represents specific bytes read or written for the purposes of character and line coutning. The buffer argument can be NULL, in which case got non-newline characters are assumed. The offset argument indicates a starting offset into buffer, so "buffer" must be at least offset plus got bytes long.

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. If 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 Racket 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 Racket 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 Racket input port for a file descriptor fd. On 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).

On 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 file descriptor used by 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 Racket output port for a file descriptor fd. On 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).

On 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 Multiple Values) 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.

void

 

scheme_socket_to_ports

(

intptr_t s,

 

 

 

 

const char* name,

 

 

 

 

int close,

 

 

 

 

Scheme_Object** inp,

 

 

 

 

Scheme_Object** outp)

Creates Racket input and output ports for a TCP socket s. The name argument supplies the name for the ports. If close is non-zero, then the ports assume responsibility for closing the socket. The resulting ports are written to inp and outp.

Whether close is zero or not, closing the resulting ports unregisters the file descriptor with scheme_fd_to_semaphore. So, passing zero for close and also using the file descriptor with other ports or with scheme_fd_to_semaphore will not work right.

Changed in version 6.9.0.6: Changed ports to always unregister with scheme_fd_to_semaphore, since it’s not safe to skip that step.

Scheme_Object*

 

scheme_fd_to_semaphore

(

intptr_t fd,

 

 

 

 

int mode,

 

 

 

 

int is_socket)

Creates or finds a Racket semaphore that becomes ready when fd is ready. The semaphore reflects a registration with the operating system’s underlying mechanisms for efficient polling. When a semaphore is created, it remains findable via scheme_fd_to_semaphore for a particular read/write mode as long as fd has not become ready in the read/write mode since the creation of the semaphore, or unless MZFD_REMOVE has been used to remove the registered semaphore. The is_socket argument indicates whether fd is a socket or a filesystem descriptor; the difference matters for Windows, and it matters for BSD-based platforms where sockets are always supported and other file descriptors are tested for whether they correspond to a directory or regular file.

The mode argument is one of the following:

Scheme_Object*

 

scheme_make_byte_string_input_port

(

char* str)

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

Creates a Racket 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,

 

 

 

 

intptr_t* 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 if limit is 0. If limit is positive, creates a pipe that stores at most limit unread characters, blocking writes when the pipe is full.

Scheme_Input_Port*

 

scheme_input_port_record

(

Scheme_Object* port)

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.

Scheme_Output_Port*

scheme_output_port_record

(

Scheme_Object* port)

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.

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)

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 (BC)) 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 Racket character string into a Racket path value.

Scheme_Object*

 

scheme_path_to_char_string

(

Scheme_Object* s)

Converts a Racket path value into a Racket 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,

 

 

 

 

intptr_t 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_offset_path

(

char* bytes,

 

 

 

 

intptr_t d,

 

 

 

 

intptr_t 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 only: Converts an FSSpec record (defined by Mac OS) 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,

 

 

 

 

intptr_t* type)

Mac OS only: Converts a pathname into an FSSpec record (defined by Mac OS), 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 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 Racket’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 Racket’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,

 

 

 

 

intptr_t* rlen)

Creates a string like Racket’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 Racket’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,

 

 

 

 

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

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