Пример #1
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);
    char          * const fmode  = MVM_string_utf8_encode_C_string(tc, mode);
    MVMOSHandle   * const result = (MVMOSHandle *)MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTIO);
    MVMIOFileData * const data   = MVM_calloc(1, sizeof(MVMIOFileData));
    uv_fs_t req;
    uv_file fd;

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

    /* Try to open the file. */
    if ((fd = uv_fs_open(tc->loop, &req, (const char *)fname, flag, DEFAULT_MODE, NULL)) < 0) {
        char *waste[] = { fname, NULL };
        MVM_exception_throw_adhoc_free(tc, waste, "Failed to open file %s: %s", fname, uv_strerror(req.result));
    }

    /* Set up handle. */
    data->fd          = fd;
    data->filename    = fname;
    data->encoding    = MVM_encoding_type_utf8;
    MVM_string_decode_stream_sep_default(tc, &(data->sep_spec));
    result->body.ops  = &op_table;
    result->body.data = data;

    return (MVMObject *)result;
}
Пример #2
0
MVMObject * MVM_io_socket_create(MVMThreadContext *tc, MVMint64 listen) {
    MVMOSHandle         * const result = (MVMOSHandle *)MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTIO);
    MVMIOSyncSocketData * const data   = MVM_calloc(1, sizeof(MVMIOSyncSocketData));
    data->ss.handle   = NULL;
    data->ss.encoding = MVM_encoding_type_utf8;
    MVM_string_decode_stream_sep_default(tc, &(data->ss.sep_spec));
    result->body.ops  = &op_table;
    result->body.data = data;
    return (MVMObject *)result;
}
Пример #3
0
/* Creates a sync pipe handle. */
MVMObject * MVM_io_syncpipe(MVMThreadContext *tc) {
    MVMOSHandle       * const result = (MVMOSHandle *)MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTIO);
    MVMIOSyncPipeData * const data   = MVM_calloc(1, sizeof(MVMIOSyncPipeData));
    uv_pipe_t *handle = MVM_malloc(sizeof(uv_pipe_t));
    uv_pipe_init(tc->loop, handle, 0);
    data->ss.handle   = (uv_stream_t *)handle;
    data->ss.encoding = MVM_encoding_type_utf8;
    MVM_string_decode_stream_sep_default(tc, &(data->ss.sep_spec));
    result->body.ops  = &op_table;
    result->body.data = data;
    return (MVMObject *)result;
}
Пример #4
0
static MVMObject * socket_accept(MVMThreadContext *tc, MVMOSHandle *h) {
    MVMIOSyncSocketData *data = (MVMIOSyncSocketData *)h->body.data;

    while (!data->accept_server) {
        if (tc->loop != data->ss.handle->loop) {
            MVM_exception_throw_adhoc(tc, "Tried to accept() on a socket from outside its originating thread");
        }
        uv_ref((uv_handle_t *)data->ss.handle);
        MVM_gc_mark_thread_blocked(tc);
        uv_run(tc->loop, UV_RUN_DEFAULT);
        MVM_gc_mark_thread_unblocked(tc);
    }

    /* Check the accept worked out. */
    if (data->accept_status < 0) {
        MVM_exception_throw_adhoc(tc, "Failed to listen: unknown error");
    }
    else {
        uv_tcp_t *client    = MVM_malloc(sizeof(uv_tcp_t));
        uv_stream_t *server = data->accept_server;
        int r;
        uv_tcp_init(tc->loop, client);
        data->accept_server = NULL;
        if ((r = uv_accept(server, (uv_stream_t *)client)) == 0) {
            MVMOSHandle         * const result = (MVMOSHandle *)MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTIO);
            MVMIOSyncSocketData * const data   = MVM_calloc(1, sizeof(MVMIOSyncSocketData));
            data->ss.handle   = (uv_stream_t *)client;
            data->ss.encoding = MVM_encoding_type_utf8;
            MVM_string_decode_stream_sep_default(tc, &(data->ss.sep_spec));
            result->body.ops  = &op_table;
            result->body.data = data;
            return (MVMObject *)result;
        }
        else {
            uv_close((uv_handle_t*)client, NULL);
            MVM_free(client);
            MVM_exception_throw_adhoc(tc, "Failed to accept: %s", uv_strerror(r));
        }
    }
}
Пример #5
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);
    uv_fs_t req;
    uv_file fd;
    int flag;

    /* 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. */
    if ((fd = uv_fs_open(tc->loop, &req, (const char *)fname, flag, DEFAULT_MODE, NULL)) < 0) {
        char *waste[] = { fname, NULL };
        const char *err = uv_strerror(req.result);

        uv_fs_req_cleanup(&req);
        MVM_exception_throw_adhoc_free(tc, waste, "Failed to open file %s: %s", fname, err);
    }
    uv_fs_req_cleanup(&req);

    /*  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 (uv_fs_fstat(tc->loop, &req, fd, NULL) == 0 && (req.statbuf.st_mode & S_IFMT) == S_IFDIR) {
        char *waste[] = { fname, NULL };

        uv_fs_req_cleanup(&req);

        if (uv_fs_close(tc->loop, &req, fd, NULL) < 0) {
            const char *err = uv_strerror(req.result);

            uv_fs_req_cleanup(&req);
            MVM_exception_throw_adhoc_free(tc, waste, "Tried to open directory %s, which we failed to close: %s",
                fname, err);
        }
        uv_fs_req_cleanup(&req);

        MVM_exception_throw_adhoc_free(tc, waste, "Tried to open directory %s", fname);
    }
    uv_fs_req_cleanup(&req);

    /* Set up handle. */
    {
        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->filename    = fname;
        data->encoding    = MVM_encoding_type_utf8;
        MVM_string_decode_stream_sep_default(tc, &(data->sep_spec));
        result->body.ops  = &op_table;
        result->body.data = data;

        return (MVMObject *)result;
    }
}