Exemplo n.º 1
0
static OpenFileInfo * create_open_file_info(Channel * ch, char * path, int file, DIR * dir) {
    LINK * list_head = NULL;

    OpenFileInfo * h = (OpenFileInfo *)loc_alloc_zero(sizeof(OpenFileInfo));
    for (;;) {
        LINK * list_next;
        OpenFileInfo * p = NULL;
        h->handle = handle_cnt++;
        list_head = &handle_hash[h->handle % HANDLE_HASH_SIZE];
        for (list_next = list_head->next; list_next != list_head; list_next = list_next->next) {
            if (hash2file(list_next)->handle == h->handle) {
                p = hash2file(list_next);
                break;
            }
        }
        if (p == NULL) break;
    }
    strcpy(h->path, path);
    h->file = file;
    h->dir = dir;
    h->inp = &ch->inp;
    h->out = &ch->out;
    list_add_first(&h->link_ring, &file_info_ring);
    list_add_first(&h->link_hash, list_head);
    list_init(&h->link_reqs);
    return h;
}
Exemplo n.º 2
0
int main()
{
	struct List * a = list_create();
	list_add_first(a, 1);
	list_add_first(a, 5);
	list_add_first(a, 16);
	list_add_first(a, 4);
	list_print(a);
}
static StreamClient * create_client(VirtualStream * stream, Channel * channel) {
    StreamClient * client = loc_alloc_zero(sizeof(StreamClient));
    list_init(&client->link_hash);
    list_init(&client->link_stream);
    list_init(&client->link_all);
    list_init(&client->read_requests);
    list_init(&client->write_requests);
    client->stream = stream;
    client->channel = channel;
    list_add_first(&client->link_hash, &handle_hash[get_client_hash(stream->id, channel)]);
    list_add_first(&client->link_stream, &stream->clients);
    list_add_first(&client->link_all, &clients);
    stream->ref_cnt++;
    return client;
}
void virtual_stream_create(const char * type, const char * context_id, size_t buf_len, unsigned access,
        VirtualStreamCallBack * callback, void * callback_args, VirtualStream ** res) {
    LINK * l;
    VirtualStream * stream = loc_alloc_zero(sizeof(VirtualStream));

    buf_len++;
    list_init(&stream->clients);
    strncpy(stream->type, type, sizeof(stream->type) - 1);
    stream->magic = STREAM_MAGIC;
    stream->id = id_cnt++;
    stream->access = access;
    stream->callback = callback;
    stream->callback_args = callback_args;
    stream->ref_cnt = 1;
    stream->buf = loc_alloc(buf_len);
    stream->buf_len = buf_len;
    for (l = subscriptions.next; l != &subscriptions; l = l->next) {
        Subscription * h = all2subscription(l);
        if (strcmp(type, h->type) == 0) {
            Trap trap;
            create_client(stream, h->channel);
            if (set_trap(&trap)) {
                send_event_stream_created(&h->channel->out, stream, context_id);
                clear_trap(&trap);
            }
            else {
                trace(LOG_ALWAYS, "Exception sending stream created event: %d %s",
                      trap.error, errno_to_str(trap.error));
            }
        }
    }
    list_add_first(&stream->link_all, &streams);
    *res = stream;
}
static void command_subscribe(char * token, Channel * c) {
    char type[256];
    int err = 0;
    LINK * l;

    json_read_string(&c->inp, type, sizeof(type));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);

    for (l = subscriptions.next; l != &subscriptions;) {
        Subscription * h = all2subscription(l);
        l = l->next;
        if (h->channel == c && strcmp(type, h->type) == 0) {
            err = ERR_OTHER;
            break;
        }
    }
    if (err == 0) {
        Subscription * s = loc_alloc_zero(sizeof(Subscription));
        list_init(&s->link_all);
        list_add_first(&s->link_all, &subscriptions);
        strncpy(s->type, type, sizeof(s->type) - 1);
        s->channel = c;
    }

    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    write_stream(&c->out, MARKER_EOM);
}
Exemplo n.º 6
0
/** add item to any position
 */
void list_add (linked_list* _this, void* item, int position) {
     // index out of list size
     if (position > _this->size) {
       return;
    }
    // add to head
    if (position == 0) {
        list_add_first(_this, item);
    } else if (position == _this->size) {
        // add to tail
        list_add_last(_this, item);
    } else {
        // insert between head and tail

       node* n = _this->head;
        int i = 0;
        // loop until the position
        while (i < position) {
            n = n->next;
            i++;
        }
        // insert new node to position
        node* newNode = list_create_node(item);
        list_insert_before(_this, n, newNode);
        _this->size++;
    }
}
Exemplo n.º 7
0
int context_attach(pid_t pid, ContextAttachCallBack * done, void * data, int mode) {
    Context * ctx = NULL;

    assert(done != NULL);
    trace(LOG_CONTEXT, "context: attaching pid %d", pid);
    if ((mode & CONTEXT_ATTACH_SELF) == 0 && ptrace(PT_ATTACH, pid, 0, 0) < 0) {
        int err = errno;
        trace(LOG_ALWAYS, "error: ptrace(PT_ATTACH) failed: pid %d, error %d %s",
            pid, err, errno_to_str(err));
        errno = err;
        return -1;
    }
    add_waitpid_process(pid);
    ctx = create_context(pid2id(pid, 0));
    ctx->mem = ctx;
    ctx->mem_access |= MEM_ACCESS_INSTRUCTION;
    ctx->mem_access |= MEM_ACCESS_DATA;
    ctx->mem_access |= MEM_ACCESS_USER;
    ctx->big_endian = big_endian_host();
    EXT(ctx)->pid = pid;
    EXT(ctx)->attach_callback = done;
    EXT(ctx)->attach_data = data;
    list_add_first(&ctx->ctxl, &pending_list);
    /* TODO: context_attach works only for main task in a process */
    return 0;
}
Exemplo n.º 8
0
static StreamClient * create_client(VirtualStream * stream, Channel * channel) {
    size_t len = (stream->buf_inp + stream->buf_len - stream->buf_out) % stream->buf_len;
    StreamClient * client = (StreamClient *)loc_alloc_zero(sizeof(StreamClient));
    list_init(&client->link_hash);
    list_init(&client->link_stream);
    list_init(&client->link_all);
    list_init(&client->read_requests);
    list_init(&client->write_requests);
    client->stream = stream;
    client->channel = channel;
    client->pos = stream->pos - len;
    list_add_first(&client->link_hash, &handle_hash[get_client_hash(stream->id, channel)]);
    list_add_first(&client->link_stream, &stream->clients);
    list_add_first(&client->link_all, &clients);
    stream->ref_cnt++;
    return client;
}
Exemplo n.º 9
0
static int start_process(Channel * c, char ** envp, char * dir, char * exe, char ** args, int attach,
                int * pid, int * selfattach, ChildProcess ** prs) {
    int err = 0;
    int fd_tty_master = -1;
    char * tty_slave_name = NULL;

    fd_tty_master = posix_openpt(O_RDWR|O_NOCTTY);
    if (fd_tty_master < 0 || grantpt(fd_tty_master) < 0 ||
        unlockpt(fd_tty_master) < 0 || (tty_slave_name = ptsname(fd_tty_master)) == NULL) err = errno;

    if (err == 0 && fd_tty_master < 3) {
        int fd0 = fd_tty_master;
        if ((fd_tty_master = dup(fd_tty_master)) < 0 || close(fd0)) err = errno;
    }

    if (!err) {
        *pid = fork();
        if (*pid < 0) err = errno;
        if (*pid == 0) {
            int fd = -1;
            int fd_tty_slave = -1;

            setsid();
            if (!err && (fd = sysconf(_SC_OPEN_MAX)) < 0) err = errno;
            if (!err && (fd_tty_slave = open(tty_slave_name, O_RDWR)) < 0) err = errno;
            if (!err && dup2(fd_tty_slave, 0) < 0) err = errno;
            if (!err && dup2(fd_tty_slave, 1) < 0) err = errno;
            if (!err && dup2(fd_tty_slave, 2) < 0) err = errno;
            while (!err && fd > 3) close(--fd);
            if (!err && attach && context_attach_self() < 0) err = errno;
            if (!err) {
                execve(exe, args, envp);
                err = errno;
            }
            if (!attach) err = 1;
            else if (err < 1) err = EINVAL;
            else if (err > 0xff) err = EINVAL;
            exit(err);
        }
    }
    if (!err) {
        *prs = loc_alloc_zero(sizeof(ChildProcess));
        (*prs)->inp = fd_tty_master;
        (*prs)->out = fd_tty_master;
        (*prs)->err = fd_tty_master;
        (*prs)->pid = *pid;
        (*prs)->bcg = c->bcg;
        list_add_first(&(*prs)->link, &prs_list);
    }

    *selfattach = 1;

    if (!err) return 0;
    errno = err;
    return -1;
}
Exemplo n.º 10
0
int main () {
    int i;
    struct Node **a = calloc (1, sizeof (struct Node*));
    *a = NULL;
    for (i = 0; i < 5; i++) {
        list_add_first(a, i);
    }
    list_sort (a);
    return 0;   
}
Exemplo n.º 11
0
void task_init() {
  active_tasks = (struct list_t *)malloc_alloc(sizeof(struct list_t));
  list_init(active_tasks);

  inactive_tasks = (struct list_t *)malloc_alloc(sizeof(struct list_t));
  list_init(inactive_tasks);

  struct task_t *task = (struct task_t *)malloc_alloc(sizeof(struct task_t));
  task->sp    = 0;
  task->msg   = 0;

  list_add_first(active_tasks, task);
  current_task_it = list_first(active_tasks);
}
Exemplo n.º 12
0
void list_sort(struct Node **list)
{
    int i, j, size = list_size(*list);
    int *a = calloc(size, sizeof(Data));
    struct Node *curr = *list;
    for (i = 0; i < size; i++) {
	a[i] = curr->val;
	curr = curr->next;
    }
    qsort(a, size, sizeof(int), cmp_int);
    list_clear(list);
    for (i = size - 1; i >= 0; i--)
	if (i != 0 && a[i] != a[i - 1] || i == 0)
	    list_add_first(list, a[i]);
    free(a);
}
Exemplo n.º 13
0
main()

{
	DynamicList* l = list_inicialize();

	/*Aluno* Al1 = (Aluno*)malloc(sizeof(Aluno));
	Aluno* Al2 = (Aluno*)malloc(sizeof(Aluno));

	Al1->RA = 1516;
	Al1->nome = "JOAO";

	Al2->RA = 2324;
	Al2->nome = "SIBA";
	*/

	printf("\nInseriu? %s", list_add_last(l, 'a')?"sim":"não");
	printf("\nInseriu? %s", list_add_last(l, 'b')?"sim":"não");

	printf("\nFirst %c\n", list_get_first(l));
	printf("\nLast %c\n", list_get_last(l));

	printf("\nInseriu? %s", list_add_last(l, 'c')?"sim":"não");
	printf("\nInseriu? %s", list_add_last(l, 'd')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'e')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'f')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'g')?"sim":"não");

	printf("\nFirst %c\n", list_get_first(l));
	printf("\nLast %c\n", list_get_last(l));

	list_print(l);

	printf("\nSize %d\n", list_size(l));

	list_clear(l);

	printf("\nSize %d\n", list_size(l));

	printf("\nInseriu? %s", list_add_last(l, 'c')?"sim":"não");
	printf("\nInseriu? %s", list_add_last(l, 'd')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'e')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'f')?"sim":"não");
	printf("\nInseriu? %s", list_add_first(l, 'g')?"sim":"não");

	list_print(l);

	list_remove_first(l);	
	list_remove_first(l);	
	list_remove_first(l);	
	
	list_print(l);
}
Exemplo n.º 14
0
void cons(i_list* l) {

    int i;

    // list size was increased: add nodes
    if (*l->size > l->prev_size) {
        for (i = 0; i < *l->size - l->prev_size; ++i)
            list_add_first(l->head, 0);
    }

    // list size was decreased: delete nodes
    else if (*l->size < l->prev_size) {
        for (i = 0; i < l->prev_size - *l->size; ++i)
            list_remove_first(l->head);
    }

    l->prev_size = *l->size;

    printf("list: ");
    list_print(*l->head);
}
Exemplo n.º 15
0
int main(int argc, char** argv) {
	t_list L = NULL;

	list_add_first(&L, ints);
	list_add_order(&L, ints+1, comp_int);
	list_add_order(&L, ints+2, comp_int);
	list_add_order(&L, ints+3, comp_int);
	list_add_order(&L, ints+5, comp_int);
	list_add_order(&L, ints+4, comp_int);

	list_del_data_all(&L, ints+4, comp_int);

	if (L == NULL)
		return -1;

	list_apply_func(L, print_int);

	list_destroy(L);

	printf("\nList Test End.\n");

	return 0;
}
Exemplo n.º 16
0
int virtual_stream_subscribe(Channel * c, const char * type) {
    LINK * l;
    int err = 0;

    for (l = subscriptions.next; l != &subscriptions;) {
        Subscription * h = all2subscription(l);
        l = l->next;
        if (h->channel == c && strcmp(type, h->type) == 0) {
            err = set_errno(ERR_OTHER, "Already subscribed");
            break;
        }
    }
    if (err == 0) {
        Subscription * s = (Subscription *)loc_alloc_zero(sizeof(Subscription));
        list_init(&s->link_all);
        list_add_first(&s->link_all, &subscriptions);
        strlcpy(s->type, type, sizeof(s->type));
        s->channel = c;
    }
    else errno = err;

    return err == 0 ? 0 : -1;
}
int main(void)
{
	linked_list_t *list = (linked_list_t*)malloc(sizeof(linked_list_t));
	list_init(list);

	for (int i = 0; i < 10; i++){
		char string[100];
		sprintf(string, "Number: %d", i);
		list_add_first(list_create_node(i, string), list);
		list_add_last (list_create_node(i, string), list);
	}

	printf("Non-empty list\n");
	list_print(list);

	list_clear(list);

	printf("Empty list\n");
	list_print(list);

	list_free(list);
	free(list);
	return 0;
}
Exemplo n.º 18
0
static void command_launch(char * token, Channel * c) {
    int err = 0;
    char encoding[TERM_PROP_DEF_SIZE];
    char pty_type[TERM_PROP_DEF_SIZE];
    const char * args[] = TERM_LAUNCH_ARGS;
    const char * exec = TERM_LAUNCH_EXEC;

    int selfattach = 0;
    ProcessStartParams prms;
    Terminal * term = (Terminal *)loc_alloc_zero(sizeof(Terminal));

    memset(&prms, 0, sizeof(prms));
    json_read_string(&c->inp, pty_type, sizeof(pty_type));
    json_test_char(&c->inp, MARKER_EOA);
    json_read_string(&c->inp, encoding, sizeof(encoding));
    json_test_char(&c->inp, MARKER_EOA);
    prms.envp = read_env(&c->inp);
    json_test_char(&c->inp, MARKER_EOM);

#if !defined(_WIN32) && !defined(__CYGWIN__)
    {
        struct stat st;
        if (err == 0 && stat(exec, &st) != 0) {
            err = errno;
            if (err == ENOENT) {
                static char fnm[FILE_PATH_SIZE];
                /* On some systems (e.g. Free DSB) bash is installed under /usr/local */
                assert(exec[0] == '/');
                snprintf(fnm, sizeof(fnm), "/usr/local%s", exec);
                if (stat(fnm, &st) == 0) {
                    args[0] = exec = fnm;
                    err = 0;
                }
            }
            if (err == ENOENT && strcmp(exec, "/bin/bash") == 0) {
                /* "bash" not found, try "sh" */
                const char * fnm = "/bin/sh";
                if (stat(fnm, &st) == 0) {
                    args[0] = exec = fnm;
                    err = 0;
                }
            }
            if (err) err = set_fmt_errno(err, "Cannot start %s", exec);
        }
    }
    set_terminal_env(&prms.envp, pty_type, encoding, exec);
    prms.dir = getenv("HOME");
    if (prms.dir) prms.dir = tmp_strdup(prms.dir);
#else
    {
        const char * home_drv = getenv("HOMEDRIVE");
        const char * home_dir = getenv("HOMEPATH");
        if (home_drv && home_dir) {
            prms.dir = tmp_strdup2(home_drv, home_dir);
        }
    }
#endif

    prms.exe = exec;
    prms.args = (char **)args;
    prms.service = TERMINALS;
    prms.use_terminal = 1;
    prms.exit_cb = terminal_exited;
    prms.exit_args = term;

    if (err == 0 && start_process(c, &prms, &selfattach, &term->prs) < 0) err = errno;

    if (!err) {
        term->bcg = c->bcg;
        channel_lock_with_msg(term->channel = c, TERMINALS);
        strlcpy(term->pty_type, pty_type, sizeof(term->pty_type));
        strlcpy(term->encoding, encoding, sizeof(term->encoding));
        list_add_first(&term->link, &terms_list);
        assert(find_terminal(get_process_pid(term->prs)) == term);
    }
    else {
        assert(term->prs == NULL);
        loc_free(term);
    }

    /* write result back */
    write_stringz(&c->out, "R");
    write_stringz(&c->out, token);
    write_errno(&c->out, err);
    if (err) {
        write_stringz(&c->out, "null");
    }
    else {
        write_context(&c->out, get_process_pid(term->prs));
        write_stream(&c->out, 0);
    }
    write_stream(&c->out, MARKER_EOM);
}
Exemplo n.º 19
0
void list_add_data_first(void* data, struct list_head *head)
{
	struct list_head* elem = new_list_elem( data );
	list_add_first(elem, head);
}
Exemplo n.º 20
0
static int start_process(Channel * c, char ** envp, char * dir, char * exe, char ** args, int attach,
                int * pid, int * selfattach, ChildProcess ** prs) {
    int err = 0;
    int p_inp[2];
    int p_out[2];
    int p_err[2];

    if (pipe(p_inp) < 0 || pipe(p_out) < 0 || pipe(p_err) < 0) err = errno;

    if (err == 0 && (p_inp[0] < 3 || p_out[1] < 3 || p_err[1] < 3)) {
        int fd0 = p_inp[0];
        int fd1 = p_out[1];
        int fd2 = p_err[1];
        if ((p_inp[0] = dup(p_inp[0])) < 0 ||
            (p_out[1] = dup(p_out[1])) < 0 ||
            (p_err[1] = dup(p_err[1])) < 0 ||
            close(fd0) < 0 ||
            close(fd1) < 0 ||
            close(fd2) < 0) err = errno;
    }

    if (!err) {
        *pid = fork();
        if (*pid < 0) err = errno;
        if (*pid == 0) {
            int fd = -1;
            int err = 0;

            if (err == 0) {
                fd = sysconf(_SC_OPEN_MAX);
                if (fd < 0) err = errno;
            }
            if (!err && dup2(p_inp[0], 0) < 0) err = errno;
            if (!err && dup2(p_out[1], 1) < 0) err = errno;
            if (!err && dup2(p_err[1], 2) < 0) err = errno;
            if (!err) {
                while (fd > 3) close(--fd);
            }
            if (!err && attach && context_attach_self() < 0) err = errno;
            if (!err) {
                execve(exe, args, envp);
                err = errno;
            }
            if (!attach) err = 1;
            else if (err < 1) err = EINVAL;
            else if (err > 0xff) err = EINVAL;
            exit(err);
        }
    }
    if (!err) {
        if (close(p_inp[0]) < 0 || close(p_out[1]) < 0 || close(p_err[1]) < 0) err = errno;
    }
    if (!err) {
        *prs = loc_alloc_zero(sizeof(ChildProcess));
        (*prs)->inp = p_inp[1];
        (*prs)->out = p_out[0];
        (*prs)->err = p_err[0];
        (*prs)->pid = *pid;
        (*prs)->bcg = c->bcg;
        list_add_first(&(*prs)->link, &prs_list);
    }

    *selfattach = 1;

    if (!err) return 0;
    errno = err;
    return -1;
}
Exemplo n.º 21
0
void test_list(void)
{
    int val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    list me = list_init(sizeof(int));
    assert(me);
    assert(list_size(me) == 0);
    assert(list_is_empty(me));
    for (int i = 0; i < 10; i++) {
        list_add_first(me, &val[i]);
        assert(list_size(me) == i + 1);
        int get = 0;
        list_get_first(&get, me);
        assert(get == val[i]);
    }
    assert(list_size(me) == 10);
    assert(!list_is_empty(me));
    int get_arr[10] = {0};
    list_copy_to_array(get_arr, me);
    for (int i = 0; i < 10; i++) {
        int get = 0;
        list_get_at(&get, me, i);
        assert(get == val[9 - i]);
        assert(get_arr[i] == val[9 - i]);
    }
    for (int i = 0; i < 7; i++) {
        list_remove_last(me);
    }
    int trimmed[5] = {0};
    list_copy_to_array(trimmed, me);
    assert(list_size(me) == 3);
    for (int i = 0; i < 3; i++) {
        assert(10 - i == trimmed[i]);
    }
    int add = 3;
    list_add_last(me, &add);
    add = -1;
    list_add_at(me, 1, &add);
    add = -2;
    list_add_last(me, &add);
    assert(list_size(me) == 6);
    int get = 0xdeadbeef;
    list_get_first(&get, me);
    assert(get == 10);
    get = 0xdeadbeef;
    list_get_at(&get, me, 0);
    assert(get == 10);
    list_get_at(&get, me, 1);
    assert(get == -1);
    list_get_at(&get, me, 2);
    assert(get == 9);
    list_get_at(&get, me, 3);
    assert(get == 8);
    list_get_at(&get, me, 4);
    assert(get == 3);
    list_get_at(&get, me, 5);
    assert(get == -2);
    get = 0xdeadbeef;
    list_get_last(&get, me);
    assert(get == -2);
    list_remove_first(me);
    list_remove_at(me, 2);
    list_remove_last(me);
    assert(list_size(me) == 3);
    get = 345;
    list_get_first(&get, me);
    assert(get == -1);
    list_get_at(&get, me, 1);
    assert(get == 9);
    list_get_last(&get, me);
    assert(get == 3);
    int set = 12;
    list_set_first(me, &set);
    set = 13;
    list_set_at(me, 1, &set);
    set = 14;
    list_set_last(me, &set);
    int arr[3] = {0};
    list_copy_to_array(arr, me);
    assert(arr[0] == 12);
    assert(arr[1] == 13);
    assert(arr[2] == 14);
    set = -5;
    list_set_at(me, 0, &set);
    set = -6;
    list_set_at(me, 1, &set);
    set = -7;
    list_set_at(me, 2, &set);
    list_copy_to_array(arr, me);
    assert(arr[0] == -5);
    assert(arr[1] == -6);
    assert(arr[2] == -7);
    assert(list_set_at(me, 4, &set) == -EINVAL);
    assert(list_get_at(&set, me, 4) == -EINVAL);
    assert(list_remove_at(me, 4) == -EINVAL);
    assert(list_add_at(me, 5, &set) == -EINVAL);
    assert(list_set_at(me, -1, &set) == -EINVAL);
    assert(list_get_at(&set, me, -1) == -EINVAL);
    assert(list_remove_at(me, -1) == -EINVAL);
    assert(list_add_at(me, -1, &set) == -EINVAL);
    list_clear(me);
    assert(list_size(me) == 0);
    assert(list_is_empty(me));
    assert(list_remove_first(me) == -EINVAL);
    assert(list_remove_last(me) == -EINVAL);
    me = list_destroy(me);
    assert(!me);
}
Exemplo n.º 22
0
static int start_process(Channel * c, char ** envp, char * dir, char * exe, char ** args, int attach,
                int * pid, int * selfattach, ChildProcess ** prs) {
    typedef struct _SYSTEM_HANDLE_INFORMATION {
        ULONG Count;
        struct HANDLE_INFORMATION {
            USHORT ProcessId;
            USHORT CreatorBackTraceIndex;
            UCHAR ObjectTypeNumber;
            UCHAR Flags;
            USHORT Handle;
            PVOID Object;
            ACCESS_MASK GrantedAccess;
        } Handles[1];
    } SYSTEM_HANDLE_INFORMATION;
    FARPROC QuerySystemInformationProc = GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation");
    DWORD size;
    NTSTATUS status;
    SYSTEM_HANDLE_INFORMATION * hi = NULL;
    int fpipes[3][2];
    HANDLE hpipes[3][2];
    char * cmd = NULL;
    int err = 0;
    int i;

    if (args != NULL) {
        int i = 0;
        int cmd_size = 0;
        int cmd_pos = 0;
#           define cmd_append(ch) { \
            if (!cmd) { \
                cmd_size = 0x1000; \
                cmd = (char *)loc_alloc(cmd_size); \
            } \
            else if (cmd_pos >= cmd_size) { \
                char * tmp = (char *)loc_alloc(cmd_size * 2); \
                memcpy(tmp, cmd, cmd_pos); \
                loc_free(cmd); \
                cmd = tmp; \
                cmd_size *= 2; \
            }; \
            cmd[cmd_pos++] = (ch); \
        }
        while (args[i] != NULL) {
            char * p = args[i++];
            if (cmd_pos > 0) cmd_append(' ');
            cmd_append('"');
            while (*p) {
                if (*p == '"') cmd_append('\\');
                cmd_append(*p);
                p++;
            }
            cmd_append('"');
        }
        cmd_append(0);
#       undef cmd_append
    }

    size = sizeof(SYSTEM_HANDLE_INFORMATION) * 16;
    hi = loc_alloc(size);
    for (;;) {
        status = QuerySystemInformationProc(SystemHandleInformation, hi, size, &size);
        if (status != STATUS_INFO_LENGTH_MISMATCH) break;
        hi = loc_realloc(hi, size);
    }
    if (status == 0) {
        ULONG i;
        DWORD id = GetCurrentProcessId();
        for (i = 0; i < hi->Count; i++) {
            if (hi->Handles[i].ProcessId != id) continue;
            SetHandleInformation((HANDLE)(int)hi->Handles[i].Handle, HANDLE_FLAG_INHERIT, FALSE);
        }
    }
    else {
        err = set_win32_errno(status);
        trace(LOG_ALWAYS, "Can't start process '%s': %s", exe, errno_to_str(err));
    }
    loc_free(hi);

    memset(hpipes, 0, sizeof(hpipes));
    for (i = 0; i < 3; i++) fpipes[i][0] = fpipes[i][1] = -1;
    if (!err) {
#if defined(__CYGWIN__)
        for (i = 0; i < 3; i++) {
            if (pipe(fpipes[i]) < 0) {
                err = errno;
                break;
            }
            hpipes[i][0] = (HANDLE)get_osfhandle(fpipes[i][0]);
            hpipes[i][1] = (HANDLE)get_osfhandle(fpipes[i][1]);
        }
#else
        for (i = 0; i < 3; i++) {
            if (!CreatePipe(&hpipes[i][0], &hpipes[i][1], NULL, PIPE_SIZE)) {
                err = set_win32_errno(GetLastError());
                break;
            }
            fpipes[i][0] = _open_osfhandle((intptr_t)hpipes[i][0], O_TEXT);
            fpipes[i][1] = _open_osfhandle((intptr_t)hpipes[i][1], O_TEXT);
        }
#endif
    }
    if (!err) {
        STARTUPINFO si;
        PROCESS_INFORMATION prs_info;
        SetHandleInformation(hpipes[0][0], HANDLE_FLAG_INHERIT, TRUE);
        SetHandleInformation(hpipes[1][1], HANDLE_FLAG_INHERIT, TRUE);
        SetHandleInformation(hpipes[2][1], HANDLE_FLAG_INHERIT, TRUE);
        memset(&si, 0, sizeof(si));
        memset(&prs_info, 0, sizeof(prs_info));
        si.cb = sizeof(si);
        si.dwFlags |= STARTF_USESTDHANDLES;
        si.hStdInput  = hpipes[0][0];
        si.hStdOutput = hpipes[1][1];
        si.hStdError  = hpipes[2][1];
        if (CreateProcess(exe, cmd, NULL, NULL, TRUE, (attach ? CREATE_SUSPENDED : 0),
                (envp ? envp[0] : NULL), (dir[0] ? dir : NULL), &si, &prs_info) == 0)
        {
            err = set_win32_errno(GetLastError());
        }
        else {
            *pid = prs_info.dwProcessId;
            CloseHandle(prs_info.hThread);
            CloseHandle(prs_info.hProcess);
        }
    }
    close(fpipes[0][0]);
    close(fpipes[1][1]);
    close(fpipes[2][1]);
    if (!err) {
        *prs = loc_alloc_zero(sizeof(ChildProcess));
        (*prs)->inp = fpipes[0][1];
        (*prs)->out = fpipes[1][0];
        (*prs)->err = fpipes[2][0];
        (*prs)->pid = *pid;
        (*prs)->bcg = c->bcg;
        list_add_first(&(*prs)->link, &prs_list);
    }
    else {
        close(fpipes[0][1]);
        close(fpipes[1][0]);
        close(fpipes[2][0]);
    }
    loc_free(cmd);
    if (!err) return 0;
    trace(LOG_ALWAYS, "Can't start process '%s': %s", exe, errno_to_str(err));
    errno = err;
    return -1;
}
Exemplo n.º 23
0
static int start_process(Channel * c, char ** envp, char * dir, char * exe, char ** args, int attach,
                int * pid, int * selfattach, ChildProcess ** prs) {
    int err = 0;
    char * ptr;
    SYM_TYPE type;

    if (symFindByName(sysSymTbl, exe, &ptr, &type) != OK) {
        err = errno;
        if (err == S_symLib_SYMBOL_NOT_FOUND) err = ERR_SYM_NOT_FOUND;
        assert(err != 0);
    }
    else {
        int i;
        int pipes[2][2];
        /* TODO: arguments, environment */
        *pid = taskCreate("tTcf", 100, 0, 0x4000, (FUNCPTR)ptr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
        for (i = 0; i < 2; i++) {
            char pnm[32];
            char pnm_m[32];
            char pnm_s[32];
            snprintf(pnm, sizeof(pnm), "/pty/tcf-%0*lx-%d", sizeof(*pid) * 2, *pid, i);
            snprintf(pnm_m, sizeof(pnm_m), "%sM", pnm);
            snprintf(pnm_s, sizeof(pnm_m), "%sS", pnm);
            if (ptyDevCreate(pnm, PIPE_SIZE, PIPE_SIZE) == ERROR) {
                err = errno;
                break;
            }
            pipes[i][0] = open(pnm_m, O_RDWR, 0);
            pipes[i][1] = open(pnm_s, O_RDWR, 0);
            if (pipes[i][0] < 0 || pipes[i][1] < 0) {
                err = errno;
                break;
            }
        }
        if (err) {
            taskDelete(*pid);
            *pid = 0;
        }
        else {
            semTake(prs_list_lock, WAIT_FOREVER);
            ioTaskStdSet(*pid, 0, pipes[0][1]);
            ioTaskStdSet(*pid, 1, pipes[0][1]);
            ioTaskStdSet(*pid, 2, pipes[1][1]);
            *prs = loc_alloc_zero(sizeof(ChildProcess));
            (*prs)->inp = pipes[0][0];
            (*prs)->out = pipes[0][0];
            (*prs)->err = pipes[1][0];
            (*prs)->pid = *pid;
            (*prs)->bcg = c->bcg;
            list_add_first(&(*prs)->link, &prs_list);
            if (attach) {
                taskStop(*pid);
                taskActivate(*pid);
                assert(taskIsStopped(*pid));
            }
            else {
                taskActivate(*pid);
            }
            semGive(prs_list_lock);
        }
    }
    if (!err) return 0;
    errno = err;
    return -1;
}