diff -u --recursive --new-files pl12/linux/config.in linux/config.in
--- pl12/linux/config.in	Sun Aug 15 11:24:56 1993
+++ linux/config.in	Sat Aug 21 10:51:27 1993
@@ -13,6 +13,10 @@
 bool 'System V IPC' CONFIG_SYSVIPC y
 bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y
 *
+* Program binary formats
+*
+bool 'Elf executables' CONFIG_BINFMT_ELF y
+*
 * SCSI support
 *
 bool 'SCSI support?' CONFIG_SCSI n
diff -u --recursive --new-files pl12/linux/fs/Makefile linux/fs/Makefile
--- pl12/linux/fs/Makefile	Sun Mar  7 16:21:10 1993
+++ linux/fs/Makefile	Fri Aug 20 08:59:30 1993
@@ -34,6 +34,9 @@
 FS_SUBDIRS := $(FS_SUBDIRS) xiafs
 endif
 
+ifdef CONFIG_BINFMT_ELF
+BINFMTS := $(BINFMTS) binfmt_elf.o
+endif
 
 .c.s:
 	$(CC) $(CFLAGS) -S $<
@@ -44,7 +47,7 @@
 
 OBJS=	open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \
 	block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
-	select.o fifo.o locks.o filesystems.o
+	select.o fifo.o locks.o filesystems.o $(BINFMTS)
 
 all: fs.o filesystems.a
 
diff -u --recursive --new-files pl12/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- pl12/linux/fs/binfmt_elf.c
+++ linux/fs/binfmt_elf.c	Fri Aug 20 08:59:30 1993
@@ -0,0 +1,358 @@
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/a.out.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/binfmts.h>
+#include <asm/segment.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+
+extern "C" int sys_exit(int exit_code);
+extern "C" int sys_close(unsigned fd);
+extern "C" int sys_open(const char *, int, int);
+
+/*
+ * These are the functions used to load ELF style executables and shared
+ * libraries.  There is no binary dependent code anywhere else.
+ */
+
+#include <linux/elf.h>
+
+int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+{
+	struct elfhdr elf_ex;
+	struct file * file;
+  	struct exec ex;
+	struct inode *interpreter_inode;
+	int i;
+	int old_fs;
+	int error;
+	struct elf_phdr * elf_ppnt, *elf_phdata;
+	int elf_exec_fileno;
+	unsigned int elf_bss, k, elf_brk;
+	int retval;
+	char * elf_interpreter;
+	unsigned int elf_entry;
+	int status;
+	unsigned int start_code, end_code, end_data;
+	unsigned int elf_stack;
+	char passed_fileno[6];
+	
+	status = 0;
+	elf_ex = *((struct elfhdr *) bprm->buf);	  /* exec-header */
+	
+	if (elf_ex.e_ident[0] != 0x7f ||
+	    strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
+		return  -ENOEXEC;
+	
+	
+	/* First of all, some simple consistency checks */
+	if(elf_ex.e_type != ET_EXEC || 
+	   (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
+	   (!bprm->inode->i_op || !bprm->inode->i_op->bmap || 
+	    !bprm->inode->i_op->default_file_ops->mmap)){
+		return -ENOEXEC;
+	};
+	
+	/* Now read in all of the header information */
+	
+	elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize * 
+						 elf_ex.e_phnum, GFP_KERNEL);
+	
+	old_fs = get_fs();
+	set_fs(get_ds());
+	retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
+			   elf_ex.e_phentsize * elf_ex.e_phnum);
+	set_fs(old_fs);
+	if (retval < 0)
+		return retval;
+	
+	elf_ppnt = elf_phdata;
+	
+	elf_bss = 0;
+	elf_brk = 0;
+	
+	elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
+
+	if (elf_exec_fileno < 0) return elf_exec_fileno;
+
+	file = current->filp[elf_exec_fileno];
+	
+	elf_stack = 0xffffffff;
+	elf_interpreter = NULL;
+	start_code = 0;
+	end_code = 0;
+	end_data = 0;
+	
+	old_fs = get_fs();
+	set_fs(get_ds());
+	
+	for(i=0;i < elf_ex.e_phnum; i++){
+		if(elf_ppnt->p_type == PT_INTERP) {
+			/* This is the program interpreter used for shared libraries - 
+			   for now assume that this is an a.out format binary */
+			
+			elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz, 
+							   GFP_KERNEL);
+			
+			retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
+					   elf_ppnt->p_filesz);
+			printk("Using ELF interpreter %s\n", elf_interpreter);
+			if(retval >= 0)
+				retval = namei(elf_interpreter, &interpreter_inode);
+			if(retval >= 0)
+				retval = read_exec(interpreter_inode,0,bprm->buf,128);
+			
+			if(retval >= 0){
+				ex = *((struct exec *) bprm->buf);		/* exec-header */
+				
+#if 0
+				printk("Interpreter: %x %x %x\n",N_MAGIC(ex), ex.a_text,ex.a_data);
+#endif
+			};
+		};
+		elf_ppnt++;
+	};
+	
+	set_fs(old_fs);
+	
+	/* Some simple consistency checks for the interpreter */
+	if(elf_interpreter){
+		if(retval < 0) {
+			kfree(elf_interpreter);
+			kfree(elf_phdata);
+			return -ELIBACC;
+		};
+		if((N_MAGIC(ex) != OMAGIC) && (N_MAGIC(ex) != ZMAGIC)) {
+			kfree(elf_interpreter);
+			kfree(elf_phdata);
+			return -ELIBBAD;
+		};
+	}
+	
+	/* OK, we are done with that, now set up the arg stuff,
+	   and then start this sucker up */
+	
+	if (!bprm->sh_bang) {
+		char * passed_p;
+		
+		sprintf(passed_fileno, "%d", elf_exec_fileno);
+		passed_p = passed_fileno;
+		
+		if(elf_interpreter) {
+			bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
+			bprm->argc++;
+		};
+		if (!bprm->p) {
+			return -E2BIG;
+		}
+	}
+	
+	/* OK, This is the point of no return */
+	flush_old_exec(bprm);
+
+	current->end_data = 0;
+	current->end_code = 0;
+	current->start_mmap = ELF_START_MMAP;
+	current->mmap = NULL;
+	elf_entry = (unsigned int) elf_ex.e_entry;
+	
+	/* Do this so that we can load the interpreter, if need be.  We will
+	   change some of these later */
+	current->rss = 0;
+	bprm->p += change_ldt(0, bprm->page);
+	current->start_stack = bprm->p;
+	
+	/* Now we do a little grungy work by mmaping the ELF image into
+	   the correct location in memory.  At this point, we assume that
+	   the image should be loaded at fixed address, not at a variable
+	   address. */
+	
+	old_fs = get_fs();
+	set_fs(get_ds());
+	
+	elf_ppnt = elf_phdata;
+	for(i=0;i < elf_ex.e_phnum; i++){
+		
+		if(elf_ppnt->p_type == PT_INTERP) {
+			/* Set these up so that we are able to load the interpreter */
+			current->brk = ex.a_bss +
+				(current->end_data = ex.a_data +
+				 (current->end_code = ex.a_text));
+			elf_entry = ex.a_entry;
+			
+			/* Now load the interpreter into user address space */
+			set_fs(old_fs);
+			
+			if (N_MAGIC(ex) == OMAGIC) {
+				retval = read_exec(interpreter_inode, 32, (char *) 0, 
+						   ex.a_text+ex.a_data);
+				iput(interpreter_inode);
+			} else if (N_MAGIC(ex) == ZMAGIC) {
+				retval = read_exec(interpreter_inode, 1024, (char *) 0, 
+						   ex.a_text+ex.a_data);
+				iput(interpreter_inode);
+			} else
+				retval = -1;
+			
+			old_fs = get_fs();
+			set_fs(get_ds());
+			
+			if(retval >= 0)
+				zeromap_page_range((ex.a_text + ex.a_data + 0xfff) & 
+						   0xfffff000, ex.a_bss, PAGE_COPY);
+			kfree(elf_interpreter);
+			
+			if(retval < 0) { 
+				kfree(elf_phdata);
+				send_sig(SIGSEGV, current, 0);
+				return 0;
+			};
+		};
+		
+		
+		if(elf_ppnt->p_type == PT_LOAD) {
+			error = do_mmap(file,
+					elf_ppnt->p_vaddr & 0xfffff000,
+					elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
+					PROT_READ | PROT_WRITE | PROT_EXEC,
+					MAP_FIXED | MAP_PRIVATE,
+					elf_ppnt->p_offset & 0xfffff000);
+			
+#ifdef LOW_ELF_STACK
+			if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack) 
+				elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
+#endif
+			
+			k = elf_ppnt->p_vaddr;
+			if(k > start_code) start_code = k;
+			k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
+			if(k > elf_bss) elf_bss = k;
+			if((elf_ppnt->p_flags | PROT_WRITE) && end_code <  k)
+				end_code = k; 
+			if(end_data < k) end_data = k; 
+			k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
+			if(k > elf_brk) elf_brk = k;		     
+			
+			if(status == 0xffffffff) {
+				set_fs(old_fs);
+				kfree(elf_phdata);
+				send_sig(SIGSEGV, current, 0);
+				return 0;
+			};
+		};
+		elf_ppnt++;
+	};
+	set_fs(old_fs);
+	
+	kfree(elf_phdata);
+	
+	if(!elf_interpreter) sys_close(elf_exec_fileno);
+	current->elf_executable = 1;
+	current->executable = bprm->inode;
+	bprm->inode->i_count++;
+#ifdef LOW_ELF_STACK
+	current->start_stack = p = elf_stack - 4;
+#endif
+	bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
+	bprm->p = (unsigned long) create_tables((char *)bprm->p,bprm->argc,bprm->envc);
+	if(elf_interpreter) current->arg_start += strlen(passed_fileno) + 1;
+	current->start_brk = current->brk = elf_brk;
+	current->end_code = end_code;
+	current->start_code = start_code;
+	current->start_stack = bprm->p;
+	current->suid = current->euid = bprm->e_uid;
+	current->sgid = current->egid = bprm->e_gid;
+	zeromap_page_range((elf_bss + 0xfff) & 0xfffff000, elf_brk - elf_bss,
+			   PAGE_COPY);
+	regs->eip = elf_entry;		/* eip, magic happens :-) */
+	regs->esp = bprm->p;			/* stack pointer */
+	if (current->flags & PF_PTRACED)
+		send_sig(SIGTRAP, current, 0);
+	
+	return 0;
+}
+
+
+int load_elf_library(int fd){
+        struct file * file;
+	struct elfhdr elf_ex;
+	struct elf_phdr *elf_phdata  =  NULL;
+	struct  inode * inode;
+	unsigned int len;
+	int old_fs, retval;
+	unsigned int bss;
+	int error;
+	int i,j;
+	
+	len = 0;
+	file = current->filp[fd];
+	inode = file->f_inode;
+	
+	set_fs(KERNEL_DS);
+	if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) {
+		sys_close(fd);
+		return -EACCES;
+	}
+	set_fs(USER_DS);
+	
+	if (elf_ex.e_ident[0] != 0x7f ||
+	    strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
+		return -ENOEXEC;
+	
+	/* First of all, some simple consistency checks */
+	if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
+	   (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
+	   (!inode->i_op || !inode->i_op->bmap || 
+	    !inode->i_op->default_file_ops->mmap)){
+		return -ENOEXEC;
+	};
+	
+	/* Now read in all of the header information */
+	
+	if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) 
+		return -ENOEXEC;
+	
+	elf_phdata =  (struct elf_phdr *) 
+		kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
+	
+	old_fs = get_fs();
+	set_fs(get_ds());
+	retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
+			   sizeof(struct elf_phdr) * elf_ex.e_phnum);
+	set_fs(old_fs);
+	
+	j = 0;
+	for(i=0; i<elf_ex.e_phnum; i++)
+		if((elf_phdata + i)->p_type == PT_LOAD) j++;
+	
+	if(j != 1)  {
+		kfree(elf_phdata);
+		return -ENOEXEC;
+	};
+	
+	while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
+	
+	/* Now use mmap to map the library into memory. */
+	error = do_mmap(file,
+			elf_phdata->p_vaddr & 0xfffff000,
+			elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
+			PROT_READ | PROT_WRITE | PROT_EXEC,
+			MAP_FIXED | MAP_PRIVATE,
+			elf_phdata->p_offset & 0xfffff000);
+	
+	sys_close(fd);
+	if (error != elf_phdata->p_vaddr & 0xfffff000)
+		return error;
+	len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
+	bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
+	if (bss > len)
+		zeromap_page_range(len, bss-len, PAGE_COPY);
+	kfree(elf_phdata);
+	return 0;
+}
+
diff -u --recursive --new-files pl12/linux/fs/exec.c linux/fs/exec.c
--- pl12/linux/fs/exec.c	Sun Aug 15 11:33:07 1993
+++ linux/fs/exec.c	Fri Aug 20 08:59:31 1993
@@ -50,7 +50,7 @@
 
 extern void shm_exit (void);
 
-static int open_inode(struct inode * inode, int mode)
+int open_inode(struct inode * inode, int mode)
 {
 	int error, fd;
 	struct file *f, **fpp;
@@ -316,7 +316,7 @@
  * it is expensive to load a segment register, we try to avoid calling
  * set_fs() unless we absolutely have to.
  */
-static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
+unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
 		unsigned long p, int from_kmem)
 {
 	char *tmp, *pag = NULL;
@@ -649,6 +649,7 @@
 		}
 	}
 
+	bprm.sh_bang = sh_bang;
 	fmt = formats;
 	do {
 		int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
@@ -694,9 +695,16 @@
 			    struct pt_regs * regs);
 extern int load_aout_library(int fd);
 
+extern int load_elf_binary(struct linux_binprm *,
+			    struct pt_regs * regs);
+extern int load_elf_library(int fd);
+
 /* Here are the actual binaries that will be accepted  */
 struct linux_binfmt formats[] = {
 	{load_aout_binary, load_aout_library},
+#ifdef CONFIG_BINFMT_ELF
+	{load_elf_binary, load_elf_library},
+#endif
 	{NULL, NULL}
 };
 
@@ -713,17 +721,20 @@
 	unsigned long p = bprm->p;
 
 	ex = *((struct exec *) bprm->buf);		/* exec-header */
-	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) ||
+	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && 
+	     N_MAGIC(ex) != QMAGIC) ||
 	    ex.a_trsize || ex.a_drsize ||
 	    bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
 		return -ENOEXEC;
 	}
-	if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
+
+	if (N_MAGIC(ex) == ZMAGIC &&
 	    (N_TXTOFF(ex) < bprm->inode->i_sb->s_blocksize)) {
 		printk("N_TXTOFF < BLOCK_SIZE. Please convert binary.");
 		return -ENOEXEC;
 	}
-	if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) != OMAGIC) {
+
+	if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) == ZMAGIC) {
 		printk("N_TXTOFF != BLOCK_SIZE. See a.out.h.");
 		return -ENOEXEC;
 	}
@@ -732,7 +743,10 @@
 	flush_old_exec(bprm);
 	current->start_brk = current->brk = ex.a_bss +
 		(current->end_data = ex.a_data +
-		 (current->end_code = ex.a_text));
+		 (current->end_code = N_TXTADDR(ex) + ex.a_text));
+
+	current->start_code += N_TXTADDR(ex);
+
 	current->rss = 0;
 	current->suid = current->euid = bprm->e_uid;
 	current->mmap = NULL;
@@ -751,23 +765,25 @@
 		file = current->filp[fd];
 		if (!file->f_op || !file->f_op->mmap) {
 			sys_close(fd);
-			read_exec(bprm->inode, 1024, (char *) 0, ex.a_text+ex.a_data);
+			read_exec(bprm->inode, N_TXTOFF(ex), 
+				  (char *) N_TXTADDR(ex), ex.a_text+ex.a_data);
 			goto beyond_if;
 		}
-		error = do_mmap(file, 0, ex.a_text,
+		error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
 				PROT_READ | PROT_EXEC,
 				MAP_FIXED | MAP_SHARED, N_TXTOFF(ex));
-		if (error != 0) {
+
+		if (error != N_TXTADDR(ex)) {
 			sys_close(fd);
 			send_sig(SIGSEGV, current, 0);
 			return 0;
 		};
 		
-		error = do_mmap(file, ex.a_text, ex.a_data,
+ 		error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
 				PROT_READ | PROT_WRITE | PROT_EXEC,
 				MAP_FIXED | MAP_PRIVATE, N_TXTOFF(ex) + ex.a_text);
 		sys_close(fd);
-		if (error != ex.a_text) {
+		if (error != N_TXTADDR(ex) + ex.a_text) {
 			send_sig(SIGSEGV, current, 0);
 			return 0;
 		};
@@ -818,6 +834,8 @@
 		return -ENOEXEC;
 	}
 	
+	if (N_FLAGS(ex)) return -ENOEXEC;
+
 	/* Now use mmap to map the library into memory. */
 	error = do_mmap(file, ex.a_entry, ex.a_text + ex.a_data,
 			PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
diff -u --recursive --new-files pl12/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- pl12/linux/fs/ext2/namei.c	Thu Aug 12 20:54:00 1993
+++ linux/fs/ext2/namei.c	Thu Aug 19 10:04:52 1993
@@ -937,6 +937,8 @@
 		new_inode->i_nlink--;
 		new_inode->i_dirt = 1;
 	}
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_dirt = 1;
 	old_bh->b_dirt = 1;
 	new_bh->b_dirt = 1;
 	if (dir_bh) {
diff -u --recursive --new-files pl12/linux/fs/file_table.c linux/fs/file_table.c
--- pl12/linux/fs/file_table.c	Mon Aug  9 17:41:22 1993
+++ linux/fs/file_table.c	Tue Aug 17 18:32:13 1993
@@ -45,7 +45,7 @@
 	struct file * file;
 	int i;
 
-	file = (struct file*) __get_free_page(GFP_BUFFER);
+	file = (struct file *) get_free_page(GFP_KERNEL);
 
 	if (!file)
 		return;
diff -u --recursive --new-files pl12/linux/fs/inode.c linux/fs/inode.c
--- pl12/linux/fs/inode.c	Mon Aug  9 17:41:22 1993
+++ linux/fs/inode.c	Tue Aug 17 18:41:05 1993
@@ -87,7 +87,7 @@
 	struct inode * inode;
 	int i;
 
-	if(!(inode = (struct inode*) get_free_page(GFP_KERNEL)))
+	if (!(inode = (struct inode*) get_free_page(GFP_KERNEL)))
 		return;
 
 	i=PAGE_SIZE / sizeof(struct inode);
diff -u --recursive --new-files pl12/linux/fs/namei.c linux/fs/namei.c
--- pl12/linux/fs/namei.c	Mon Aug  9 18:02:29 1993
+++ linux/fs/namei.c	Tue Aug 17 23:40:11 1993
@@ -266,7 +266,7 @@
  *
  * namei for open - this is in fact almost the whole open-routine.
  *
- * Note that the low bits of "flag" aren't the same asin the open
+ * Note that the low bits of "flag" aren't the same as in the open
  * system call - they are 00 - no permissions needed
  *			  01 - read permission needed
  *			  10 - write permission needed
@@ -376,6 +376,16 @@
 			}
  		}
  	}
+	if (flag & O_TRUNC) {
+	      inode->i_size = 0;
+	      if (inode->i_op && inode->i_op->truncate)
+	           inode->i_op->truncate(inode);
+	      if ((error = notify_change(NOTIFY_SIZE, inode))) {
+		   iput(inode);
+		   return error;
+	      }
+	      inode->i_dirt = 1;
+	}
 	*res_inode = inode;
 	return 0;
 }
diff -u --recursive --new-files pl12/linux/fs/nfs/mmap.c linux/fs/nfs/mmap.c
--- pl12/linux/fs/nfs/mmap.c	Sun Aug 15 11:46:03 1993
+++ linux/fs/nfs/mmap.c	Sat Aug 21 10:31:31 1993
@@ -50,11 +50,9 @@
 {
 	struct vm_area_struct * mpnt;
 
-	if (off & (inode->i_sb->s_blocksize - 1))
+	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported now */
 		return -EINVAL;
-	if (len > high_memory || off > high_memory - len) /* avoid overflow */
-		return -ENXIO;
-	if (get_limit(USER_DS) != TASK_SIZE)
+	if (off & (inode->i_sb->s_blocksize - 1))
 		return -EINVAL;
 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
 		return -EACCES;
@@ -79,10 +77,6 @@
 	mpnt->vm_ops = &nfs_file_mmap;
 	mpnt->vm_next = current->mmap;
 	current->mmap = mpnt;
-#if 0
-	printk("VFS: Loaded mmap at %08x - %08x\n",
-		mpnt->vm_start,	mpnt->vm_end);
-#endif
 	return 0;
 }
 
diff -u --recursive --new-files pl12/linux/fs/open.c linux/fs/open.c
--- pl12/linux/fs/open.c	Mon Aug  9 18:02:29 1993
+++ linux/fs/open.c	Tue Aug 17 23:40:11 1993
@@ -378,18 +378,7 @@
 		f->f_count--;
 		return error;
 	}
-	if (flag & O_TRUNC) {
-		inode->i_size = 0;
-		if (inode->i_op && inode->i_op->truncate)
-			inode->i_op->truncate(inode);
-		if ((error = notify_change(NOTIFY_SIZE, inode))) {
-			iput(inode);
-			current->filp[fd] = NULL;
-			f->f_count--;
-			return error;
-		}
-		inode->i_dirt = 1;
-	}
+
 	f->f_inode = inode;
 	f->f_pos = 0;
 	f->f_reada = 0;
diff -u --recursive --new-files pl12/linux/fs/proc/array.c linux/fs/proc/array.c
--- pl12/linux/fs/proc/array.c	Mon Aug  9 18:02:29 1993
+++ linux/fs/proc/array.c	Fri Aug 20 09:40:57 1993
@@ -194,7 +194,7 @@
 	if (vsize) {
 		eip = KSTK_EIP(vsize);
 		esp = KSTK_ESP(vsize);
-		vsize = (*p)->brk + PAGE_SIZE-1;
+		vsize = (*p)->brk - (*p)->start_code + PAGE_SIZE-1;
 		if (esp)
 			vsize += TASK_SIZE - esp;
 	}
@@ -264,7 +264,7 @@
 		return 0;
 	tpag = (*p)->end_code / PAGE_SIZE;
 	if ((*p)->state != TASK_ZOMBIE) {
-	  pagedir = PAGE_DIR_OFFSET((*p)->tss.cr3,(*p)->start_code);
+	  pagedir = (unsigned long *) (*p)->tss.cr3;
 	  for (i = 0; i < 0x300; ++i) {
 	    if ((ptbl = pagedir[i]) == 0) {
 	      tpag -= PTRS_PER_PAGE;
diff -u --recursive --new-files pl12/linux/include/linux/a.out.h linux/include/linux/a.out.h
--- pl12/linux/include/linux/a.out.h	Mon Aug  9 17:41:23 1993
+++ linux/include/linux/a.out.h	Fri Aug 20 08:59:31 1993
@@ -71,24 +71,26 @@
 #define NMAGIC 0410
 /* Code indicating demand-paged executable.  */
 #define ZMAGIC 0413
+/* This indicates a demand-paged executable with the header in the text. 
+   The first page is unmapped to help trap NULL pointer references */
+#define QMAGIC 0314
 
 /* Code indicating core file.  */
 #define CMAGIC 0421
+
 #if !defined (N_BADMAG)
-#define N_BADMAG(x)					\
- (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC		\
-  && N_MAGIC(x) != ZMAGIC)
+#define N_BADMAG(x)	  (N_MAGIC(x) != OMAGIC		\
+			&& N_MAGIC(x) != NMAGIC		\
+  			&& N_MAGIC(x) != ZMAGIC \
+		        && N_MAGIC(x) != QMAGIC)
 #endif
 
-#define _N_BADMAG(x)					\
- (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC		\
-  && N_MAGIC(x) != ZMAGIC)
-
 #define _N_HDROFF(x) (1024 - sizeof (struct exec))
 
 #if !defined (N_TXTOFF)
 #define N_TXTOFF(x) \
- (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec))
+ (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
+  (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
 #endif
 
 #if !defined (N_DATOFF)
@@ -113,7 +115,7 @@
 
 /* Address of text segment in memory after it is loaded.  */
 #if !defined (N_TXTADDR)
-#define N_TXTADDR(x) 0
+#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
 #endif
 
 /* Address of data segment in memory after it is loaded.
diff -u --recursive --new-files pl12/linux/include/linux/binfmts.h linux/include/linux/binfmts.h
--- pl12/linux/include/linux/binfmts.h	Fri Aug  6 13:32:00 1993
+++ linux/include/linux/binfmts.h	Fri Aug 20 08:59:31 1993
@@ -15,6 +15,7 @@
   char buf[128];
   unsigned long page[MAX_ARG_PAGES];
   unsigned long p;
+  int sh_bang;
   struct inode * inode;
   int e_uid, e_gid;
   int argc, envc;
@@ -31,6 +32,15 @@
 
 extern struct linux_binfmt formats[];
 
+extern int read_exec(struct inode *inode, unsigned long offset,
+	char * addr, unsigned long count);
 
+extern int open_inode(struct inode * inode, int mode);
+
+extern void flush_old_exec(struct linux_binprm * bprm);
+extern unsigned long change_ldt(unsigned long text_size,unsigned long * page);
+extern unsigned long * create_tables(char * p,int argc,int envc);
+extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
+		unsigned long p, int from_kmem);
 
 #endif
diff -u --recursive --new-files pl12/linux/include/linux/elf.h linux/include/linux/elf.h
--- pl12/linux/include/linux/elf.h
+++ linux/include/linux/elf.h	Fri Aug 20 08:59:31 1993
@@ -0,0 +1,306 @@
+#ifndef _ELF_H
+#define _ELF_H
+
+/* THese constants are for the segment types stored in the image headers */
+#define PT_NULL    0
+#define PT_LOAD    1
+#define PT_DYNAMIC 2
+#define PT_INTERP  3
+#define PT_NOTE    4
+#define PT_SHLIB   5
+#define PT_PHDR    6
+#define PT_LOPROC  0x70000000
+#define PT_HIPROC  0x7fffffff
+
+/* These constants define the different elf file types */
+#define ET_NONE   0
+#define ET_REL    1
+#define ET_EXEC   2
+#define ET_DYN    3
+#define ET_CORE   4
+#define ET_LOPROC 5
+#define ET_HIPROC 6
+
+/* These constants define the various ELF target machines */
+#define EM_NONE  0
+#define EM_M32   1
+#define EM_SPARC 2
+#define EM_386   3
+#define EM_68K   4
+#define EM_88K   5
+#define EM_486   6   /* Perhaps disused */
+#define EM_860   7
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH 	15
+#define DT_SYMBOLIC	16
+#define DT_REL	        17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL  0
+#define STB_GLOBAL 1
+#define STB_WEAK   2
+
+#define STT_NOTYPE  0
+#define STT_OBJECT  1
+#define STT_FUNC    2
+#define STT_SECTION 3
+#define STT_FILE    4
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+
+
+struct dynamic{
+  int d_tag;
+  union{
+    int d_val;
+    char * d_ptr;
+  } d_un;
+};
+
+/* THe following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define R_386_NONE	0
+#define R_386_32	1
+#define R_386_PC32	2
+#define R_386_GOT32	3
+#define R_386_PLT32	4
+#define R_386_COPY	5
+#define R_386_GLOB_DAT	6
+#define R_386_JMP_SLOT	7
+#define R_386_RELATIVE	8
+#define R_386_GOTOFF	9
+#define R_386_GOTPC	10
+#define R_386_NUM	11
+
+struct Elf32_Rel{
+  unsigned int * offset;
+  int info;
+};
+
+struct Elf32_Rela{
+  unsigned int * offset;
+  int info;
+  int addend;
+};
+
+struct Elf32_Sym{
+  int st_name;
+  unsigned int st_value;
+  int st_size;
+  unsigned char st_info;
+  unsigned char st_other;
+  short int st_shndx;
+};
+
+struct elfhdr{
+  char	e_ident[16];
+  short int e_type;
+  short int e_machine;
+  int   e_version;
+  char *e_entry;  /* Entry point */
+  int   e_phoff;
+  int   e_shoff;
+  int   e_flags;
+  short int e_ehsize;
+  short int e_phentsize;
+  short int e_phnum;
+  short int e_shentsize;
+  short int e_shnum;
+  short int e_shstrndx;
+};
+
+struct elf_phdr{
+  int p_type;
+  int p_offset;
+  int p_vaddr;
+  int p_paddr;
+  int p_filesz;
+  int p_memsz;
+  int p_flags;
+  int p_align;
+};
+
+#define ELF_START_MMAP 0x80000000
+
+#endif
+#ifndef _ELF_H
+#define _ELF_H
+
+/* THese constants are for the segment types stored in the image headers */
+#define PT_NULL    0
+#define PT_LOAD    1
+#define PT_DYNAMIC 2
+#define PT_INTERP  3
+#define PT_NOTE    4
+#define PT_SHLIB   5
+#define PT_PHDR    6
+#define PT_LOPROC  0x70000000
+#define PT_HIPROC  0x7fffffff
+
+/* These constants define the different elf file types */
+#define ET_NONE   0
+#define ET_REL    1
+#define ET_EXEC   2
+#define ET_DYN    3
+#define ET_CORE   4
+#define ET_LOPROC 5
+#define ET_HIPROC 6
+
+/* These constants define the various ELF target machines */
+#define EM_NONE  0
+#define EM_M32   1
+#define EM_SPARC 2
+#define EM_386   3
+#define EM_68K   4
+#define EM_88K   5
+#define EM_486   6   /* Perhaps disused */
+#define EM_860   7
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH 	15
+#define DT_SYMBOLIC	16
+#define DT_REL	        17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL  0
+#define STB_GLOBAL 1
+#define STB_WEAK   2
+
+#define STT_NOTYPE  0
+#define STT_OBJECT  1
+#define STT_FUNC    2
+#define STT_SECTION 3
+#define STT_FILE    4
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+
+
+struct dynamic{
+  int d_tag;
+  union{
+    int d_val;
+    char * d_ptr;
+  } d_un;
+};
+
+/* THe following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define R_386_NONE	0
+#define R_386_32	1
+#define R_386_PC32	2
+#define R_386_GOT32	3
+#define R_386_PLT32	4
+#define R_386_COPY	5
+#define R_386_GLOB_DAT	6
+#define R_386_JMP_SLOT	7
+#define R_386_RELATIVE	8
+#define R_386_GOTOFF	9
+#define R_386_GOTPC	10
+#define R_386_NUM	11
+
+struct Elf32_Rel{
+  unsigned int * offset;
+  int info;
+};
+
+struct Elf32_Rela{
+  unsigned int * offset;
+  int info;
+  int addend;
+};
+
+struct Elf32_Sym{
+  int st_name;
+  unsigned int st_value;
+  int st_size;
+  unsigned char st_info;
+  unsigned char st_other;
+  short int st_shndx;
+};
+
+struct elfhdr{
+  char	e_ident[16];
+  short int e_type;
+  short int e_machine;
+  int   e_version;
+  char *e_entry;  /* Entry point */
+  int   e_phoff;
+  int   e_shoff;
+  int   e_flags;
+  short int e_ehsize;
+  short int e_phentsize;
+  short int e_phnum;
+  short int e_shentsize;
+  short int e_shnum;
+  short int e_shstrndx;
+};
+
+struct elf_phdr{
+  int p_type;
+  int p_offset;
+  int p_vaddr;
+  int p_paddr;
+  int p_filesz;
+  int p_memsz;
+  int p_flags;
+  int p_align;
+};
+
+#define ELF_START_MMAP 0x80000000
+
+#endif
diff -u --recursive --new-files pl12/linux/include/linux/signal.h linux/include/linux/signal.h
--- pl12/linux/include/linux/signal.h	Thu May 20 10:34:30 1993
+++ linux/include/linux/signal.h	Mon Aug 16 18:55:12 1993
@@ -53,6 +53,9 @@
 */
 #define SIGPWR		30
 
+/* Arggh. Bad user source code wants this.. */
+#define SIGBUS		SIGUNUSED
+
 /*
  * sa_flags values: SA_STACK is not currently supported, but will allow the
  * usage of signal stacks by using the (now obsolete) sa_restorer field in
diff -u --recursive --new-files pl12/linux/include/linux/tasks.h linux/include/linux/tasks.h
--- pl12/linux/include/linux/tasks.h	Mon Jan 18 22:06:34 1993
+++ linux/include/linux/tasks.h	Wed Aug 18 23:05:21 1993
@@ -4,6 +4,6 @@
 /*
  * This is the maximum nr of tasks - change it if you need to
  */
-#define NR_TASKS	64
+#define NR_TASKS	128
 
 #endif
diff -u --recursive --new-files pl12/linux/include/linux/timer.h linux/include/linux/timer.h
--- pl12/linux/include/linux/timer.h	Sat Aug 14 23:47:22 1993
+++ linux/include/linux/timer.h	Tue Aug 17 18:39:34 1993
@@ -17,6 +17,8 @@
  * 
  * HD_TIMER		harddisk timer
  *
+ * HD_TIMER2		(atdisk2 patches)
+ *
  * FLOPPY_TIMER		floppy disk timer (not used right now)
  * 
  * SCSI_TIMER		scsi.c timeout timer
@@ -43,6 +45,8 @@
 
 #define TAPE_QIC02_TIMER	22	/* hhb */
 #define MCD_TIMER	23
+
+#define HD_TIMER2	24
 
 struct timer_struct {
 	unsigned long expires;
diff -u --recursive --new-files pl12/linux/kernel/chr_drv/keyboard.c linux/kernel/chr_drv/keyboard.c
--- pl12/linux/kernel/chr_drv/keyboard.c	Sat Aug 14 18:52:34 1993
+++ linux/kernel/chr_drv/keyboard.c	Thu Aug 19 18:45:38 1993
@@ -584,6 +584,8 @@
 		value = KVAL(K_SHIFT);
 		clr_vc_kbd_flag(kbd, VC_CAPSLOCK);
 	}
+	if (value > 3)
+		return;
 
 	if (up_flag) {
 		if (k_down[value])
diff -u --recursive --new-files pl12/linux/kernel/chr_drv/mem.c linux/kernel/chr_drv/mem.c
--- pl12/linux/kernel/chr_drv/mem.c	Mon Aug  9 18:02:32 1993
+++ linux/kernel/chr_drv/mem.c	Sat Aug 21 10:19:32 1993
@@ -129,12 +129,28 @@
 static int mmap_mem(struct inode * inode, struct file * file,
 	unsigned long addr, size_t len, int prot, unsigned long off)
 {
+	struct vm_area_struct * mpnt;
+
 	if (off & 0xfff || off + len < off)
 		return -ENXIO;
-
 	if (remap_page_range(addr, off, len, prot))
 		return -EAGAIN;
-	
+/* try to create a dummy vmm-structure so that the rest of the kernel knows we are here */
+	mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+	if (!mpnt)
+		return 0;
+
+	mpnt->vm_task = current;
+	mpnt->vm_start = addr;
+	mpnt->vm_end = addr + len;
+	mpnt->vm_page_prot = prot;
+	mpnt->vm_share = NULL;
+	mpnt->vm_inode = inode;
+	inode->i_count++;
+	mpnt->vm_offset = off;
+	mpnt->vm_ops = NULL;
+	mpnt->vm_next = current->mmap;
+	current->mmap = mpnt;
 	return 0;
 }
 
diff -u --recursive --new-files pl12/linux/kernel/chr_drv/serial.c linux/kernel/chr_drv/serial.c
--- pl12/linux/kernel/chr_drv/serial.c	Fri Aug 13 21:20:52 1993
+++ linux/kernel/chr_drv/serial.c	Wed Aug 18 01:13:23 1993
@@ -1321,12 +1321,10 @@
 	
 	switch (cmd) {
 		case TCSBRK:	/* SVID version: non-zero arg --> no break */
-			wait_until_sent(tty);
 			if (!arg)
 				send_break(info, HZ/4);	/* 1/4 second */
 			return 0;
 		case TCSBRKP:	/* support for POSIX tcsendbreak() */
-			wait_until_sent(tty);
 			send_break(info, arg ? arg*(HZ/10) : HZ/4);
 			return 0;
 		case TIOCGSOFTCAR:
diff -u --recursive --new-files pl12/linux/kernel/chr_drv/tty_ioctl.c linux/kernel/chr_drv/tty_ioctl.c
--- pl12/linux/kernel/chr_drv/tty_ioctl.c	Thu Jul 29 12:15:25 1993
+++ linux/kernel/chr_drv/tty_ioctl.c	Wed Aug 18 01:13:07 1993
@@ -605,7 +605,12 @@
 			     tty->packet = 0;
 			   return (0);
 			}
-
+		case TCSBRK: case TCSBRKP:
+			wait_until_sent(tty);
+			if (!tty->ioctl)
+				return 0;
+			tty->ioctl(tty, file, cmd, arg);
+			return 0;
 		default:
 			if (tty->ioctl) {
 				retval = (tty->ioctl)(tty, file, cmd, arg);
diff -u --recursive --new-files pl12/linux/kernel/exit.c linux/kernel/exit.c
--- pl12/linux/kernel/exit.c	Mon Aug  2 18:16:26 1993
+++ linux/kernel/exit.c	Sat Aug 21 11:14:59 1993
@@ -376,7 +376,7 @@
 		current->mmap = NULL;
 		while (mpnt) {
 			mpnt1 = mpnt->vm_next;
-			if (mpnt->vm_ops->close)
+			if (mpnt->vm_ops && mpnt->vm_ops->close)
 				mpnt->vm_ops->close(mpnt);
 			kfree(mpnt);
 			mpnt = mpnt1;
diff -u --recursive --new-files pl12/linux/kernel/signal.c linux/kernel/signal.c
--- pl12/linux/kernel/signal.c	Sun Aug 15 14:28:14 1993
+++ linux/kernel/signal.c	Sat Aug 21 10:38:00 1993
@@ -22,6 +22,31 @@
 
 extern "C" int do_signal(unsigned long oldmask, struct pt_regs * regs);
 
+struct sigcontext_struct {
+	unsigned short gs, __gsh;
+	unsigned short fs, __fsh;
+	unsigned short es, __esh;
+	unsigned short ds, __dsh;
+	unsigned long edi;
+	unsigned long esi;
+	unsigned long ebp;
+	unsigned long esp;
+	unsigned long ebx;
+	unsigned long edx;
+	unsigned long ecx;
+	unsigned long eax;
+	unsigned long trapno;
+	unsigned long err;
+	unsigned long eip;
+	unsigned short cs, __csh;
+	unsigned long eflags;
+	unsigned long esp_at_signal;
+	unsigned short ss, __ssh;
+	unsigned long i387;
+	unsigned long oldmask;
+	unsigned long cr2;
+};
+
 extern "C" int sys_sgetmask(void)
 {
 	return current->blocked;
@@ -151,15 +176,32 @@
 /*
  * This sets regs->esp even though we don't actually use sigstacks yet..
  */
-extern "C" int sys_sigreturn(unsigned long oldmask, unsigned long eip, unsigned long esp)
+extern "C" int sys_sigreturn(unsigned long __unused)
 {
+#define CHECK_SEG(x) if (x) x |= 3
+#define COPY(x) regs->x = context.x
+	struct sigcontext_struct context;
 	struct pt_regs * regs;
 
-	regs = (struct pt_regs *) &oldmask;
-	current->blocked = oldmask & _BLOCKABLE;
-	regs->eip = eip;
-	regs->esp = esp;
-	return 0;
+	regs = (struct pt_regs *) &__unused;
+	memcpy_fromfs(&context,(void *) regs->esp, sizeof(context));
+	current->blocked = context.oldmask & _BLOCKABLE;
+	CHECK_SEG(context.ss);
+	CHECK_SEG(context.cs);
+	CHECK_SEG(context.ds);
+	CHECK_SEG(context.es);
+	CHECK_SEG(context.fs);
+	CHECK_SEG(context.gs);
+	COPY(eip); COPY(eflags);
+	COPY(ecx); COPY(edx);
+	COPY(ebx);
+	COPY(esp); COPY(ebp);
+	COPY(edi); COPY(esi);
+	COPY(cs); COPY(ss);
+	COPY(ds); COPY(es);
+	COPY(fs); COPY(gs);
+	regs->orig_eax = -1;		/* disable syscall checks */
+	return context.eax;
 }
 
 /*
@@ -186,32 +228,26 @@
 	put_fs_long(regs->edi, frame+6);
 	put_fs_long(regs->esi, frame+7);
 	put_fs_long(regs->ebp, frame+8);
-	put_fs_long(regs->esp, frame+9);
+	put_fs_long((long)*fp, frame+9);
 	put_fs_long(regs->ebx, frame+10);
 	put_fs_long(regs->edx, frame+11);
 	put_fs_long(regs->ecx, frame+12);
 	put_fs_long(regs->eax, frame+13);
-	put_fs_long(0, frame+14);		/* trapno */
-	put_fs_long(0, frame+15);		/* err */
-	put_fs_long(regs->eip, frame+16);
+	put_fs_long(0, frame+14);		/* trapno - not implemented */
+	put_fs_long(0, frame+15);		/* err - not implemented */
+	put_fs_long(eip, frame+16);
 	put_fs_long(regs->cs, frame+17);
 	put_fs_long(regs->eflags, frame+18);
 	put_fs_long(regs->esp, frame+19);
 	put_fs_long(regs->ss, frame+20);
-	put_fs_long(0,frame+21);		/* 387 state pointer */
-/* linux extended stack - easier to handle.. */
-	put_fs_long(regs->eflags, frame+22);
-	put_fs_long(eip, frame+23);
+	put_fs_long(0,frame+21);		/* 387 state pointer - not implemented*/
+/* non-iBCS2 extensions.. */
+	put_fs_long(oldmask, frame+22);
+	put_fs_long(0, frame+23);		/* cr2 - not implemented */
 /* set up the return code... */
 	put_fs_long(0x0000b858, CODE(0));	/* popl %eax ; movl $,%eax */
-	put_fs_long(0x00bb0000, CODE(4));	/* movl $,%ebx */
-	put_fs_long(0xcd000000, CODE(8));	/* int $0x80 */
-	put_fs_long(0x0fa90f80, CODE(12));	/* pop %gs ; pop %fs */
-	put_fs_long(0x611f07a1, CODE(16));	/* pop %es ; pop %ds ; popad */
-	put_fs_long(0x20c48390, CODE(20));	/* nop ; addl $32,%esp */
-	put_fs_long(0x0020c29d, CODE(24));	/* popfl ; ret $32 */
-	put_fs_long(__NR_ssetmask, CODE(2));
-	put_fs_long(oldmask, CODE(7));
+	put_fs_long(0x80cd0000, CODE(4));	/* int $0x80 */
+	put_fs_long(__NR_sigreturn, CODE(2));
 	*fp = frame;
 #undef __CODE
 #undef CODE
@@ -317,8 +353,8 @@
 	frame = (unsigned long *) regs->esp;
 	signr = 1;
 	sa = current->sigaction;
-	if (regs->cs != USER_CS || regs->ss != USER_DS)
-		printk("Warning: signal handler with nonstandard code/stack segment\n");
+	if (regs->ss != USER_DS)
+		printk("Warning: signal handler with nonstandard stack segment\n");
 	for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
 		if (mask > handler_signal)
 			break;
@@ -331,6 +367,9 @@
 		__asm__("testb $0,%%fs:%0": :"m" (*(char *) sa_handler));
 		setup_frame(&frame,eip,regs,signr,sa_handler,oldmask);
 		eip = sa_handler;
+		regs->cs = USER_CS; regs->ss = USER_DS;
+		regs->ds = USER_DS; regs->es = USER_DS;
+		regs->gs = USER_DS; regs->fs = USER_DS;
 		current->blocked |= sa->sa_mask;
 		oldmask |= sa->sa_mask;
 	}
diff -u --recursive --new-files pl12/linux/mm/memory.c linux/mm/memory.c
--- pl12/linux/mm/memory.c	Sun Aug 15 11:09:18 1993
+++ linux/mm/memory.c	Sat Aug 21 10:23:07 1993
@@ -760,7 +760,7 @@
 {
 	struct task_struct ** p;
 
-	if (!inode || inode->i_count < 2)
+	if (!inode || inode->i_count < 2 || !area->vm_ops)
 		return 0;
 	for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
 		if (!*p)
@@ -773,8 +773,8 @@
 			   we can share pages with */
 			if(area){
 			  struct vm_area_struct * mpnt;
-			  for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next){
-			    if(mpnt->vm_ops && mpnt->vm_ops == area->vm_ops &&
+			  for (mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
+			    if (mpnt->vm_ops == area->vm_ops &&
 			       mpnt->vm_inode->i_ino == area->vm_inode->i_ino&&
 			       mpnt->vm_inode->i_dev == area->vm_inode->i_dev){
 			      if (mpnt->vm_ops->share(mpnt, area, address))
@@ -851,6 +851,8 @@
 			continue;
 		if (address >= ((mpnt->vm_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
 			continue;
+		if (!mpnt->vm_ops || !mpnt->vm_ops->nopage)
+			break;
 		mpnt->vm_ops->nopage(error_code, mpnt, address);
 		return;
 	}
@@ -858,7 +860,7 @@
 	get_empty_page(tsk,address);
 	if (tsk != current)
 		return;
-	if (address < tsk->brk)
+	if (address >= tsk->end_data && address < tsk->brk)
 		return;
 	if (address+8192 >= (user_esp & 0xfffff000) && 
 	    address <= current->start_stack)
diff -u --recursive --new-files pl12/linux/mm/mmap.c linux/mm/mmap.c
--- pl12/linux/mm/mmap.c	Mon Aug  9 18:02:33 1993
+++ linux/mm/mmap.c	Sat Aug 21 11:37:00 1993
@@ -52,11 +52,11 @@
 	switch (flags & MAP_TYPE) {
 	case MAP_SHARED:
 		if ((prot & PROT_WRITE) && !(file->f_mode & 2))
-			return -EINVAL;
+			return -EACCES;
 		/* fall through */
 	case MAP_PRIVATE:
 		if (!(file->f_mode & 1))
-			return -EINVAL;
+			return -EACCES;
 		break;
 
 	default:
@@ -169,7 +169,7 @@
 	while (free) {
 		mpnt = free;
 		free = free->vm_next;
-		if (mpnt->vm_ops->close)
+		if (mpnt->vm_ops && mpnt->vm_ops->close)
 			mpnt->vm_ops->close(mpnt);
 		kfree(mpnt);
 	}
@@ -197,11 +197,9 @@
 	extern struct vm_operations_struct file_mmap;
 	struct buffer_head * bh;
 
-	if (off & (inode->i_sb->s_blocksize - 1))
+	if (prot & PAGE_RW)	/* only PAGE_COW or read-only supported right now */
 		return -EINVAL;
-	if (len > high_memory || off > high_memory - len) /* avoid overflow */
-		return -ENXIO;
-	if (get_limit(USER_DS)  != TASK_SIZE)
+	if (off & (inode->i_sb->s_blocksize - 1))
 		return -EINVAL;
 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
 		return -EACCES;
@@ -231,10 +229,6 @@
 	mpnt->vm_ops = &file_mmap;
 	mpnt->vm_next = current->mmap;
 	current->mmap = mpnt;
-#if 0
-	printk("VFS: Loaded mmap at %08x -  %08x\n",
-		mpnt->vm_start,	mpnt->vm_end);
-#endif
 	return 0;
 }
 
diff -u --recursive --new-files pl12/linux/net/inet/slip.c linux/net/inet/slip.c
--- pl12/linux/net/inet/slip.c	Sat Jul 31 15:42:22 1993
+++ linux/net/inet/slip.c	Thu Aug 19 09:46:23 1993
@@ -688,7 +688,7 @@
   if (already++ == 0) {
 	printk("SLIP: version %s (%d channels): ",
 				SLIP_VERSION, SL_NRUNIT);
-
+	printk("CSLIP code copyright 1989 Regents of the University of California\n");
 	/* Fill in our LDISC request block. */
 	sl_ldisc.flags	= 0;
 	sl_ldisc.open	= slip_open;
