src/io/io_unix.c - UNIX IO layer


This is the Parrot UNIX IO layer. It implements unbuffered, low-level, UNIX-specific functionality.

As "UNIX" is already a generalization, it may be necessary to create separate OS-specific layers for UNIX flavors, to avoid over-complicating this file.

References: ^

APitUE - W. Richard Stevens, AT&T SFIO, Perl5 (Nick Ing-Simmons)

Functions ^

PARROT_CONST_FUNCTION static INTVAL flags_to_unix(INTVAL flags)

Returns a UNIX-specific interpretation of flags suitable for passing to open() and fopen() in PIO_unix_open() and PIO_unix_fdopen() respectively.

static INTVAL PIO_unix_init(PARROT_INTERP, NOTNULL(ParrotIOLayer *layer))

Sets up the interpreter's standard std* IO handles. Returns 0 on success and -1 on error.

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL static ParrotIO *PIO_unix_open(PARROT_INTERP, NOTNULL(ParrotIOLayer *layer), ARGIN(const char *spath), INTVAL flags)

Opens *spath. flags is a bitwise or combination of PIO_F_* values.

INTVAL PIO_unix_async(PARROT_INTERP, NOTNULL(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), INTVAL b)

Experimental asynchronous IO.

This is available if PARROT_ASYNC_DEVEL is defined.

Only works on Linux at the moment.

Toggles the O_ASYNC flag on the IO file descriptor.


Returns a new ParrotIO with file descriptor fd.

static INTVAL PIO_unix_close(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io))

Closes *io's file descriptor.

static INTVAL PIO_unix_isatty(PIOHANDLE fd)

Returns a boolean value indicating whether fd is a console/tty.

INTVAL PIO_unix_getblksize(PIOHANDLE fd)

Various ways of determining block size.

If passed a file descriptor then fstat() and the stat buffer are used if available.

If called without an argument then the BLKSIZE constant is returned if it was available at compile time, otherwise PIO_BLKSIZE is returned.

static INTVAL PIO_unix_flush(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io))

At lowest layer all we can do for flush is to ask the kernel to sync().

XXX: Is it necessary to sync() here?

static size_t PIO_unix_read(PARROT_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), NOTNULL(STRING **buf))

Calls read() to return up to len bytes in the memory starting at buffer.

static size_t PIO_unix_write(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), NOTNULL(STRING *s))

Calls write() to write len bytes from the memory starting at buffer to the file descriptor in *io.

static PIOOFF_T PIO_unix_seek(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), PIOOFF_T offset, INTVAL whence)

Hard seek.

Calls lseek() to advance the read/write position on *io's file descriptor to offset bytes from the location indicated by whence.

static PIOOFF_T PIO_unix_tell(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io))

Returns the current read/write position on *io's file discriptor.

Networking ^

Define PARROT_NET_DEVEL to enable networking.

These could be native extensions but they probably should be here if we wish to make them integrated with the async IO system.

Very minimal stubs for now, maybe someone will run with these.


PIO_sockaddr_in() is not part of the layer and so must be extern.

XXX: We can probably just write our own routines (htons(), inet_aton(), etc.) and take this out of platform specific compilation

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL static ParrotIO *PIO_unix_socket(PARROT_INTERP, SHIM(ParrotIOLayer *layer), int fam, int type, int proto)

Uses socket() to create a socket with the specified address family, socket type and protocol number.

static INTVAL PIO_unix_connect(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), NULLOK(STRING *r))

Connects *io's socket to address *r.

static INTVAL PIO_unix_bind(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), NOTNULL(STRING *l))

Binds *io's socket to the local address and port specified by *l.

static INTVAL PIO_unix_listen(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), INTVAL sec)

Listen for new connections. This is only applicable to STREAM or SEQ sockets.


Accept a new connection and return a newly created ParrotIO socket.

static INTVAL PIO_unix_send(SHIM_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), NOTNULL(STRING *s))

Send the message *s to *io's connected socket.

static INTVAL PIO_unix_recv(PARROT_INTERP, SHIM(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), NOTNULL(STRING **s))

Receives a message in **s from *io's connected socket.

static INTVAL PIO_unix_poll(SHIM_INTERP, SHIM(ParrotIOLayer *l), NOTNULL(ParrotIO *io), int which, int sec, int usec)

Utility function for polling a single IO stream with a timeout.

Returns a 1 | 2 | 4 (read, write, error) value.

This is not equivalent to any speficic POSIX or BSD socket call, however it is a useful, common primitive.

Not at all usefule --leo.

Also, a buffering layer above this may choose to reimpliment by checking the read buffer.

PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL static ParrotIO *PIO_unix_pipe(PARROT_INTERP, SHIM(ParrotIOLayer *l), ARGIN(const char *cmd), int flags)

Very limited exec for now.

XXX: Where does this fit, should it belong in the ParrotIOLayerAPI?


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


Initially written by Melvin Smith (