Exemplo n.º 1
0
/* Seek to the specified position in the file. */
static void seek(MVMThreadContext *tc, MVMOSHandle *h, MVMint64 offset, MVMint64 whence) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    if (!data->seekable)
        MVM_exception_throw_adhoc(tc, "It is not possible to seek this kind of handle");
    flush_output_buffer(tc, data);
    if (MVM_platform_lseek(data->fd, offset, whence) == -1)
        MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno);
}
Exemplo n.º 2
0
/* Seek to the specified position in the file. */
static void seek(MVMThreadContext *tc, MVMOSHandle *h, MVMint64 offset, MVMint64 whence) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    MVMint64 r;

    if (data->ds) {
        /* We'll start over from a new position. */
        MVM_string_decodestream_destory(tc, data->ds);
        data->ds = NULL;
    }

    /* Seek, then get absolute position for new decodestream. */
    if (MVM_platform_lseek(data->fd, offset, whence) == -1)
        MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno);
    if ((r = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1)
        MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno);
    data->ds = MVM_string_decodestream_create(tc, data->encoding, r);
}
Exemplo n.º 3
0
/* Opens a file, returning a synchronous file handle. */
MVMObject * MVM_file_open_fh(MVMThreadContext *tc, MVMString *filename, MVMString *mode) {
    char * const fname = MVM_string_utf8_c8_encode_C_string(tc, filename);
    int fd;
    int flag;
    STAT statbuf;

    /* Resolve mode description to flags. */
    char * const fmode  = MVM_string_utf8_encode_C_string(tc, mode);
    if (!resolve_open_mode(&flag, fmode)) {
        char *waste[] = { fname, fmode, NULL };
        MVM_exception_throw_adhoc_free(tc, waste,
            "Invalid open mode for file %s: %s", fname, fmode);
    }
    MVM_free(fmode);

    /* Try to open the file. */
#ifdef _WIN32
    flag |= _O_BINARY;
#endif
    if ((fd = open((const char *)fname, flag, DEFAULT_MODE)) == -1) {
        char *waste[] = { fname, NULL };
        const char *err = strerror(errno);
        MVM_exception_throw_adhoc_free(tc, waste, "Failed to open file %s: %s", fname, err);
    }

    /*  Check that we didn't open a directory by accident.
        If fstat fails, just move on: Most of the documented error cases should
        already have triggered when opening the file, and we can't do anything
        about the others; a failure also does not necessarily imply that the
        file descriptor cannot be used for reading/writing. */
    if (fstat(fd, &statbuf) == 0 && (statbuf.st_mode & S_IFMT) == S_IFDIR) {
        char *waste[] = { fname, NULL };
        if (close(fd) == -1) {
            const char *err = strerror(errno);
            MVM_exception_throw_adhoc_free(tc, waste,
                "Tried to open directory %s, which we failed to close: %s",
                fname, err);
        }
        MVM_exception_throw_adhoc_free(tc, waste, "Tried to open directory %s", fname);
    }

    /* Set up handle. */
    MVM_free(fname);
    {
        MVMIOFileData * const data   = MVM_calloc(1, sizeof(MVMIOFileData));
        MVMOSHandle   * const result = (MVMOSHandle *)MVM_repr_alloc_init(tc,
            tc->instance->boot_types.BOOTIO);
        data->fd          = fd;
        data->seekable    = MVM_platform_lseek(fd, 0, SEEK_CUR) != -1;
        result->body.ops  = &op_table;
        result->body.data = data;
        return (MVMObject *)result;
    }
}
Exemplo n.º 4
0
/* Get curernt position in the file. */
static MVMint64 mvm_tell(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    MVMint64 r;

    if (data->ds)
        return MVM_string_decodestream_tell_bytes(tc, data->ds);

    if ((r = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1)
        MVM_exception_throw_adhoc(tc, "Failed to tell in filehandle: %d", errno);

    return r;
}
Exemplo n.º 5
0
/* Opens a file, returning a synchronous file handle. */
MVMObject * MVM_file_handle_from_fd(MVMThreadContext *tc, int fd) {
    MVMOSHandle   * const result = (MVMOSHandle *)MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTIO);
    MVMIOFileData * const data   = MVM_calloc(1, sizeof(MVMIOFileData));
    data->fd          = fd;
    data->seekable    = MVM_platform_lseek(fd, 0, SEEK_CUR) != -1;
    result->body.ops  = &op_table;
    result->body.data = data;
#ifdef _WIN32
    _setmode(fd, _O_BINARY);
#endif
    return (MVMObject *)result;
}
Exemplo n.º 6
0
/* Checks if the end of file has been reached. */
static MVMint64 mvm_eof(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    MVMint64 seek_pos;
    uv_fs_t  req;
    if (data->ds && !MVM_string_decodestream_is_empty(tc, data->ds))
        return 0;
    if (uv_fs_fstat(tc->loop, &req, data->fd, NULL) == -1) {
        MVM_exception_throw_adhoc(tc, "Failed to stat file descriptor: %s", uv_strerror(req.result));
    }
    if ((seek_pos = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1)
        MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno);
    return req.statbuf.st_size == seek_pos;
}
Exemplo n.º 7
0
/* Get current position in the file. */
static MVMint64 mvm_tell(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    flush_output_buffer(tc, data);
    if (data->seekable) {
        MVMint64 r;
        if ((r = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1)
            MVM_exception_throw_adhoc(tc, "Failed to tell in filehandle: %d", errno);
        return r;
    }
    else {
        return data->byte_position;
    }
}
Exemplo n.º 8
0
/* Checks if the end of file has been reached. */
static MVMint64 mvm_eof(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    MVMint64 seek_pos;
    uv_fs_t  req;
    if (data->ds && !MVM_string_decodestream_is_empty(tc, data->ds))
        return 0;
    if (uv_fs_fstat(tc->loop, &req, data->fd, NULL) == -1) {
        MVM_exception_throw_adhoc(tc, "Failed to stat file descriptor: %s", uv_strerror(req.result));
    }
    if ((seek_pos = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1)
        MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno);
    /* Comparison with seek_pos for some special files, like those in /proc,
     * which file size is 0 can be false. In that case, we fall back to check
     * file size to detect EOF. */
    return req.statbuf.st_size == seek_pos || req.statbuf.st_size == 0;
}
Exemplo n.º 9
0
/* Checks if the end of file has been reached. */
static MVMint64 mvm_eof(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOFileData *data = (MVMIOFileData *)h->body.data;
    if (data->seekable) {
        MVMint64 seek_pos;
        STAT statbuf;
        if (fstat(data->fd, &statbuf) == -1)
            MVM_exception_throw_adhoc(tc, "Failed to stat file descriptor: %s",
                strerror(errno));
        if ((seek_pos = MVM_platform_lseek(data->fd, 0, SEEK_CUR)) == -1)
            MVM_exception_throw_adhoc(tc, "Failed to seek in filehandle: %d", errno);
        /* Comparison with seek_pos for some special files, like those in /proc,
         * which file size is 0 can be false. In that case, we fall back to check
         * file size to detect EOF. */
        return statbuf.st_size == seek_pos || statbuf.st_size == 0;
    }
    else {
        return data->eof_reported;
    }
}