예제 #1
0
int close(int fd)
{
    int ret;
    struct fdtab_entry *e = fdtab_get(fd);
    if (e->type == FDTAB_TYPE_AVAILABLE) {
        return -1;
    }

    if (e->type == FDTAB_TYPE_LWIP_SOCKET) {
        if(e->inherited) {
            // Perform shallow close on lwip so that it will not terminate
            // the TCP session
            printf("close: Inherited socket, not closing completely\n");
            ret = 0;
        } else {
            ret = lwip_close(e->fd);
            if(ret < 0) {
                POSIXCOMPAT_DEBUG("[%d]error in lwip_close\n",
                        disp_get_domain_id());
                return -1;
            }
        }
        fdtab_free(fd);
    } else {
        ret = vfsfd_close(fd);
    }

    return ret;
}
예제 #2
0
파일: close.c 프로젝트: huiweics/arrakis
int close(int fd)
{
    int ret;
    struct fdtab_entry *e = fdtab_get(fd);
    if (e->type == FDTAB_TYPE_AVAILABLE) {
        return -1;
    }

    // Might need to remove from epoll list
    if(e->epoll_fd != -1) {
        ret = epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, fd, NULL);
        assert(ret == 0);
    }

    switch(e->type) {
    case FDTAB_TYPE_LWIP_SOCKET:
        if (e->inherited) {
            // Perform shallow close on lwip so that it will not terminate
            // the TCP session
            printf("close: Inherited socket, not closing completely\n");
            ret = 0;
        } else {
            ret = lwip_close(e->fd);
            if(ret < 0) {
                POSIXCOMPAT_DEBUG("[%d]error in lwip_close\n",
                                  disp_get_domain_id());
                return -1;
            }
        }
        fdtab_free(fd);
        break;

    case FDTAB_TYPE_PTM:
        ret = ptm_close(fd);
        break;

    case FDTAB_TYPE_PTS:
        ret = pts_close(fd);
        break;

    default:
        ret = vfsfd_close(fd);
    }

    return ret;
}
예제 #3
0
파일: vfs_fd.c 프로젝트: Karamax/arrakis
//XXX: flags are ignored...
int vfsfd_open(const char *pathname, int flags)
{
    vfs_handle_t vh;
    errval_t err;

    char *path = vfs_path_mkabs(pathname);
    assert(path != NULL);

    // If O_CREAT was given, we use vfs_create()
    if(flags & O_CREAT) {
        // If O_EXCL was also given, we check whether we can open() first
        if(flags & O_EXCL) {
            err = vfs_open(path, &vh);
            if(err_is_ok(err)) {
                vfs_close(vh);
                errno = EEXIST;
                return -1;
            }
            assert(err_no(err) == FS_ERR_NOTFOUND);
        }

        err = vfs_create(path, &vh);
    } else {
        // Regular open()
        err = vfs_open(path, &vh);
    }

    free(path);
    if (err_is_fail(err)) {
        VFSFD_DEBUG("open('%s') failed\n", pathname);

        switch(err_no(err)) {
        case FS_ERR_NOTFOUND:
            errno = ENOENT;
            break;

        default:
#ifdef VFSFD_DEBUG_ENABLED
            DEBUG_ERR(err, "vfs_open");
#endif
            break;
        }

        return -1;
    }

    struct fdtab_entry e = {
        .type = FDTAB_TYPE_FILE,
        .handle = vh,
        .epoll_fd = -1,
    };
    int fd = fdtab_alloc(&e);
    VFSFD_DEBUG("open(%s) as fd %d\n", pathname, fd);
    if (fd < 0) {
        vfs_close(vh);
        return -1;
    } else {
        return fd;
    }
}


int vfsfd_read(int fd, void *buf, size_t len)
{
    struct fdtab_entry *e = fdtab_get(fd);
    size_t retlen = 0;
    switch(e->type) {
    case FDTAB_TYPE_FILE:
        {
            errval_t err = vfs_read((vfs_handle_t)e->handle, buf, len, &retlen);
            VFSFD_DEBUG("%d : read(%d, %d) = %lu\n", disp_get_domain_id(), fd, len, retlen);
            if (err_is_fail(err)) {
                DEBUG_ERR(err, "error in vfs_read");
                return -1;
            }
        }
        break;

    case FDTAB_TYPE_STDIN:
        retlen = terminal_read((char *)buf, len);
        break;

    case FDTAB_TYPE_STDOUT:
    case FDTAB_TYPE_STDERR:
    case FDTAB_TYPE_AVAILABLE:
    default:
        return -1;
    }

    return retlen;
}

int vfsfd_write(int fd, const void *buf, size_t len)
{
    struct fdtab_entry *e = fdtab_get(fd);
    if (e->type == FDTAB_TYPE_AVAILABLE) {
        return -1;
    }

    size_t retlen = 0;

    switch(e->type) {
    case FDTAB_TYPE_FILE:
        {
            errval_t err = vfs_write((vfs_handle_t)e->handle, buf, len, &retlen);
            VFSFD_DEBUG("write(%d, %d) = %lu\n", fd, len, retlen);
            if (err_is_fail(err)) {
                DEBUG_ERR(err, "error in vfs_write");
                return -1;
            }
        }
        break;

    case FDTAB_TYPE_STDOUT:
        /* only support writting to terminal */
        retlen = terminal_write((const char*) buf, len);
        break;

    case FDTAB_TYPE_STDERR:
        retlen = terminal_write((const char*) buf, len);
        break;

    case FDTAB_TYPE_STDIN:
    case FDTAB_TYPE_AVAILABLE:
    default:
        return -1;
    }

    return retlen;
}

int vfsfd_close(int fd)
{
    errval_t err;
    struct fdtab_entry *e = fdtab_get(fd);
    if (e->type == FDTAB_TYPE_AVAILABLE) {
        return -1;
    }

    VFSFD_DEBUG("close(%d)\n", fd);

    switch(e->type) {
    case FDTAB_TYPE_FILE:
        err = vfs_close((vfs_handle_t)e->handle);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "error in vfs_close");
            return -1;
        }
        break;

    case FDTAB_TYPE_STDIN:
    case FDTAB_TYPE_STDOUT:
    case FDTAB_TYPE_STDERR:
        // XXX: Should call fclose() when closing last FD
        break;

    default:
        return -1;
    } // end switch

    fdtab_free(fd);
    return 0;
}
예제 #4
0
static errval_t get_inherited_fds(void) 
{
    errval_t err;

    /* Map the FD buffer into our address space.
     * It stays there since the FD data structures will remain in there and be 
     * referenced from the FD table.
     */
    struct capref frame = {
        .cnode = cnode_task,
        .slot = TASKCN_SLOT_FDSPAGE,
    };

    void *fdspg;
    err = vspace_map_one_frame(&fdspg, FDS_SIZE, frame, NULL, NULL);
    if (err_is_fail(err)) {
        return err_push(err, SPAWN_ERR_MAP_FDSPG_TO_SELF);
    }

    /* Set up to read the table */
    char *p = fdspg;
    printf("fds at: %p\n", p);

    int num_fds = *((int*)p);
    printf("num fds: %d\n", num_fds);

    struct fd_store *fd;
    p += sizeof(int);
    fd = (struct fd_store*)p;
    p += (sizeof(struct fd_store)*num_fds);

    /* Process all the FDs passed in the buffer */
    int i;
    for (i = 0; i < num_fds; i++, fd++) {

        /* add each to our fd table - replacing any fds already there */
        struct fdtab_entry fde;
        fde.type = fd->type;
        fde.handle = fd->handle;

        if (fdtab_get(fd->num)->type != FDTAB_TYPE_AVAILABLE) {
            fdtab_free(fd->num);
        }
        fdtab_alloc_from(&fde, fd->num);

        /* print out some info about the FD */

        char *s = "";
        switch (fd->type) {
        case FDTAB_TYPE_AVAILABLE:
            s = "available";
            break;
        case FDTAB_TYPE_FILE:
            s = "file";
            break;
        case FDTAB_TYPE_UNIX_SOCKET:
            s = "unix socket";
            break;
        case FDTAB_TYPE_STDIN:
            s = "stdin";
            break;
        case FDTAB_TYPE_STDOUT:
            s = "stdout";
            break;
        case FDTAB_TYPE_STDERR:
            s = "stderr";
            break;
        case FDTAB_TYPE_LWIP_SOCKET:
            s = "lwip socket";
            break;
        case FDTAB_TYPE_EPOLL_INSTANCE:
            s = "epoll instance";
            break;
        case FDTAB_TYPE_PTM:
            s = "pseudo-terminal master";
            break;
        case FDTAB_TYPE_PTS:
            s = "pseudo-terminal slave";
            break;
        }
        printf("fd_store %d: num: %d, type: %d:%s handle: %p\n", 
               i, fd->num, fd->type, s, fd->handle);

        switch (fd->type) {
        case FDTAB_TYPE_FILE:
            print_file_fd((void*)(p + (genpaddr_t)fd->handle));
            break;
        case FDTAB_TYPE_UNIX_SOCKET:
            print_unixsock_fd((void*)(p + (genpaddr_t)fd->handle));
            break;
        default:
            printf("[no handle data]\n");
            break;
        }

    }

    return SYS_ERR_OK;

}