Modified most (but not yet all) I/O to always go through sys.stdout or
sys.stderr or sys.stdin, and to work with any object as long as it has
a write() (respectively readline()) methods.  Some functions that took
a FILE* argument now take an object* argument.
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 2f46931..9ba07af 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -308,28 +308,19 @@
 	return (*nb->nb_hex)(v);
 }
 
+static object *builtin_raw_input PROTO((object *, object *));
+
 static object *
 builtin_input(self, v)
 	object *self;
 	object *v;
 {
-	FILE *in = sysgetfile("stdin", stdin);
-	FILE *out = sysgetfile("stdout", stdout);
-	int c;
-	object *m, *d;
-	flushline();
-	if (v != NULL) {
-		if (printobject(v, out, PRINT_RAW) != 0)
-			return NULL;
-	}
-	m = add_module("__main__");
-	d = getmoduledict(m);
-	BGN_SAVE
-	while ((c = getc(in)) != EOF && (c == ' ' || c == '\t'))
-		;
-	ungetc(c, in);
-	END_SAVE
-	return run_file(in, "<stdin>", expr_input, d, d);
+	object *line = builtin_raw_input(self, v);
+	if (line == NULL)
+		return line;
+	v = exec_eval(line, eval_input);
+	DECREF(line);
+	return v;
 }
 
 static object *
@@ -578,10 +569,14 @@
 	object *self;
 	object *v;
 {
-	FILE *out = sysgetfile("stdout", stdout);
+	object *f = sysget("stdout");
+	if (f == NULL) {
+		err_setstr(RuntimeError, "lost sys.stdout");
+		return NULL;
+	}
 	flushline();
 	if (v != NULL) {
-		if (printobject(v, out, PRINT_RAW) != 0)
+		if (writeobject(v, f, PRINT_RAW) != 0)
 			return NULL;
 	}
 	return filegetline(sysget("stdin"), -1);
diff --git a/Python/ceval.c b/Python/ceval.c
index 469068e..4637d35 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -176,7 +176,6 @@
 	object *trace = NULL;	/* Trace function or NULL */
 	object *retval;		/* Return value iff why == WHY_RETURN */
 	char *name;		/* Name used by some instructions */
-	FILE *fp;		/* Used by print operations */
 #ifdef LLTRACE
 	int lltrace = dictlookup(globals, "__lltrace__") != NULL;
 #endif
@@ -598,12 +597,12 @@
 		
 		case PRINT_EXPR:
 			v = POP();
-			fp = sysgetfile("stdout", stdout);
 			/* Print value except if procedure result */
 			if (v != None) {
 				flushline();
-				softspace(sysget("stdout"), 1);
-				err = printobject(v, fp, 0);
+				x = sysget("stdout");
+				softspace(x, 1);
+				err = writeobject(v, x, 0);
 				flushline();
 			}
 			DECREF(v);
@@ -611,30 +610,30 @@
 		
 		case PRINT_ITEM:
 			v = POP();
-			fp = sysgetfile("stdout", stdout);
-			if (softspace(sysget("stdout"), 1))
-				fprintf(fp, " ");
+			w = sysget("stdout");
+			if (softspace(w, 1))
+				writestring(" ", w);
 			if (is_stringobject(v)) {
 				char *s = getstringvalue(v);
 				int len = getstringsize(v);
-				fwrite(s, 1, len, fp);
-				if (ferror(fp)) {
-					err_errno(IOError);
-					err = -1;
-				}
-				else if (len > 0 && s[len-1] == '\n')
-					softspace(sysget("stdout"), 0);
+				err = writeobject(v, w, PRINT_RAW);
+				if (err == 0 && len > 0 && s[len-1] == '\n')
+					softspace(w, 0);
 			}
 			else {
-				err = printobject(v, fp, 0);
+				err = writeobject(v, w, 0);
 			}
 			DECREF(v);
 			break;
 		
 		case PRINT_NEWLINE:
-			fp = sysgetfile("stdout", stdout);
-			fprintf(fp, "\n");
-			softspace(sysget("stdout"), 0);
+			x = sysget("stdout");
+			if (x == NULL)
+				err_setstr(RuntimeError, "lost sys.stdout");
+			else {
+				writestring("\n", x);
+				softspace(x, 0);
+			}
 			break;
 		
 		case BREAK_LOOP:
@@ -1395,13 +1394,13 @@
 }
 
 void
-printtraceback(fp)
-	FILE *fp;
+printtraceback(f)
+	object *f;
 {
 	object *v = tb_fetch();
 	if (v != NULL) {
-		fprintf(fp, "Stack backtrace (innermost last):\n");
-		tb_print(v, fp);
+		writestring("Stack backtrace (innermost last):\n", f);
+		tb_print(v, f);
 		DECREF(v);
 	}
 }
@@ -1410,8 +1409,9 @@
 void
 flushline()
 {
-	if (softspace(sysget("stdout"), 0))
-		fprintf(sysgetfile("stdout", stdout), "\n");
+	object *f = sysget("stdout");
+	if (softspace(f, 0))
+		writestring("\n", f);
 }
 
 
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 35b1815..90a4294 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -214,7 +214,7 @@
 void
 print_error()
 {
-	object *exception, *v;
+	object *exception, *v, *f;
 	err_get(&exception, &v);
 	if (exception == SystemExit) {
 		if (v == NULL || v == None)
@@ -222,6 +222,7 @@
 		if (is_intobject(v))
 			goaway((int)getintvalue(v));
 		else {
+			/* OK to use real stderr here */
 			printobject(v, stderr, PRINT_RAW);
 			fprintf(stderr, "\n");
 			goaway(1);
@@ -229,17 +230,22 @@
 	}
 	sysset("last_type", exception);
 	sysset("last_value", v);
-	if (printobject(exception, stderr, PRINT_RAW) != 0)
-		err_clear();
-	if (v != NULL && v != None) {
-		fprintf(stderr, ": ");
-		if (printobject(v, stderr, PRINT_RAW) != 0)
+	f = sysget("stderr");
+	if (f == NULL)
+		fprintf(stderr, "lost sys.stderr\n");
+	else {
+		if (writeobject(exception, f, PRINT_RAW) != 0)
 			err_clear();
+		if (v != NULL && v != None) {
+			writestring(": ", f);
+			if (writeobject(v, f, PRINT_RAW) != 0)
+				err_clear();
+		}
+		writestring("\n", f);
+		printtraceback(f);
 	}
-	fprintf(stderr, "\n");
 	XDECREF(exception);
 	XDECREF(v);
-	printtraceback(stderr);
 }
 
 object *
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index a83ec46..5dff38e 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -62,7 +62,7 @@
 {
 	FILE *fp = NULL;
 	object *v = sysget(name);
-	if (v != NULL)
+	if (v != NULL && is_fileobject(v))
 		fp = getfilefile(v);
 	if (fp == NULL)
 		fp = def;
diff --git a/Python/traceback.c b/Python/traceback.c
index bcd2f76..3c246b5 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -150,8 +150,8 @@
 }
 
 static void
-tb_displayline(fp, filename, lineno)
-	FILE *fp;
+tb_displayline(f, filename, lineno)
+	object *f;
 	char *filename;
 	int lineno;
 {
@@ -189,15 +189,17 @@
 			}
 		}
 	}
-	fprintf(fp, "  File \"%s\"", filename);
+	sprintf(linebuf, "  File \"%.900s\"%s line %d\n",
+		filename,
 #ifdef applec /* MPW */
-	/* This is needed by MPW's File and Line commands */
-	fprintf(fp, "; ");
+		/* This is needed by MPW's File and Line commands */
+		";",
 #else
-	/* This is needed by Emacs' compile command */
-	fprintf(fp, ", ");
+		/* This is needed by Emacs' compile command */
+		",",
 #endif
-	fprintf(fp, "line %d\n", lineno);
+		lineno);
+	writestring(linebuf, f);
 	if (xfp == NULL)
 		return;
 	for (i = 0; i < lineno; i++) {
@@ -208,20 +210,21 @@
 		char *p = linebuf;
 		while (*p == ' ' || *p == '\t')
 			p++;
-		fprintf(fp, "    %s", p);
+		writestring("    ", f);
+		writestring(p, f);
 		if (strchr(p, '\n') == NULL)
-			fprintf(fp, "\n");
+			writestring("\n", f);
 	}
 	fclose(xfp);
 }
 
 static void
-tb_printinternal(tb, fp)
+tb_printinternal(tb, f)
 	tracebackobject *tb;
-	FILE *fp;
+	object *f;
 {
 	while (tb != NULL && !intrcheck()) {
-		tb_displayline(fp,
+		tb_displayline(f,
 		     getstringvalue(tb->tb_frame->f_code->co_filename),
 							tb->tb_lineno);
 		tb = tb->tb_next;
@@ -229,9 +232,9 @@
 }
 
 int
-tb_print(v, fp)
+tb_print(v, f)
 	object *v;
-	FILE *fp;
+	object *f;
 {
 	if (v == NULL)
 		return 0;
@@ -240,6 +243,6 @@
 		return -1;
 	}
 	sysset("last_traceback", v);
-	tb_printinternal((tracebackobject *)v, fp);
+	tb_printinternal((tracebackobject *)v, f);
 	return 0;
 }