Пример #1
0
int shim_do_getsid (pid_t pid)
{
    struct shim_thread * thread =
            pid ? lookup_thread(pid) : get_cur_thread();

    if (!thread)
        return -ESRCH;

    return thread->pgid;
}
Пример #2
0
void signal_alarm (IDTYPE target, void * arg)
{
    debug("alarm goes off, signaling thread %u\n", target);

    struct shim_thread * thread = lookup_thread(target);
    if (!thread)
        return;

    append_signal(thread, SIGALRM, NULL, true);
}
Пример #3
0
void signal_io (IDTYPE target, void * arg)
{
    debug("detecting input, signaling thread %u\n", target);

    struct shim_thread * thread = lookup_thread(target);
    if (!thread)
        return;

    append_signal(thread, SIGIO, NULL, true);
}
Пример #4
0
/* If *phdl is returned on success, the ref count is incremented */
static int parse_thread_fd (const char * name, const char ** rest,
                            struct shim_handle ** phdl)
{
    const char * next, * nextnext;
    int next_len;

    int pid = parse_thread_name(name, &next, &next_len, &nextnext);

    if (!pid)
        return pid;

    if (!next || !nextnext || memcmp(next, "fd", next_len))
        return -EINVAL;

    const char * p = nextnext;
    int fd = 0;

    for ( ; *p && *p != '/' ; p++) {
        if (*p < '0' || *p > '9')
            return -ENOENT;
        fd = fd * 10 + *p - '0';
        if (fd >= __rlim[RLIMIT_NOFILE].rlim_cur)
            return -ENOENT;
    }

    struct shim_thread * thread = lookup_thread(pid);

    if (!thread)
        return -ENOENT;

    struct shim_handle_map * handle_map = get_cur_handle_map(thread);

    lock(&handle_map->lock);

    if (fd >= handle_map->fd_top ||
        handle_map->map[fd] == NULL ||
        handle_map->map[fd]->handle == NULL) {
        unlock(&handle_map->lock);
        return -ENOENT;
    }

    if (phdl) {
        *phdl = handle_map->map[fd]->handle;
        get_handle(*phdl);
    }

    unlock(&handle_map->lock);

    if (rest)
        *rest = *p ? p + 1 : NULL;

    return 0;
}
Пример #5
0
int shim_do_setpgid (pid_t pid, pid_t pgid)
{
    struct shim_thread * thread =
            pid ? lookup_thread(pid) : get_cur_thread();

    if (!pid)
        assert(thread);

    if (!thread)
        return -ESRCH;

    thread->pgid = pgid ? : thread->tgid;

    return 0;
}
Пример #6
0
static int proc_list_thread_each_fd (const char * name,
                                     struct shim_dirent ** buf, int count)
{
    const char * next;
    int next_len;
    int pid = parse_thread_name(name, &next, &next_len, NULL);

    if (!pid)
        return pid;

    if (!next || memcmp(next, "fd", next_len))
        return -EINVAL;

    struct shim_thread * thread = lookup_thread(pid);
    if (!thread)
        return -ENOENT;

    struct shim_handle_map * handle_map = get_cur_handle_map(thread);
    int err = 0, bytes = 0;
    struct shim_dirent * dirent = *buf, ** last = NULL;

    lock(&handle_map->lock);

    for (int i = 0 ; i < handle_map->fd_size ; i++)
        if (handle_map->map[i] &&
            handle_map->map[i]->handle) {
            int d = i, l = 0;
            for ( ; d ; d /= 10, l++);
            l = l ? : 1;

            bytes += sizeof(struct shim_dirent) + l + 1;
            if (bytes > count) {
                err = -ENOMEM;
                break;
            }

            dirent->next = (void *) (dirent + 1) + l + 1;
            dirent->ino = 1;
            dirent->type = LINUX_DT_LNK;
            dirent->name[0] = '0';
            dirent->name[l--] = 0;
            for (d = i ; d ; d /= 10)
                dirent->name[l--] = '0' + d % 10;
            last = &dirent->next;
            dirent = dirent->next;
        }
Пример #7
0
pid_t shim_do_wait4 (pid_t pid, int * status, int option,
                     struct __kernel_rusage * ru)
{
    struct shim_thread * cur = get_cur_thread();
    struct shim_thread * thread = NULL;
    int ret = 0;

    INC_PROFILE_OCCURENCE(syscall_use_ipc);

    if (pid > 0) {
        if (!(thread = lookup_thread(pid)))
            return -ECHILD;

        if (!(option & WNOHANG)) {
block_pid:
            DkObjectsWaitAny(1, &thread->exit_event,
                             NO_TIMEOUT);
        }

        lock(thread->lock);

        if (thread->is_alive) {
            unlock(thread->lock);
            if (!(option & WNOHANG))
                goto block_pid;
            put_thread(thread);
            return 0;
        }

        if (!list_empty(&thread->siblings)) {
            struct shim_thread * parent = thread->parent;
            assert(parent);

            lock(parent->lock);
            list_del_init(&thread->siblings);
            unlock(parent->lock);

            put_thread(parent);
            put_thread(thread);
            thread->parent = NULL;
        }

        unlock(thread->lock);
        goto found;
    }

    lock(cur->lock);

    if (list_empty(&cur->children) &&
        list_empty(&cur->exited_children)) {
        unlock(cur->lock);
        return -ECHILD;
    }

    if (!(option & WNOHANG)) {
block:
        if (cur->child_exit_event)
            while (list_empty(&cur->exited_children)) {
                unlock(cur->lock);
                DkObjectsWaitAny(1, &cur->child_exit_event, NO_TIMEOUT);
                lock(cur->lock);
            }
    }

    if (pid == 0 || pid < -1) {
        if (pid == 0)
            pid = -cur->pgid;

        list_for_each_entry(thread, &cur->exited_children, siblings)
            if (thread->pgid == -pid)
                goto found_child;

        if (!(option & WNOHANG))
            goto block;
    } else {
        if (!list_empty(&cur->exited_children)) {
Пример #8
0
static int find_thread_link (const char * name, struct shim_qstr * link,
                             struct shim_dentry ** dentptr,
                             struct shim_thread ** threadptr)
{
    const char * next, * nextnext;
    int next_len;
    int pid = parse_thread_name(name, &next, &next_len, &nextnext);
    if (pid < 0)
        return pid;

    struct shim_thread * thread = lookup_thread(pid);
    struct shim_dentry * dent = NULL;
    int ret = 0;

    if (!thread)
        return -ENOENT;

    if (!thread->in_vm) {
        ret = -ENOENT;
        goto out;
    }

    lock(&thread->lock);

    if (next_len == static_strlen("root") && !memcmp(next, "root", next_len)) {
        dent = thread->root;
        get_dentry(dent);
    }

    if (next_len == static_strlen("cwd") && !memcmp(next, "cwd", next_len)) {
        dent = thread->cwd;
        get_dentry(dent);
    }

    if (next_len == static_strlen("exe") && !memcmp(next, "exe", next_len)) {
        struct shim_handle * exec = thread->exec;
        if (!exec->dentry) {
            unlock(&thread->lock);
            ret = -EINVAL;
            goto out;
        }
        dent = exec->dentry;
        get_dentry(dent);
    }

    unlock(&thread->lock);

    if (nextnext) {
        struct shim_dentry * next_dent = NULL;

        ret = path_lookupat(dent, nextnext, 0, &next_dent, dent->fs);
        if (ret < 0)
            goto out;

        put_dentry(dent);
        dent = next_dent;
    }

    if (link) {
        int size;
        char * path = dentry_get_path(dent, true, &size);
        qstrsetstr(link, path, size);
    }

    if (dentptr) {
        get_dentry(dent);
        *dentptr = dent;
    }

    if (threadptr) {
        get_thread(thread);
        *threadptr = thread;
    }

    ret = 0;
out:
    if (dent)
        put_dentry(dent);
    if (thread)
        put_thread(thread);
    return ret;
}