mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 06:01:23 +00:00
[PATCH] merge locate_fd() and get_unused_fd()
New primitive: alloc_fd(start, flags). get_unused_fd() and get_unused_fd_flags() become wrappers on top of it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
a1bc6eb4b4
commit
1027abe882
4 changed files with 76 additions and 129 deletions
85
fs/fcntl.c
85
fs/fcntl.c
|
@ -49,73 +49,6 @@ static int get_close_on_exec(unsigned int fd)
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* locate_fd finds a free file descriptor in the open_fds fdset,
|
||||
* expanding the fd arrays if necessary. Must be called with the
|
||||
* file_lock held for write.
|
||||
*/
|
||||
|
||||
static int locate_fd(unsigned int orig_start, int cloexec)
|
||||
{
|
||||
struct files_struct *files = current->files;
|
||||
unsigned int newfd;
|
||||
unsigned int start;
|
||||
int error;
|
||||
struct fdtable *fdt;
|
||||
|
||||
spin_lock(&files->file_lock);
|
||||
repeat:
|
||||
fdt = files_fdtable(files);
|
||||
/*
|
||||
* Someone might have closed fd's in the range
|
||||
* orig_start..fdt->next_fd
|
||||
*/
|
||||
start = orig_start;
|
||||
if (start < files->next_fd)
|
||||
start = files->next_fd;
|
||||
|
||||
newfd = start;
|
||||
if (start < fdt->max_fds)
|
||||
newfd = find_next_zero_bit(fdt->open_fds->fds_bits,
|
||||
fdt->max_fds, start);
|
||||
|
||||
error = expand_files(files, newfd);
|
||||
if (error < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If we needed to expand the fs array we
|
||||
* might have blocked - try again.
|
||||
*/
|
||||
if (error)
|
||||
goto repeat;
|
||||
|
||||
if (start <= files->next_fd)
|
||||
files->next_fd = newfd + 1;
|
||||
|
||||
FD_SET(newfd, fdt->open_fds);
|
||||
if (cloexec)
|
||||
FD_SET(newfd, fdt->close_on_exec);
|
||||
else
|
||||
FD_CLR(newfd, fdt->close_on_exec);
|
||||
error = newfd;
|
||||
|
||||
out:
|
||||
spin_unlock(&files->file_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int dupfd(struct file *file, unsigned int start, int cloexec)
|
||||
{
|
||||
int fd = locate_fd(start, cloexec);
|
||||
if (fd >= 0)
|
||||
fd_install(fd, file);
|
||||
else
|
||||
fput(file);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
|
||||
{
|
||||
int err = -EBADF;
|
||||
|
@ -194,10 +127,15 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
|
|||
asmlinkage long sys_dup(unsigned int fildes)
|
||||
{
|
||||
int ret = -EBADF;
|
||||
struct file * file = fget(fildes);
|
||||
struct file *file = fget(fildes);
|
||||
|
||||
if (file)
|
||||
ret = dupfd(file, 0, 0);
|
||||
if (file) {
|
||||
ret = get_unused_fd();
|
||||
if (ret >= 0)
|
||||
fd_install(ret, file);
|
||||
else
|
||||
fput(file);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -322,8 +260,11 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
|
|||
case F_DUPFD_CLOEXEC:
|
||||
if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
|
||||
break;
|
||||
get_file(filp);
|
||||
err = dupfd(filp, arg, cmd == F_DUPFD_CLOEXEC);
|
||||
err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
|
||||
if (err >= 0) {
|
||||
get_file(filp);
|
||||
fd_install(err, filp);
|
||||
}
|
||||
break;
|
||||
case F_GETFD:
|
||||
err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue