diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
commit | 230e5ab6a084ed50470f101934782dbf54b0d06b (patch) | |
tree | 5dd821c8d33f450470588e7a543f74bf74306e9e /fs/exec.c | |
parent | c9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff) |
Merge with Linux 2.1.67.
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 56 |
1 files changed, 42 insertions, 14 deletions
@@ -376,13 +376,13 @@ int read_exec(struct dentry *dentry, unsigned long offset, if (to_kmem) { unsigned long old_fs = get_fs(); set_fs(get_ds()); - result = file.f_op->read(inode, &file, addr, count); + result = file.f_op->read(&file, addr, count, &file.f_pos); set_fs(old_fs); } else { result = verify_area(VERIFY_WRITE, addr, count); if (result) goto close_readexec; - result = file.f_op->read(inode, &file, addr, count); + result = file.f_op->read(&file, addr, count, &file.f_pos); } close_readexec: if (file.f_op->release) @@ -431,16 +431,34 @@ fail_restore: current->mm = old_mm; mmput(mm); - /* - * N.B. binfmt_xxx needs to handle the error instead of oom() - */ fail_nomem: - /* this is wrong, I think. */ - oom(current); return retval; } /* + * This function makes sure the current process has its own signal table, + * so that flush_old_signals can later reset the signals without disturbing + * other processes. (Other processes might share the signal table via + * the CLONE_SIGHAND option to clone().) + */ + +static inline int make_private_signals(void) +{ + struct signal_struct * newsig; + + if (atomic_read(¤t->sig->count) <= 1) + return 0; + newsig = kmalloc(sizeof(*newsig), GFP_KERNEL); + if (newsig == NULL) + return -ENOMEM; + spin_lock_init(&newsig->siglock); + atomic_set(&newsig->count, 1); + memcpy(newsig->action, current->sig->action, sizeof(newsig->action)); + current->sig = newsig; + return 0; +} + +/* * These functions flushes out all traces of the currently running executable * so that a new one can be started */ @@ -480,18 +498,24 @@ static inline void flush_old_files(struct files_struct * files) } } -void flush_old_exec(struct linux_binprm * bprm) +int flush_old_exec(struct linux_binprm * bprm) { char * name; int i, ch, retval; + struct signal_struct * oldsig; + + /* + * Make sure we have a private signal table + */ + oldsig = current->sig; + retval = make_private_signals(); + if (retval) goto flush_failed; /* - * Release all of the old mmap stuff ... do this first - * so we can bail out on failure. + * Release all of the old mmap stuff */ retval = exec_mmap(); - if (retval) - goto out; + if (retval) goto flush_failed; if (current->euid == current->uid && current->egid == current->gid) current->dumpable = 1; @@ -513,8 +537,12 @@ void flush_old_exec(struct linux_binprm * bprm) flush_old_signals(current->sig); flush_old_files(current->files); -out: - return; /* retval; FIXME. */ + + return 0; + +flush_failed: + current->sig = oldsig; + return retval; } /* |