parrotcode: IO Layer for mmaped files | |
Contents | C |
src/io/io_mmap.c - IO Layer for mmaped files
Open mmaps the file.
*/
#include "parrot/parrot.h" #include "io_private.h"
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
static INTVAL PIO_mmap_close( PARROT_INTERP, NOTNULL(ParrotIOLayer *layer), NOTNULL(ParrotIO *io) ) __attribute__nonnull__(1) __attribute__nonnull__(2) __attribute__nonnull__(3);
PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL static ParrotIO * PIO_mmap_open( PARROT_INTERP, NOTNULL(ParrotIOLayer *layer), NOTNULL(const char *path), INTVAL flags ) __attribute__nonnull__(1) __attribute__nonnull__(2) __attribute__nonnull__(3);
static size_t PIO_mmap_read( PARROT_INTERP, NOTNULL(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), NOTNULL(STRING **buf) ) __attribute__nonnull__(1) __attribute__nonnull__(2) __attribute__nonnull__(3) __attribute__nonnull__(4);
/* HEADERIZER END: static */
static const ParrotIOLayerAPI pio_mmap_layer_api = { PIO_null_init, PIO_base_new_layer, PIO_base_delete_layer, PIO_null_push_layer, PIO_null_pop_layer, PIO_mmap_open, PIO_null_open2, PIO_null_open3, PIO_null_open_async, PIO_null_fdopen, PIO_mmap_close, PIO_null_write, PIO_null_write_async, PIO_mmap_read, PIO_null_read_async, PIO_null_flush, PIO_null_peek, PIO_null_seek, PIO_null_tell, PIO_null_setbuf, PIO_null_setlinebuf, PIO_null_getcount, PIO_null_fill, PIO_null_eof, NULL, /* no poll */ NULL, /* no socket */ NULL, /* no connect */ NULL, /* no send */ NULL, /* no recv */ NULL, /* no bind */ NULL, /* no listen */ NULL /* no accept */ };
ParrotIOLayer pio_mmap_layer = { NULL, "mmap", 0, &pio_mmap_layer_api, NULL, NULL };
PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL ParrotIOLayer * PIO_mmap_register_layer(void) { return &pio_mmap_layer; }
/*
FUNCDOC: PIO_mmap_open
The buffer layer's Open
function.
*/
PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL static ParrotIO * PIO_mmap_open(PARROT_INTERP, NOTNULL(ParrotIOLayer *layer), NOTNULL(const char *path), INTVAL flags) { ParrotIO *io; ParrotIOLayer *l = PIO_DOWNLAYER(layer);
if (!l) {
l = interp->piodata->default_stack;
if (strcmp(l->name, "buf") == 0)
l = PIO_DOWNLAYER(l);
}
io = PIO_open_down(interp, l, path, flags);
if (!io) {
/* error creating IO stream */
return NULL;
}
#ifdef PARROT_HAS_HEADER_SYSMMAN
{
/* XXX assume fstat exists too
*/
struct stat statbuf;
int status;
PIOOFF_T file_size;
status = fstat(io->fd, &statbuf); /* XXX We're ignoring this return value. */
file_size = statbuf.st_size;
/* TODO verify flags */
io->b.startb = (unsigned char *)mmap(0, file_size, PROT_READ, MAP_SHARED, io->fd, 0);
io->b.size = (size_t)file_size; /* XXX */
io->b.endb = io->b.startb + io->b.size;
io->b.flags |= PIO_BF_MMAP;
}
#endif
return io;
}
/*
FUNCDOC: PIO_mmap_read
Calls read()
to return up to len
bytes in the memory starting at buffer
.
*/
static size_t PIO_mmap_read(PARROT_INTERP, NOTNULL(ParrotIOLayer *layer), NOTNULL(ParrotIO *io), NOTNULL(STRING **buf)) { STRING *s; UINTVAL len;
if (!(io->b.flags & PIO_BF_MMAP))
return PIO_read_down(interp, PIO_DOWNLAYER(layer), io, buf);
if (*buf == NULL) {
*buf = new_string_header(interp, 0);
}
s = *buf;
/* TODO create string_free API for reusing string headers */
if (s->strstart && PObj_sysmem_TEST(s))
mem_sys_free(PObj_bufstart(s));
PObj_get_FLAGS(s) |= PObj_external_FLAG;
PObj_bufstart(s) = io->b.startb + io->fpos;
s->strstart = (char *) io->b.startb + io->fpos;
len = s->bufused ? s->bufused : io->b.size;
io->fpos += len;
PObj_buflen(s) = s->strlen = len;
return len;
}
/*
FUNCDOC: PIO_mmap_close
Closes *io
's file descriptor.
*/
static INTVAL PIO_mmap_close(PARROT_INTERP, NOTNULL(ParrotIOLayer *layer), NOTNULL(ParrotIO *io)) { INTVAL ret = -1;
if (io->fd >= 0)
ret = PIO_close_down(interp, PIO_DOWNLAYER(layer), io);
return ret;
}
/*
src/io/io_passdown.c, src/io/io.c, src/io/io_layers.c, src/io/io_private.h.
Initially written by Leo.
*/
/* * Local variables: * c-file-style: "parrot" * End: * vim: expandtab shiftwidth=4: */
|