|
@@ -110,7 +110,7 @@ out:
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
-static int dupfd(struct file *file, unsigned int start)
|
|
|
|
|
|
+static int dupfd(struct file *file, unsigned int start, int cloexec)
|
|
{
|
|
{
|
|
struct files_struct * files = current->files;
|
|
struct files_struct * files = current->files;
|
|
struct fdtable *fdt;
|
|
struct fdtable *fdt;
|
|
@@ -122,7 +122,10 @@ static int dupfd(struct file *file, unsigned int start)
|
|
/* locate_fd() may have expanded fdtable, load the ptr */
|
|
/* locate_fd() may have expanded fdtable, load the ptr */
|
|
fdt = files_fdtable(files);
|
|
fdt = files_fdtable(files);
|
|
FD_SET(fd, fdt->open_fds);
|
|
FD_SET(fd, fdt->open_fds);
|
|
- FD_CLR(fd, fdt->close_on_exec);
|
|
|
|
|
|
+ if (cloexec)
|
|
|
|
+ FD_SET(fd, fdt->close_on_exec);
|
|
|
|
+ else
|
|
|
|
+ FD_CLR(fd, fdt->close_on_exec);
|
|
spin_unlock(&files->file_lock);
|
|
spin_unlock(&files->file_lock);
|
|
fd_install(fd, file);
|
|
fd_install(fd, file);
|
|
} else {
|
|
} else {
|
|
@@ -195,7 +198,7 @@ asmlinkage long sys_dup(unsigned int fildes)
|
|
struct file * file = fget(fildes);
|
|
struct file * file = fget(fildes);
|
|
|
|
|
|
if (file)
|
|
if (file)
|
|
- ret = dupfd(file, 0);
|
|
|
|
|
|
+ ret = dupfd(file, 0, 0);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -319,8 +322,9 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
|
|
|
|
|
|
switch (cmd) {
|
|
switch (cmd) {
|
|
case F_DUPFD:
|
|
case F_DUPFD:
|
|
|
|
+ case F_DUPFD_CLOEXEC:
|
|
get_file(filp);
|
|
get_file(filp);
|
|
- err = dupfd(filp, arg);
|
|
|
|
|
|
+ err = dupfd(filp, arg, cmd == F_DUPFD_CLOEXEC);
|
|
break;
|
|
break;
|
|
case F_GETFD:
|
|
case F_GETFD:
|
|
err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
|
|
err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
|