コード例 #1
0
ファイル: syncfile.c プロジェクト: hoelzro/MoarVM
/* 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_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;
    result->body.ops  = &op_table;
    result->body.data = data;

    return (MVMObject *)result;
}
コード例 #2
0
ファイル: syncfile.c プロジェクト: chipdude/MoarVM
/* 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;
    }
}
コード例 #3
0
ファイル: syncsocket.c プロジェクト: usev6/MoarVM
/* This function may return any type of sockaddr e.g. sockaddr_un, sockaddr_in or sockaddr_in6
 * It shouldn't be a problem with general code as long as the port number is kept below the int16 limit: 65536
 * After this it defines the family which may spawn non internet sockaddr's
 * The family can be extracted by (port >> 16) & USHORT_MAX
 *
 * Currently supported families:
 *
 * AF_UNSPEC = 1
 *   Unspecified, in most cases should be equal to AF_INET or AF_INET6
 *
 * AF_UNIX = 1
 *   Unix domain socket, will spawn a sockaddr_un which will use the given host as path
 *   e.g: MVM_io_resolve_host_name(tc, "/run/moarvm.sock", 1 << 16)
 *   will spawn an unix domain socket on /run/moarvm.sock
 *
 * AF_INET = 2
 *   IPv4 socket
 *
 * AF_INET6 = 10
 *   IPv6 socket
 */
struct sockaddr * MVM_io_resolve_host_name(MVMThreadContext *tc, MVMString *host, MVMint64 port) {
    char *host_cstr = MVM_string_utf8_encode_C_string(tc, host);
    struct sockaddr *dest;
    int error;
    struct addrinfo *result;
    char port_cstr[8];
    unsigned short family = (port >> 16) & USHRT_MAX;
    struct addrinfo hints;

#ifndef _WIN32
    /* AF_UNIX = 1 */
    if (family == AF_UNIX) {
        struct sockaddr_un *result_un = MVM_malloc(sizeof(struct sockaddr_un));

        if (strlen(host_cstr) > 107) {
            MVM_free(result_un);
            MVM_free(host_cstr);
            MVM_exception_throw_adhoc(tc, "Socket path can only be maximal 107 characters long");
        }

        result_un->sun_family = AF_UNIX;
        strcpy(result_un->sun_path, host_cstr);
        MVM_free(host_cstr);

        return (struct sockaddr *)result_un;
    }
#endif

    hints.ai_family = family;
    hints.ai_socktype = 0;
    hints.ai_flags = AI_PASSIVE;
    hints.ai_protocol = 0;
    hints.ai_addrlen = 0;
    hints.ai_addr = NULL;
    hints.ai_canonname = NULL;
    hints.ai_next = NULL;

    snprintf(port_cstr, 8, "%d", (int)port);

    MVM_gc_mark_thread_blocked(tc);
    error = getaddrinfo(host_cstr, port_cstr, &hints, &result);
    MVM_gc_mark_thread_unblocked(tc);
    if (error == 0) {
        size_t size = get_struct_size_for_family(result->ai_addr->sa_family);
        MVM_free(host_cstr);
        dest = MVM_malloc(size);
        memcpy(dest, result->ai_addr, size);
    }
    else {
        char *waste[] = { host_cstr, NULL };
        MVM_exception_throw_adhoc_free(tc, waste, "Failed to resolve host name '%s' with family %d. Error: '%s'",
                                       host_cstr, family, gai_strerror(error));
    }
    freeaddrinfo(result);

    return dest;
}
コード例 #4
0
ファイル: reprs.c プロジェクト: MasterDuke17/MoarVM
static MVMReprRegistry * find_repr_by_name(MVMThreadContext *tc,
        MVMString *name) {
    MVMReprRegistry *entry;

    MVM_HASH_GET(tc, tc->instance->repr_hash, name, entry)

    if (entry == NULL) {
        char *c_name = MVM_string_ascii_encode_any(tc, name);
        char *waste[] = { c_name, NULL };
        MVM_exception_throw_adhoc_free(tc, waste, "Lookup by name of unknown REPR: %s",
            c_name);
    }

    return entry;
}
コード例 #5
0
ファイル: nativecall_dyncall.c プロジェクト: hoelzro/MoarVM
/* Maps a calling convention name to an ID. */
MVMint16 MVM_nativecall_get_calling_convention(MVMThreadContext *tc, MVMString *name) {
    MVMint16 result = DC_CALL_C_DEFAULT;
    if (name && MVM_string_graphs(tc, name) > 0) {
        char *cname = MVM_string_utf8_encode_C_string(tc, name);
        if (strcmp(cname, "cdecl") == 0)
            result = DC_CALL_C_X86_CDECL;
        else if (strcmp(cname, "stdcall") == 0)
            result = DC_CALL_C_X86_WIN32_STD;
        else if (strcmp(cname, "stdcall") == 0)
            result = DC_CALL_C_X64_WIN64;
        else {
            char *waste[] = { cname, NULL };
            MVM_exception_throw_adhoc_free(tc, waste,
                "Unknown calling convention '%s' used for native call", cname);
        }
        MVM_free(cname);
    }
    return result;
}
コード例 #6
0
ファイル: syncfile.c プロジェクト: zostay/MoarVM
/* 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;
    }
}
コード例 #7
0
ファイル: parse_num.c プロジェクト: MasterDuke17/MoarVM
MVM_NO_RETURN static void parse_error(MVMThreadContext *tc, MVMString *s, const char* reason) {
    char* got = MVM_string_utf8_c8_encode_C_string(tc, s);
    char *waste[] = { got, NULL };
    MVM_exception_throw_adhoc_free(tc, waste, "Can't convert '%s' to num: %s", got, reason);
}