예제 #1
0
/* Install a given filp in a given files_struct, with CLOEXEC set.
 * Safe for files != current->files.
 * Mostly cut-and-paste from linux-2.6.0/fs/fcntl.c:locate_fd()
 */
int cr_dup_other(struct files_struct *files, struct file *filp)
{
    unsigned int newfd;
    unsigned int start;
    unsigned int max_fds;
    int error;
    cr_fdtable_t *fdt;

    spin_lock(&files->file_lock);

repeat: 
    fdt = cr_fdtable(files);
    start = CR_NEXT_FD(files, fdt);
    newfd = start;
    max_fds = CR_MAX_FDS(fdt);
    if (start < max_fds) {
	newfd = find_next_zero_bit(CR_OPEN_FDS_BITS(fdt),
				   max_fds, start);
    }

    /* XXX: Really shouldn't be using current here.
     * However, I haven't bothered to figure out the locking
     * requirements for using anything else.
     * XXX: Probably could just pass the limit in.
     * XXX: Later kernels push this into expand_files()
     */
    error = -EMFILE;
    if (newfd >= CR_RLIM(current)[RLIMIT_NOFILE].rlim_cur) {
	goto out;
    }

    error = expand_files(files, newfd);
    if (error < 0) {
	goto out;
    } else if (error) {
	/* grew - search again (also reacquires fdt) */
	goto repeat;
    }

    CR_NEXT_FD(files, fdt) = newfd + 1;

    /* Claim */
    cr_set_open_fd(newfd, fdt);
    cr_set_close_on_exec(newfd, fdt);

    /* Install */
    get_file(filp);
    rcu_assign_pointer(fdt->fd[newfd], filp);

    error = newfd;
    
out:
    spin_unlock(&files->file_lock);
    return error;
}
예제 #2
0
/*
 * cr_fd_claim
 *
 * Atomically checks and claims an fd
 *
 * returns < 0 on conflict w/ an existing fd
 */
int
cr_fd_claim(int fd)
{
    cr_fdtable_t *fdt;
    int retval;

    /* Mark the fd in use */
    spin_lock(&current->files->file_lock);
    fdt = cr_fdtable(current->files);
    if (FD_ISSET(fd, fdt->open_fds)) {
	retval = -EBUSY;
    } else {
	retval = 0;
	FD_SET(fd, fdt->open_fds);
	FD_CLR(fd, fdt->close_on_exec);
    }
    spin_unlock(&current->files->file_lock);

    return retval;
}
예제 #3
0
/*
 * cr_fd_claim
 *
 * Atomically checks and claims an fd
 *
 * returns < 0 on conflict w/ an existing fd
 */
int
cr_fd_claim(int fd)
{
    cr_fdtable_t *fdt;
    int retval;

    /* Mark the fd in use */
    spin_lock(&current->files->file_lock);
    fdt = cr_fdtable(current->files);
    if (cr_read_open_fd(fd, fdt)) {
	retval = -EBUSY;
    } else {
	retval = 0;
	cr_set_open_fd(fd, fdt);
	cr_clear_close_on_exec(fd, fdt);
    }
    spin_unlock(&current->files->file_lock);

    return retval;
}