NAME ^

src/io/io.c - Generic IO

DESCRIPTION ^

The Parrot IO subsystem uses a per-interpreter stack to provide a layer-based approach to IO. Each layer implements a subset of the ParrotIOLayerAPI vtable. To find an IO function, Parrot searches the layer stack downwards until it finds a non-NULL function pointer for that particular slot.

This file implements the generic functionality. Specific layers are in separate files: src/io/io_buf.c, src/io/io_stdio.c, src/io/io_unix.c, src/io/io_win32.c, and src/io/io_layers.c.

The ParrotIO PMC provides the class-based interface that is used in Parrot ops. The ParrotIO struct is defined in src/io/io_private.h.

Resource Functions ^

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC *new_io_pmc(PARROT_INTERP, NULLOK(ParrotIO *io))

Creates and returns a new ParrotIO PMC.

PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL STRING *PIO_make_io_string(PARROT_INTERP, NOTNULL(STRING **buf), size_t len)

Creates a STRING* suitable for returning results from IO read functions. The passed in buf parameter can:

  1. Point to a NULL STRING
  2. Point to a real STRING
  3. Point to a fake STRING with (strstart, bufused) holding the *buffer information.
In the third case, the buffer or STRING must be able to hold the required amount of data. For cases 1 and 2, a NULL strstart tells this function to allocate the STRING memory.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL ParrotIO *PIO_new(PARROT_INTERP, SHIM(INTVAL iotype), INTVAL flags, INTVAL mode)

Creates a new IO stream.

The values of flags and mode are set in the returned ParrotIO.

Currently iotype is unused.

PARROT_API void PIO_destroy(SHIM_INTERP, NOTNULL(PMC *pmc))

Destroys the IO stream. At the moment, this only frees the memory and removes the pointers from the PMC.

PARROT_API void PIO_init(PARROT_INTERP)

Sets up the interpreter's layer stack and creates the STD* handles.

Called when creating an interpreter.

PARROT_API void PIO_finish(PARROT_INTERP)

Closes the interpreter's IO resourses. Called during its interpreter destruction.

PARROT_API void PIO_internal_shutdown(SHIM_INTERP)

IO system destructor, called on destruction of the last interpreter.

PARROT_API INTVAL PIO_init_stacks(PARROT_INTERP)

Initializes the interpreter's default IO stack by pushing on the IO layers (OS-specific first).

PARROT_API INTVAL PIO_base_init(SHIM_INTERP, SHIM(ParrotIOLayer *l))

Init routine called once for each layer at interpreter creation time. This is similar to a Perl module INIT {} block.

This default implementation does nothing and returns 0.

Generic top-level ParrotIO interface ^

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL PIO_parse_open_flags(ARGIN_NULLOK(const char *flagstr))

Parses *flagstr for Perl-style file open mode flags (<, >, >>, +<, +>) and returns the combined generic bit flags.

The low level OS layers may then interpret the generic bits differently depending on platform.

XXX BD Should this be static?

PARROT_API INTVAL PIO_peek(PARROT_INTERP, NOTNULL(PMC *pmc), NOTNULL(STRING **buffer))

Iterates down the stack to the first layer implementing "Peek" API.

PARROT_API INTVAL PIO_pioctl(PARROT_INTERP, NOTNULL(PMC *pmc), INTVAL cmd, INTVAL arg)

General purpose interface for manipulating IO objects and layer attributes.

Refer to the PIOCTL* values in include/parrot/io.h.

All set operations return 0 on success and a negative value on error. get operations use the return value as the value requested, but should always be >= 0. A negative value indicates an error. This may be too limited, but we will see. --Melvin

PARROT_API INTVAL PIO_setbuf(PARROT_INTERP, NOTNULL(PMC *pmc), size_t bufsize)

Sets the buffer size for *pmc to bufsize. Returns 0 if the buffering was enabled.

PARROT_API INTVAL PIO_setlinebuf(PARROT_INTERP, NOTNULL(PMC *pmc))

Enables line buffering for *pmc. Returns 0 if line buffering was successfully set, or already enabled.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC *PIO_open(PARROT_INTERP, NULLOK(ParrotIOLayer *layer), ARGIN(const char *spath), ARGIN(const char *sflags))

Creates and returns a ParrotIO PMC for *spath.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC *PIO_fdopen(PARROT_INTERP, NULLOK(ParrotIOLayer *layer), PIOHANDLE fd, ARGIN(const char *sflags))

Creates and returns a ParrotIO PMC for *spath on an existing, open file descriptor.

This is used particularly to initialize the STD* IO handles onto the OS IO handles (0, 1, 2).

PARROT_API INTVAL PIO_close(PARROT_INTERP, NULLOK(PMC *pmc))

Flushes, closes, and destroys the ParrotIO PMC *pmc.

PARROT_API void PIO_flush(PARROT_INTERP, NOTNULL(PMC *pmc))

Flushes the ParrotIO PMC *pmc.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL STRING *PIO_reads(PARROT_INTERP, NOTNULL(PMC *pmc), size_t len)

Return a new STRING* holding up to len bytes.

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL PIO_read(PARROT_INTERP, NOTNULL(PMC *pmc), NOTNULL(char *buffer), size_t len)

Reads up to len bytes from *pmc and copies them into *buffer.

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL PIO_write(PARROT_INTERP, NOTNULL(PMC *pmc), ARGIN(const void *buffer), size_t len)

Writes len bytes from *buffer to *pmc.

PARROT_API PARROT_WARN_UNUSED_RESULT PIOOFF_T PIO_seek(PARROT_INTERP, NOTNULL(PMC *pmc), PIOOFF_T offset, INTVAL w)

Moves the read/write position of *pmc to offset bytes from the position indicated by w. Typically w will be 0 for the start of the file, 1 for the current position, and 2 for the end.

PARROT_API PARROT_WARN_UNUSED_RESULT PIOOFF_T PIO_tell(PARROT_INTERP, NOTNULL(PMC *pmc))

Returns the current read/write position of *pmc.

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL PIO_eof(SHIM_INTERP, NOTNULL(PMC *pmc))

Returns a boolean value indication whether *pmc's current read/write position is EOF.

PARROT_API INTVAL PIO_puts(PARROT_INTERP, NOTNULL(PMC *pmc), ARGIN(const char *s))

Writes *s tp *pmc. C string version.

PARROT_API INTVAL PIO_putps(PARROT_INTERP, NOTNULL(PMC *pmc), NULLOK(STRING *s))

Writes *s to *pmc. Parrot string version.

PARROT_API INTVAL PIO_fprintf(PARROT_INTERP, NOTNULL(PMC *pmc), ARGIN(const char *s), ...)

Writes a C string format with varargs to *pmc.

PARROT_API INTVAL PIO_printf(PARROT_INTERP, ARGIN(const char *s), ...)

Writes a C string format with varargs to stdout.

PARROT_API INTVAL PIO_eprintf(NULLOK(PARROT_INTERP), ARGIN(const char *s), ...)

Writes a C string format with varargs to stderr.

PARROT_API PARROT_WARN_UNUSED_RESULT PIOHANDLE PIO_getfd(SHIM_INTERP, NOTNULL(PMC *pmc))

Returns *pmc's file descriptor, or 0 if it is not defined.

PIO_STD* Functions ^

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC *PIO_STDIN(PARROT_INTERP)

Returns the ParrotIO PMC for stdin.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC *PIO_STDOUT(PARROT_INTERP)

Returns the ParrotIO PMC for stdout.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC *PIO_STDERR(PARROT_INTERP)

Returns the ParrotIO PMC for stderr.

DOD-related Functions ^

PARROT_API void Parrot_IOData_mark(PARROT_INTERP, NOTNULL(ParrotIOData *piodata))

Called from trace_active_PMCs() to mark the IO data live.

Offset Functions ^

These are used to create offsets for the seek op.

PIOOFF_T PIO_make_offset(INTVAL offset)

Returns offset.

PIOOFF_T PIO_make_offset32(INTVAL hi, INTVAL lo)

hi is shifted 32 bytes to the left and ored together with lo. This allows 64-bit seeks with only 32-bit INTVALS.

PIOOFF_T PIO_make_offset_pmc(PARROT_INTERP, NOTNULL(PMC *pmc))

Returns the return value of the get_integer vtable method on *pmc.

Networking Functions ^

PARROT_API INTVAL PIO_poll(PARROT_INTERP, NOTNULL(PMC *pmc), INTVAL which, INTVAL sec, INTVAL usec)

Polls *pmc for the events in which every sec seconds + usec microseconds.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL PMC *PIO_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto)

Creates and returns a socket using the specified address family, socket type, and protocol number. Check the returned PMC with a boolean test to see whether the socket was successfully created.

PARROT_API INTVAL PIO_recv(PARROT_INTERP, NOTNULL(PMC *pmc), NOTNULL(STRING **buf))

Receives a message from the connected socket *pmc in *buf. Returns -1 if it fails.

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL PIO_send(PARROT_INTERP, NOTNULL(PMC *pmc), NOTNULL(STRING *buf))

Sends the message *buf to the connected socket *pmc. Returns -1 if it cannot send the message.

PARROT_API INTVAL PIO_connect(PARROT_INTERP, NOTNULL(PMC *pmc), NOTNULL(STRING *address))

Connects *pmc to *address. Returns -1 on failure.

PARROT_API INTVAL PIO_bind(PARROT_INTERP, NOTNULL(PMC *pmc), NOTNULL(STRING *address))

Binds *pmc's socket to the local address and port specified by *address. Returns -1 on failure.

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL PIO_listen(PARROT_INTERP, NOTNULL(PMC *pmc), INTVAL backlog)

Listens for new connections on socket *pmc. Returns -1 on failure.

PARROT_API PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL PMC *PIO_accept(PARROT_INTERP, NOTNULL(PMC *pmc))

Accepts a new connection and returns a newly created ParrotIO socket. Returns NULL on failure.

PARROT_API PARROT_WARN_UNUSED_RESULT INTVAL PIO_isatty(SHIM_INTERP, NOTNULL(PMC *pmc))

Returns a boolean value indicating whether *pmc is a console/tty.

SEE ALSO ^

io/io_buf.c, io/io_passdown.c, io/io_stdio.c, io/io_unix.c, io/io_win32.c, io/io_private.h.

HISTORY ^

Initially written by Melvin Smith.

Some ideas and goals from Perl 5.7 and Nick Ing-Simmons' work.

TODO ^

Rework to use copy-on-write IO stacks rather than creating a new stack for each IO stream.

Add support for loadable layers in Parrot bytecode.


parrot