Пример #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;
}
Пример #2
0
int shim_do_close (int fd)
{
    struct shim_handle * handle = detach_fd_handle(fd, NULL, NULL);
    if (!handle)
        return -EBADF;

    close_handle(handle);
    return 0;
}
Пример #3
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;
}