New posix functions open, close, dup, dup2, lseek, read, write, fstat, pipe.
Improved some comments and defaults in the Makefile.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 4e84407..2e800de 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -135,10 +135,7 @@
 
 /* Set a POSIX-specific error from errno, and return NULL */
 
-static object *
-posix_error()
-{
-	return err_errno(PosixError);
+static object * posix_error() { 	return err_errno(PosixError);
 }
 
 
@@ -207,7 +204,6 @@
 {
 	struct stat st;
 	char *path;
-	object *v;
 	int res;
 	if (!getstrarg(args, &path))
 		return NULL;
@@ -216,7 +212,7 @@
 	END_SAVE
 	if (res != 0)
 		return posix_error();
-	v = mkvalue("(llllllllll)",
+	return mkvalue("(llllllllll)",
 		    (long)st.st_mode,
 		    (long)st.st_ino,
 		    (long)st.st_dev,
@@ -664,7 +660,7 @@
 #else
 	if (setpgrp(0, 0) < 0)
 #endif
-		return err_errno(PosixError);
+		return posix_error();
 	INCREF(None);
 	return None;
 }
@@ -823,10 +819,8 @@
 		return NULL;
 	errno = 0;
 	c = times(&t);
-	if (c == (clock_t) -1) {
-		err_errno(PosixError);
-		return NULL;
-	}
+	if (c == (clock_t) -1)
+		return posix_error();
 	return mkvalue("dddd",
 		       (double)t.tms_utime / HZ,
 		       (double)t.tms_stime / HZ,
@@ -845,10 +839,8 @@
 {
 	if (!getnoarg(args))
 		return NULL;
-	if (setsid() < 0) {
-		err_errno(PosixError);
-		return NULL;
-	}
+	if (setsid() < 0)
+		return posix_error();
 	INCREF(None);
 	return None;
 }
@@ -861,10 +853,8 @@
 	int pid, pgrp;
 	if (!getargs(args, "(ii)", &pid, &pgrp))
 		return NULL;
-	if (setpgid(pid, pgrp) < 0) {
-		err_errno(PosixError);
-		return NULL;
-	}
+	if (setpgid(pid, pgrp) < 0)
+		return posix_error();
 	INCREF(None);
 	return None;
 }
@@ -878,10 +868,8 @@
 	if (!getargs(args, "i", &fd))
 		return NULL;
 	pgid = tcgetpgrp(fd);
-	if (pgid < 0) {
-		err_errno(PosixError);
-		return NULL;
-	}
+	if (pgid < 0)
+		return posix_error();
 	return newintobject((long)pgid);
 }
 
@@ -893,16 +881,221 @@
 	int fd, pgid;
 	if (!getargs(args, "(ii)", &fd, &pgid))
 		return NULL;
-	if (tcsetpgrp(fd, pgid) < 0) {
-		err_errno(PosixError);
-		return NULL;
-	}
+	if (tcsetpgrp(fd, pgid) < 0)
+		return posix_error();
        INCREF(None);
 	return None;
 }
 
 #endif /* DO_PG */
 
+/* Functions acting on file descriptors */
+
+object *
+posix_open(self, args)
+	object *self;
+	object *args;
+{
+	char *file;
+	int flag;
+	int mode = 0777;
+	int fd;
+	if (!getargs(args, "(si)", &file, &flag)) {
+		err_clear();
+		if (!getargs(args, "(sii)", &file, &flag, &mode))
+			return NULL;
+	}
+	BGN_SAVE
+	fd = open(file, flag, mode);
+	END_SAVE
+	if (fd < 0)
+		return posix_error();
+	return newintobject((long)fd);
+}
+
+object *
+posix_close(self, args)
+	object *self;
+	object *args;
+{
+	int fd, res;
+	if (!getargs(args, "i", &fd))
+		return NULL;
+	BGN_SAVE
+	res = close(fd);
+	END_SAVE
+	if (res < 0)
+		return posix_error();
+	INCREF(None);
+	return None;
+}
+
+object *
+posix_dup(self, args)
+	object *self;
+	object *args;
+{
+	int fd;
+	if (!getargs(args, "i", &fd))
+		return NULL;
+	BGN_SAVE
+	fd = dup(fd);
+	END_SAVE
+	if (fd < 0)
+		return posix_error();
+	return newintobject((long)fd);
+}
+
+object *
+posix_dup2(self, args)
+	object *self;
+	object *args;
+{
+	int fd, fd2, res;
+	if (!getargs(args, "(ii)", &fd, &fd2))
+		return NULL;
+	BGN_SAVE
+	res = dup2(fd, fd2);
+	END_SAVE
+	if (res < 0)
+		return posix_error();
+	INCREF(None);
+	return None;
+}
+
+object *
+posix_lseek(self, args)
+	object *self;
+	object *args;
+{
+	int fd, how;
+	long pos, res;
+	if (!getargs(args, "(ili)", &fd, &pos, &how))
+		return NULL;
+#ifdef SEEK_SET
+	/* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
+	switch (how) {
+	case 0: how = SEEK_SET; break;
+	case 1: how = SEEK_CUR; break;
+	case 2: how = SEEK_END; break;
+	}
+#endif
+	BGN_SAVE
+	res = lseek(fd, pos, how);
+	END_SAVE
+	if (res < 0)
+		return posix_error();
+	return newintobject(res);
+}
+
+object *
+posix_read(self, args)
+	object *self;
+	object *args;
+{
+	int fd, size;
+	object *buffer;
+	if (!getargs(args, "(ii)", &fd, &size))
+		return NULL;
+	buffer = newsizedstringobject((char *)NULL, size);
+	if (buffer == NULL)
+		return NULL;
+	BGN_SAVE
+	size = read(fd, getstringvalue(buffer), size);
+	END_SAVE
+	if (size < 0) {
+		DECREF(buffer);
+		return posix_error();
+	}
+	resizestring(&buffer, size);
+	return buffer;
+}
+
+object *
+posix_write(self, args)
+	object *self;
+	object *args;
+{
+	int fd, size;
+	char *buffer;
+	if (!getargs(args, "(is#)", &fd, &buffer, &size))
+		return NULL;
+	BGN_SAVE
+	size = write(fd, buffer, size);
+	END_SAVE
+	if (size < 0)
+		return posix_error();
+	return newintobject((long)size);
+}
+
+object *
+posix_fstat(self, args)
+	object *self;
+	object *args;
+{
+	int fd;
+	struct stat st;
+	int res;
+	if (!getargs(args, "i", &fd))
+		return NULL;
+	BGN_SAVE
+	res = fstat(fd, &st);
+	END_SAVE
+	if (res != 0)
+		return posix_error();
+	return mkvalue("(llllllllll)",
+		    (long)st.st_mode,
+		    (long)st.st_ino,
+		    (long)st.st_dev,
+		    (long)st.st_nlink,
+		    (long)st.st_uid,
+		    (long)st.st_gid,
+		    (long)st.st_size,
+		    (long)st.st_atime,
+		    (long)st.st_mtime,
+		    (long)st.st_ctime);
+}
+
+static object *
+posix_fdopen(self, args)
+	object *self;
+	object *args;
+{
+	extern int fclose PROTO((FILE *));
+	int fd;
+	char *mode;
+	FILE *fp;
+	if (!getargs(args, "(is)", &fd, &mode))
+		return NULL;
+	BGN_SAVE
+	fp = fdopen(fd, mode);
+	END_SAVE
+	if (fp == NULL)
+		return posix_error();
+	/* From now on, ignore SIGPIPE and let the error checking
+	   do the work. */
+	(void) signal(SIGPIPE, SIG_IGN);
+	return newopenfileobject(fp, "(fdopen)", mode, fclose);
+}
+
+#ifndef MSDOS
+object *
+posix_pipe(self, args)
+	object *self;
+	object *args;
+{
+	int fds[2];
+	int res;
+	if (!getargs(args, ""))
+		return NULL;
+	BGN_SAVE
+	res = pipe(fds);
+	END_SAVE
+	if (res != 0)
+		return posix_error();
+	return mkvalue("(ii)", fds[0], fds[1]);
+}
+#endif /* MSDOS */
 
 static struct methodlist posix_methods[] = {
 	{"chdir",	posix_chdir},
@@ -960,6 +1153,19 @@
 	{"tcsetpgrp",	posix_tcsetpgrp},
 #endif
 
+	{"open",	posix_open},
+	{"close",	posix_close},
+	{"dup",		posix_dup},
+	{"dup2",	posix_dup2},
+	{"lseek",	posix_lseek},
+	{"read",	posix_read},
+	{"write",	posix_write},
+	{"fstat",	posix_fstat},
+	{"fdopen",	posix_fdopen},
+#ifndef MSDOS
+	{"pipe",	posix_pipe},
+#endif
+
 	{NULL,		NULL}		 /* Sentinel */
 };