Ejemplo n.º 1
0
MVMint64 MVM_proc_shell(MVMThreadContext *tc, MVMString *cmd, MVMString *cwd, MVMObject *env) {
    MVMint64 result = 0, spawn_result = 0;
    uv_process_t *process = calloc(1, sizeof(uv_process_t));
    uv_process_options_t process_options = {0};
    uv_stdio_container_t process_stdio[3];
    int i;

    char * const cmdin = MVM_string_utf8_encode_C_string(tc, cmd);
    char * const _cwd = MVM_string_utf8_encode_C_string(tc, cwd);
    const MVMuint64 size = MVM_repr_elems(tc, env);
    MVMIter * const iter = (MVMIter *)MVM_iter(tc, env);
    char **_env = malloc((size + 1) * sizeof(char *));

#ifdef _WIN32
    const MVMuint16 acp = GetACP(); /* We should get ACP at runtime. */
    char * const _cmd = ANSIToUTF8(acp, getenv("ComSpec"));
    char *args[3];
    args[0] = "/c";
    {
        MVMint64 len = strlen(cmdin);
        MVMint64 i;
        for (i = 0; i < len; i++)
            if (cmdin[i] == '/')
                cmdin[i] = '\\';
    }
    args[1] = cmdin;
    args[2] = NULL;
#else
    char * const _cmd = "/bin/sh";
    char *args[4];
    args[0] = "/bin/sh";
    args[1] = "-c";
    args[2] = cmdin;
    args[3] = NULL;
#endif

    INIT_ENV();
    SPAWN(_cmd);
    FREE_ENV();

    free(_cwd);

#ifdef _WIN32
    free(_cmd);
#endif

    free(cmdin);
    return result;
}
Ejemplo n.º 2
0
MVMint64 MVM_proc_spawn(MVMThreadContext *tc, MVMString *cmd, MVMString *cwd, MVMObject *env) {
    MVMint64 result, spawn_result;
    uv_process_t process = {0};
    uv_process_options_t process_options = {0};
    int i;

    char   * const     cmdin = MVM_string_utf8_encode_C_string(tc, cmd);
    char   * const      _cwd = MVM_string_utf8_encode_C_string(tc, cwd);
    const MVMuint64     size = MVM_repr_elems(tc, env);
    MVMIter * const     iter = (MVMIter *)MVM_iter(tc, env);
    char              **_env = malloc((size + 1) * sizeof(char *));

#ifdef _WIN32
    const MVMuint16      acp = GetACP(); /* We should get ACP at runtime. */
    char    * const     _cmd = ANSIToUTF8(acp, getenv("ComSpec"));
    char   *args[3];
    args[0] = "/c";
    args[1] = cmdin;
    args[2] = NULL;
#else
    char * const _cmd = "/bin/sh";
    char   *args[4];
    args[0] = "/bin/sh";
    args[1] = "-c";
    args[2] = cmdin;
    args[3] = NULL;
#endif

    MVMROOT(tc, iter, {
        MVMString * const equal = MVM_string_ascii_decode(tc, tc->instance->VMString, STR_WITH_LEN("="));
        MVMROOT(tc, equal, {
            MVMString *env_str;
            i = 0;
            while(MVM_iter_istrue(tc, iter)) {
                MVM_repr_shift_o(tc, (MVMObject *)iter);
                env_str = MVM_string_concatenate(tc, MVM_iterkey_s(tc, iter), equal);
                env_str = MVM_string_concatenate(tc, env_str, MVM_repr_get_str(tc, MVM_iterval(tc, iter)));
                _env[i++] = MVM_string_utf8_encode_C_string(tc, env_str);
            }
            _env[size] = NULL;
        });
    });
Ejemplo n.º 3
0
MVMint64 MVM_proc_shell(MVMThreadContext *tc, MVMString *cmd, MVMString *cwd, MVMObject *env,
        MVMObject *in, MVMObject *out, MVMObject *err, MVMint64 flags) {
    MVMint64 result = 0, spawn_result;
    uv_process_t *process = MVM_calloc(1, sizeof(uv_process_t));
    uv_process_options_t process_options = {0};
    uv_stdio_container_t process_stdio[3];
    int i, process_still_running;

    char * const cmdin = MVM_string_utf8_c8_encode_C_string(tc, cmd);
    char * const _cwd = MVM_string_utf8_c8_encode_C_string(tc, cwd);
    const MVMuint64 size = MVM_repr_elems(tc, env);
    char **_env = MVM_malloc((size + 1) * sizeof(char *));
    MVMIter *iter;

#ifdef _WIN32
    const MVMuint16 acp = GetACP(); /* We should get ACP at runtime. */
    char * const _cmd = ANSIToUTF8(acp, getenv("ComSpec"));
    char *args[3];
    args[0] = "/c";
    args[1] = cmdin;
    args[2] = NULL;
#else
    char * const _cmd = "/bin/sh";
    char *args[4];
    args[0] = "/bin/sh";
    args[1] = "-c";
    args[2] = cmdin;
    args[3] = NULL;
#endif

    MVMROOT(tc, in, {
    MVMROOT(tc, out, {
    MVMROOT(tc, err, {
        iter = (MVMIter *)MVM_iter(tc, env);
        INIT_ENV();
    });
    });
Ejemplo n.º 4
0
MVMint64 MVM_proc_spawn(MVMThreadContext *tc, MVMObject *argv, MVMString *cwd, MVMObject *env) {
    MVMint64 result = 0, spawn_result = 0;
    uv_process_t *process = calloc(1, sizeof(uv_process_t));
    uv_process_options_t process_options = {0};
    uv_stdio_container_t process_stdio[3];
    int i;

    char   * const      _cwd = MVM_string_utf8_encode_C_string(tc, cwd);
    const MVMuint64     size = MVM_repr_elems(tc, env);
    MVMIter * const     iter = (MVMIter *)MVM_iter(tc, env);
    char              **_env = malloc((size + 1) * sizeof(char *));
    const MVMuint64  arg_size = MVM_repr_elems(tc, argv);
    char             **args = malloc((arg_size + 1) * sizeof(char *));
    MVMRegister        reg;

    i = 0;
    while(i < arg_size) {
        REPR(argv)->pos_funcs.at_pos(tc, STABLE(argv), argv, OBJECT_BODY(argv), i, &reg, MVM_reg_obj);
        args[i++] = MVM_string_utf8_encode_C_string(tc, MVM_repr_get_str(tc, reg.o));
    }
    args[arg_size] = NULL;

    INIT_ENV();
    SPAWN(arg_size ? args[0] : NULL);
    FREE_ENV();

    free(_cwd);

    i = 0;
    while(args[i])
        free(args[i++]);

    free(args);

    return result;
}
Ejemplo n.º 5
0
/* Locates all of the attributes. Puts them onto a flattened, ordered
 * list of attributes (populating the passed flat_list). Also builds
 * the index mapping for doing named lookups. Note index is not related
 * to the storage position. */
static MVMObject * index_mapping_and_flat_list(MVMThreadContext *tc, MVMObject *mro, MVMCPPStructREPRData *repr_data) {
    MVMInstance *instance  = tc->instance;
    MVMObject *flat_list, *class_list, *attr_map_list;
    MVMint32  num_classes, i, current_slot = 0;
    MVMCPPStructNameMap *result;

    MVMint32 mro_idx = MVM_repr_elems(tc, mro);

    MVM_gc_root_temp_push(tc, (MVMCollectable **)&mro);

    flat_list = MVM_repr_alloc_init(tc, MVM_hll_current(tc)->slurpy_array_type);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&flat_list);

    class_list = MVM_repr_alloc_init(tc, MVM_hll_current(tc)->slurpy_array_type);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&class_list);

    attr_map_list = MVM_repr_alloc_init(tc, MVM_hll_current(tc)->slurpy_array_type);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&attr_map_list);

    /* Walk through the parents list. */
    while (mro_idx)
    {
        /* Get current class in MRO. */
        MVMObject *type_info     = MVM_repr_at_pos_o(tc, mro, --mro_idx);
        MVMObject *current_class = MVM_repr_at_pos_o(tc, type_info, 0);

        /* Get its local parents; make sure we're not doing MI. */
        MVMObject *parents     = MVM_repr_at_pos_o(tc, type_info, 2);
        MVMint32  num_parents = MVM_repr_elems(tc, parents);
        if (num_parents <= 1) {
            /* Get attributes and iterate over them. */
            MVMObject *attributes     = MVM_repr_at_pos_o(tc, type_info, 1);
            MVMIter * const attr_iter = (MVMIter *)MVM_iter(tc, attributes);
            MVMObject *attr_map = NULL;

            if (MVM_iter_istrue(tc, attr_iter)) {
                MVM_gc_root_temp_push(tc, (MVMCollectable **)&attr_iter);
                attr_map = MVM_repr_alloc_init(tc, MVM_hll_current(tc)->slurpy_hash_type);
                MVM_gc_root_temp_push(tc, (MVMCollectable **)&attr_map);
            }

            while (MVM_iter_istrue(tc, attr_iter)) {
                MVMObject *current_slot_obj = MVM_repr_box_int(tc, MVM_hll_current(tc)->int_box_type, current_slot);
                MVMObject *attr, *name_obj;
                MVMString *name;

                MVM_repr_shift_o(tc, (MVMObject *)attr_iter);

                /* Get attribute. */
                attr = MVM_iterval(tc, attr_iter);

                /* Get its name. */
                name_obj = MVM_repr_at_key_o(tc, attr, instance->str_consts.name);
                name     = MVM_repr_get_str(tc, name_obj);

                MVM_repr_bind_key_o(tc, attr_map, name, current_slot_obj);

                current_slot++;

                /* Push attr onto the flat list. */
                MVM_repr_push_o(tc, flat_list, attr);
            }

            if (attr_map) {
                MVM_gc_root_temp_pop_n(tc, 2);
            }

            /* Add to class list and map list. */
            MVM_repr_push_o(tc, class_list, current_class);
            MVM_repr_push_o(tc, attr_map_list, attr_map);
        }
        else {
            MVM_exception_throw_adhoc(tc,
                "CPPStruct representation does not support multiple inheritance");
        }
    }

    MVM_gc_root_temp_pop_n(tc, 4);

    /* We can now form the name map. */
    num_classes = MVM_repr_elems(tc, class_list);
    result = (MVMCPPStructNameMap *) MVM_malloc(sizeof(MVMCPPStructNameMap) * (1 + num_classes));

    for (i = 0; i < num_classes; i++) {
        result[i].class_key = MVM_repr_at_pos_o(tc, class_list, i);
        result[i].name_map  = MVM_repr_at_pos_o(tc, attr_map_list, i);
    }

    /* set the end to be NULL, it's useful for iteration. */
    result[i].class_key = NULL;

    repr_data->name_to_index_mapping = result;

    return flat_list;
}
Ejemplo n.º 6
0
MVMint64 MVM_proc_spawn(MVMThreadContext *tc, MVMObject *argv, MVMString *cwd, MVMObject *env,
        MVMObject *in, MVMObject *out, MVMObject *err, MVMint64 flags) {
    MVMint64 result = 0, spawn_result;
    uv_process_t *process = MVM_calloc(1, sizeof(uv_process_t));
    uv_process_options_t process_options = {0};
    uv_stdio_container_t process_stdio[3];
    int i;

    char   * const      _cwd = MVM_string_utf8_c8_encode_C_string(tc, cwd);
    const MVMuint64     size = MVM_repr_elems(tc, env);
    MVMIter * const     iter = (MVMIter *)MVM_iter(tc, env);
    char              **_env = MVM_malloc((size + 1) * sizeof(char *));
    const MVMuint64  arg_size = MVM_repr_elems(tc, argv);
    char             **args = MVM_malloc((arg_size + 1) * sizeof(char *));
    MVMRegister        reg;

    i = 0;
    while(i < arg_size) {
        REPR(argv)->pos_funcs.at_pos(tc, STABLE(argv), argv, OBJECT_BODY(argv), i, &reg, MVM_reg_obj);
        args[i++] = MVM_string_utf8_c8_encode_C_string(tc, MVM_repr_get_str(tc, reg.o));
    }
    args[arg_size] = NULL;

    INIT_ENV();
    setup_process_stdio(tc, in,  process, &process_stdio[0], 0, flags,      "spawn");
    setup_process_stdio(tc, out, process, &process_stdio[1], 1, flags >> 3, "spawn");
    setup_process_stdio(tc, err, process, &process_stdio[2], 2, flags >> 6, "spawn");

    process_options.stdio       = process_stdio;
    process_options.file        = arg_size ? args[0] : NULL;
    process_options.args        = args;
    process_options.cwd         = _cwd;
    process_options.flags       = UV_PROCESS_WINDOWS_HIDE;
    process_options.env         = _env;
    process_options.stdio_count = 3;
    process_options.exit_cb     = spawn_on_exit;
    if (flags & (MVM_PIPE_CAPTURE_IN | MVM_PIPE_CAPTURE_OUT | MVM_PIPE_CAPTURE_ERR)) {
        process->data = MVM_calloc(1, sizeof(MVMint64));
        uv_ref((uv_handle_t *)process);
        spawn_result = uv_spawn(tc->loop, process, &process_options);
        if (spawn_result)
            result = spawn_result;
    }
    else {
        process->data = &result;
        uv_ref((uv_handle_t *)process);
        spawn_result = uv_spawn(tc->loop, process, &process_options);
        if (spawn_result)
            result = spawn_result;
        else
            uv_run(tc->loop, UV_RUN_DEFAULT);
    }

    FREE_ENV();
    MVM_free(_cwd);
    uv_unref((uv_handle_t *)process);

    i = 0;
    while(args[i])
        MVM_free(args[i++]);

    MVM_free(args);

    return result;
}
Ejemplo n.º 7
0
MVMint64 MVM_proc_shell(MVMThreadContext *tc, MVMString *cmd, MVMString *cwd, MVMObject *env,
        MVMObject *in, MVMObject *out, MVMObject *err, MVMint64 flags) {
    MVMint64 result = 0, spawn_result;
    uv_process_t *process = MVM_calloc(1, sizeof(uv_process_t));
    uv_process_options_t process_options = {0};
    uv_stdio_container_t process_stdio[3];
    int i;

    char * const cmdin = MVM_string_utf8_c8_encode_C_string(tc, cmd);
    char * const _cwd = MVM_string_utf8_c8_encode_C_string(tc, cwd);
    const MVMuint64 size = MVM_repr_elems(tc, env);
    MVMIter * const iter = (MVMIter *)MVM_iter(tc, env);
    char **_env = MVM_malloc((size + 1) * sizeof(char *));

#ifdef _WIN32
    const MVMuint16 acp = GetACP(); /* We should get ACP at runtime. */
    char * const _cmd = ANSIToUTF8(acp, getenv("ComSpec"));
    char *args[3];
    args[0] = "/c";
    args[1] = cmdin;
    args[2] = NULL;
#else
    char * const _cmd = "/bin/sh";
    char *args[4];
    args[0] = "/bin/sh";
    args[1] = "-c";
    args[2] = cmdin;
    args[3] = NULL;
#endif

    INIT_ENV();
    setup_process_stdio(tc, in,  process, &process_stdio[0], 0, flags,      "shell");
    setup_process_stdio(tc, out, process, &process_stdio[1], 1, flags >> 3, "shell");
    setup_process_stdio(tc, err, process, &process_stdio[2], 2, flags >> 6, "shell");

    process_options.stdio       = process_stdio;
    process_options.file        = _cmd;
    process_options.args        = args;
    process_options.cwd         = _cwd;
    process_options.flags       = UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS | UV_PROCESS_WINDOWS_HIDE;
    process_options.env         = _env;
    process_options.stdio_count = 3;
    process_options.exit_cb     = spawn_on_exit;
    if (flags & (MVM_PIPE_CAPTURE_IN | MVM_PIPE_CAPTURE_OUT | MVM_PIPE_CAPTURE_ERR)) {
        process->data = MVM_calloc(1, sizeof(MVMint64));
        uv_ref((uv_handle_t *)process);
        spawn_result = uv_spawn(tc->loop, process, &process_options);
        if (spawn_result)
            result = spawn_result;
    }
    else {
        process->data = &result;
        uv_ref((uv_handle_t *)process);
        spawn_result = uv_spawn(tc->loop, process, &process_options);
        if (spawn_result)
            result = spawn_result;
        else
            uv_run(tc->loop, UV_RUN_DEFAULT);
    }

    FREE_ENV();
    MVM_free(_cwd);
#ifdef _WIN32
    MVM_free(_cmd);
#endif
    MVM_free(cmdin);
    uv_unref((uv_handle_t *)process);

    return result;
}
Ejemplo n.º 8
0
MVMObject * MVM_file_openpipe(MVMThreadContext *tc, MVMString *cmd, MVMString *cwd, MVMObject *env, MVMString *err_path) {
    MVMint64 spawn_result = 0;
    uv_process_t *process = calloc(1, sizeof(uv_process_t));
    uv_process_options_t process_options = {0};
    uv_stdio_container_t process_stdio[3];
    int i;
    int status;
    int readable = 1;
    uv_pipe_t *out, *in;

    char * const cmdin = MVM_string_utf8_encode_C_string(tc, cmd);
    char * const _cwd = MVM_string_utf8_encode_C_string(tc, cwd);
    const MVMuint64 size = MVM_repr_elems(tc, env);
    MVMIter * const iter = (MVMIter *)MVM_iter(tc, env);
    char **_env = malloc((size + 1) * sizeof(char *));

#ifdef _WIN32
    const MVMuint16 acp = GetACP(); /* We should get ACP at runtime. */
    char * const _cmd = ANSIToUTF8(acp, getenv("ComSpec"));
    char *args[3];
    args[0] = "/c";
    {
        MVMint64 len = strlen(cmdin);
        MVMint64 i;
        for (i = 0; i < len; i++)
            if (cmdin[i] == '/')
                cmdin[i] = '\\';
    }
    args[1] = cmdin;
    args[2] = NULL;
#else
    char * const _cmd = "/bin/sh";
    char *args[4];
    args[0] = "/bin/sh";
    args[1] = "-c";
    args[2] = cmdin;
    args[3] = NULL;
#endif

    INIT_ENV();
    /* Making openpipe distinguish between :rp and :wp and all other options
     * is left as an excercise for the reader. 
    readable = strncmp(cmdin, "/usr/bin/wc", 11) != 0; */

    if (readable) {
        /* We want to read from the child's stdout. */
        out = malloc(sizeof(uv_pipe_t));
        uv_pipe_init(tc->loop, out, 0);
        uv_pipe_open(out, 0);
        process_stdio[0].flags       = UV_INHERIT_FD; // child's stdin
        process_stdio[0].data.fd     = 0;
        process_stdio[1].flags       = UV_CREATE_PIPE | UV_WRITABLE_PIPE; // child's stdout
        process_stdio[1].data.stream = (uv_stream_t*)out;
    }
    else {
        /* We want to print to the child's stdin. */
        in  = malloc(sizeof(uv_pipe_t));
        uv_pipe_init(tc->loop, in, 0);
        uv_pipe_open(in, 1);
        process_stdio[0].flags       = UV_CREATE_PIPE | UV_READABLE_PIPE; // child's stdin
        process_stdio[0].data.stream = (uv_stream_t*)in;
        process_stdio[1].flags       = UV_INHERIT_FD; // child's stdout
        process_stdio[1].data.fd     = 1;
    }
    process_stdio[2].flags      = UV_INHERIT_FD; // child's stderr
    process_stdio[2].data.fd    = 2;
    process_options.stdio       = process_stdio;
    process_options.file        = _cmd;
    process_options.args        = args;
    process_options.cwd         = _cwd;
    process_options.flags       = UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS | UV_PROCESS_WINDOWS_HIDE;
    process_options.env         = _env;
    process_options.stdio_count = 3;
    process_options.exit_cb     = spawn_on_exit;
    uv_ref((uv_handle_t *)process);
    spawn_result = uv_spawn(tc->loop, process, &process_options);
    if (spawn_result) {
        FREE_ENV();
        free(_cwd);
        free(cmdin);
        uv_unref((uv_handle_t *)process);
        MVM_exception_throw_adhoc(tc, "Failed to open pipe: %d", errno);
    }

    FREE_ENV();
    free(_cwd);
    free(cmdin);
    uv_unref((uv_handle_t *)process);

    return MVM_io_syncpipe(tc, (uv_stream_t *)(readable ? out : in), process);
}