patch-2.1.60 linux/fs/exec.c
Next file: linux/fs/ext2/dir.c
Previous file: linux/fs/dcache.c
Back to the patch index
Back to the overall index
- Lines: 101
- Date:
Tue Oct 21 08:57:29 1997
- Orig file:
v2.1.59/linux/fs/exec.c
- Orig date:
Tue Sep 23 16:48:48 1997
diff -u --recursive --new-file v2.1.59/linux/fs/exec.c linux/fs/exec.c
@@ -372,13 +372,13 @@
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)
@@ -427,16 +427,34 @@
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
*/
@@ -476,18 +494,24 @@
}
}
-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;
@@ -509,8 +533,12 @@
flush_old_signals(current->sig);
flush_old_files(current->files);
-out:
- return; /* retval; FIXME. */
+
+ return 0;
+
+flush_failed:
+ current->sig = oldsig;
+ return retval;
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov