Loading fs/exec.c +6 −35 Original line number Diff line number Diff line Loading @@ -1006,40 +1006,6 @@ static int de_thread(struct task_struct *tsk) return 0; } /* * These functions flushes out all traces of the currently running executable * so that a new one can be started */ static void flush_old_files(struct files_struct * files) { long j = -1; struct fdtable *fdt; spin_lock(&files->file_lock); for (;;) { unsigned long set, i; j++; i = j * BITS_PER_LONG; fdt = files_fdtable(files); if (i >= fdt->max_fds) break; set = fdt->close_on_exec[j]; if (!set) continue; fdt->close_on_exec[j] = 0; spin_unlock(&files->file_lock); for ( ; set ; i++,set >>= 1) { if (set & 1) { sys_close(i); } } spin_lock(&files->file_lock); } spin_unlock(&files->file_lock); } char *get_task_comm(char *buf, struct task_struct *tsk) { /* buf must be at least sizeof(tsk->comm) in size */ Loading @@ -1050,6 +1016,11 @@ char *get_task_comm(char *buf, struct task_struct *tsk) } EXPORT_SYMBOL_GPL(get_task_comm); /* * These functions flushes out all traces of the currently running executable * so that a new one can be started */ void set_task_comm(struct task_struct *tsk, char *buf) { task_lock(tsk); Loading Loading @@ -1171,7 +1142,7 @@ void setup_new_exec(struct linux_binprm * bprm) current->self_exec_id++; flush_signal_handlers(current, 0); flush_old_files(current->files); do_close_on_exec(current->files); } EXPORT_SYMBOL(setup_new_exec); Loading fs/file.c +37 −0 Original line number Diff line number Diff line Loading @@ -652,6 +652,43 @@ int __close_fd(struct files_struct *files, unsigned fd) return -EBADF; } void do_close_on_exec(struct files_struct *files) { unsigned i; struct fdtable *fdt; /* exec unshares first */ BUG_ON(atomic_read(&files->count) != 1); spin_lock(&files->file_lock); for (i = 0; ; i++) { unsigned long set; unsigned fd = i * BITS_PER_LONG; fdt = files_fdtable(files); if (fd >= fdt->max_fds) break; set = fdt->close_on_exec[i]; if (!set) continue; fdt->close_on_exec[i] = 0; for ( ; set ; fd++, set >>= 1) { struct file *file; if (!(set & 1)) continue; file = fdt->fd[fd]; if (!file) continue; rcu_assign_pointer(fdt->fd[fd], NULL); __put_unused_fd(files, fd); spin_unlock(&files->file_lock); filp_close(file, files); cond_resched(); spin_lock(&files->file_lock); } } spin_unlock(&files->file_lock); } struct file *fget(unsigned int fd) { struct file *file; Loading include/linux/fdtable.h +1 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ void put_files_struct(struct files_struct *fs); void reset_files_struct(struct files_struct *); int unshare_files(struct files_struct **); struct files_struct *dup_fd(struct files_struct *, int *); void do_close_on_exec(struct files_struct *); extern int __alloc_fd(struct files_struct *files, unsigned start, unsigned end, unsigned flags); Loading Loading
fs/exec.c +6 −35 Original line number Diff line number Diff line Loading @@ -1006,40 +1006,6 @@ static int de_thread(struct task_struct *tsk) return 0; } /* * These functions flushes out all traces of the currently running executable * so that a new one can be started */ static void flush_old_files(struct files_struct * files) { long j = -1; struct fdtable *fdt; spin_lock(&files->file_lock); for (;;) { unsigned long set, i; j++; i = j * BITS_PER_LONG; fdt = files_fdtable(files); if (i >= fdt->max_fds) break; set = fdt->close_on_exec[j]; if (!set) continue; fdt->close_on_exec[j] = 0; spin_unlock(&files->file_lock); for ( ; set ; i++,set >>= 1) { if (set & 1) { sys_close(i); } } spin_lock(&files->file_lock); } spin_unlock(&files->file_lock); } char *get_task_comm(char *buf, struct task_struct *tsk) { /* buf must be at least sizeof(tsk->comm) in size */ Loading @@ -1050,6 +1016,11 @@ char *get_task_comm(char *buf, struct task_struct *tsk) } EXPORT_SYMBOL_GPL(get_task_comm); /* * These functions flushes out all traces of the currently running executable * so that a new one can be started */ void set_task_comm(struct task_struct *tsk, char *buf) { task_lock(tsk); Loading Loading @@ -1171,7 +1142,7 @@ void setup_new_exec(struct linux_binprm * bprm) current->self_exec_id++; flush_signal_handlers(current, 0); flush_old_files(current->files); do_close_on_exec(current->files); } EXPORT_SYMBOL(setup_new_exec); Loading
fs/file.c +37 −0 Original line number Diff line number Diff line Loading @@ -652,6 +652,43 @@ int __close_fd(struct files_struct *files, unsigned fd) return -EBADF; } void do_close_on_exec(struct files_struct *files) { unsigned i; struct fdtable *fdt; /* exec unshares first */ BUG_ON(atomic_read(&files->count) != 1); spin_lock(&files->file_lock); for (i = 0; ; i++) { unsigned long set; unsigned fd = i * BITS_PER_LONG; fdt = files_fdtable(files); if (fd >= fdt->max_fds) break; set = fdt->close_on_exec[i]; if (!set) continue; fdt->close_on_exec[i] = 0; for ( ; set ; fd++, set >>= 1) { struct file *file; if (!(set & 1)) continue; file = fdt->fd[fd]; if (!file) continue; rcu_assign_pointer(fdt->fd[fd], NULL); __put_unused_fd(files, fd); spin_unlock(&files->file_lock); filp_close(file, files); cond_resched(); spin_lock(&files->file_lock); } } spin_unlock(&files->file_lock); } struct file *fget(unsigned int fd) { struct file *file; Loading
include/linux/fdtable.h +1 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ void put_files_struct(struct files_struct *fs); void reset_files_struct(struct files_struct *); int unshare_files(struct files_struct **); struct files_struct *dup_fd(struct files_struct *, int *); void do_close_on_exec(struct files_struct *); extern int __alloc_fd(struct files_struct *files, unsigned start, unsigned end, unsigned flags); Loading