Ejemplo n.º 1
0
int shim_do_pipe2 (int * filedes, int flags)
{
    if (!filedes)
        return -EINVAL;

    int ret = 0;

    struct shim_handle * hdl1 = get_new_handle();
    struct shim_handle * hdl2 = get_new_handle();

    if (!hdl1 || !hdl2) {
        ret = -ENOMEM;
        goto out;
    }

    hdl1->type       = TYPE_PIPE;
    set_handle_fs(hdl1, &pipe_builtin_fs);
    hdl1->flags      = O_RDONLY;
    hdl1->acc_mode   = MAY_READ;

    hdl2->type       = TYPE_PIPE;
    set_handle_fs(hdl2, &pipe_builtin_fs);
    hdl2->flags      = O_WRONLY;
    hdl2->acc_mode   = MAY_WRITE;

    if ((ret = create_pipes(&hdl1->info.pipe.pipeid,
                            &hdl1->pal_handle, &hdl2->pal_handle,
                            &hdl1->uri, flags)) < 0)
        goto out;

    qstrcopy(&hdl2->uri, &hdl2->uri);

    flags = flags & O_CLOEXEC ? FD_CLOEXEC : 0;
    int vfd1 = set_new_fd_handle(hdl1, flags, NULL);
    int vfd2 = set_new_fd_handle(hdl2, flags, NULL);

    if (vfd1 < 0 || vfd2 < 0) {
        if (vfd1 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        if (vfd2 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        goto out;
    }

    filedes[0] = vfd1;
    filedes[1] = vfd2;
out:
    if (hdl1)
        put_handle(hdl1);
    if (hdl2)
        put_handle(hdl2);
    return ret;
}
Ejemplo n.º 2
0
static inline int init_tty_handle (struct shim_handle * hdl, bool write)
{
    struct shim_dentry * dent = NULL;
    int ret;

    if ((ret = path_lookupat(NULL, "/dev/tty", LOOKUP_OPEN, &dent)) < 0)
        return ret;

    int flags = (write ? O_WRONLY : O_RDONLY)|O_APPEND;
    struct shim_mount * fs = dent->fs;
    ret = fs->d_ops->open(hdl, dent, flags);
    if (ret < 0)
        return ret;

    set_handle_fs(hdl, fs);
    hdl->dentry = dent;
    hdl->flags = O_RDWR|O_APPEND|0100000;

    int size;
    char * path = dentry_get_path(dent, true, &size);
    if (path)
        qstrsetstr(&hdl->path, path, size);
    else
        qstrsetstr(&hdl->path, "/dev/tty", 8);

    return 0;
}
Ejemplo n.º 3
0
static inline int init_exec_handle (struct shim_thread * thread)
{
    if (!PAL_CB(executable))
        return 0;

    struct shim_handle * exec = get_new_handle();
    if (!exec)
        return -ENOMEM;

    set_handle_fs(exec, &chroot_builtin_fs);
    qstrsetstr(&exec->uri, PAL_CB(executable), strlen(PAL_CB(executable)));
    exec->type     = TYPE_FILE;
    exec->flags    = O_RDONLY;
    exec->acc_mode = MAY_READ;

    lock(thread->lock);
    thread->exec = exec;
    unlock(thread->lock);

    return 0;
}
Ejemplo n.º 4
0
int shim_do_socketpair (int domain, int type, int protocol, int * sv)
{
    if (domain != AF_UNIX)
        return -EAFNOSUPPORT;

    if (type != SOCK_STREAM)
        return -EPROTONOSUPPORT;

    if (!sv)
        return -EINVAL;

    int ret = 0;
    struct shim_handle * hdl1 = get_new_handle();
    struct shim_handle * hdl2 = get_new_handle();

    if (!hdl1 || !hdl2) {
        ret = -ENOMEM;
        goto out;
    }

    struct shim_sock_handle * sock1 = &hdl1->info.sock;
    struct shim_sock_handle * sock2 = &hdl2->info.sock;

    hdl1->type          = TYPE_SOCK;
    set_handle_fs(hdl1, &socket_builtin_fs);
    hdl1->flags         = O_RDONLY;
    hdl1->acc_mode      = MAY_READ|MAY_WRITE;
    sock1->domain       = domain;
    sock1->sock_type    = type & ~(SOCK_NONBLOCK|SOCK_CLOEXEC);
    sock1->protocol     = protocol;
    sock1->sock_state   = SOCK_ACCEPTED;

    hdl2->type          = TYPE_SOCK;
    set_handle_fs(hdl2, &socket_builtin_fs);
    hdl1->flags         = O_WRONLY;
    hdl2->acc_mode      = MAY_READ|MAY_WRITE;
    sock2->domain       = domain;
    sock2->sock_type    = type & ~(SOCK_NONBLOCK|SOCK_CLOEXEC);
    sock2->protocol     = protocol;
    sock2->sock_state   = SOCK_CONNECTED;

    if ((ret = create_pipes(&sock1->addr.un.pipeid, &hdl1->pal_handle,
                            &hdl2->pal_handle, &hdl1->uri,
                            type & SOCK_NONBLOCK ? O_NONBLOCK : 0)) < 0)
        goto out;

    sock2->addr.un.pipeid = sock1->addr.un.pipeid;
    qstrcopy(&hdl2->uri, &hdl1->uri);

    int flags = type & SOCK_CLOEXEC ? FD_CLOEXEC : 0;
    int vfd1 = set_new_fd_handle(hdl1, flags, NULL);
    int vfd2 = set_new_fd_handle(hdl2, flags, NULL);

    if (vfd1 < 0 || vfd2 < 0) {
        if (vfd1 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd1, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        if (vfd2 >= 0) {
            struct shim_handle * tmp = detach_fd_handle(vfd2, NULL, NULL);
            if (tmp)
                close_handle(tmp);
        }
        goto out;
    }

    sv[0] = vfd1;
    sv[1] = vfd2;
out:
    if (hdl1)
        put_handle(hdl1);
    if (hdl2)
        put_handle(hdl2);
    return ret;
}