sysmodule.c revision 2a47c0fa23a3b84d767ee846f93f98aee7e2f5c3
1
2/* System module */
3
4/*
5Various bits of information used by the interpreter are collected in
6module 'sys'.
7Function member:
8- exit(sts): raise SystemExit
9Data members:
10- stdin, stdout, stderr: standard file objects
11- modules: the table of modules (dictionary)
12- path: module search path (list of strings)
13- argv: script arguments (list of strings)
14- ps1, ps2: optional primary and secondary prompts (strings)
15*/
16
17#include "Python.h"
18#include "compile.h"
19#include "frameobject.h"
20
21#include "osdefs.h"
22
23#ifdef MS_COREDLL
24extern void *PyWin_DLLhModule;
25/* A string loaded from the DLL at startup: */
26extern const char *PyWin_DLLVersionString;
27#endif
28
29PyObject *
30PySys_GetObject(char *name)
31{
32	PyThreadState *tstate = PyThreadState_Get();
33	PyObject *sd = tstate->interp->sysdict;
34	if (sd == NULL)
35		return NULL;
36	return PyDict_GetItemString(sd, name);
37}
38
39FILE *
40PySys_GetFile(char *name, FILE *def)
41{
42	FILE *fp = NULL;
43	PyObject *v = PySys_GetObject(name);
44	if (v != NULL && PyFile_Check(v))
45		fp = PyFile_AsFile(v);
46	if (fp == NULL)
47		fp = def;
48	return fp;
49}
50
51int
52PySys_SetObject(char *name, PyObject *v)
53{
54	PyThreadState *tstate = PyThreadState_Get();
55	PyObject *sd = tstate->interp->sysdict;
56	if (v == NULL) {
57		if (PyDict_GetItemString(sd, name) == NULL)
58			return 0;
59		else
60			return PyDict_DelItemString(sd, name);
61	}
62	else
63		return PyDict_SetItemString(sd, name, v);
64}
65
66static PyObject *
67sys_displayhook(PyObject *self, PyObject *o)
68{
69	PyObject *outf;
70	PyInterpreterState *interp = PyThreadState_Get()->interp;
71	PyObject *modules = interp->modules;
72	PyObject *builtins = PyDict_GetItemString(modules, "__builtin__");
73
74	if (builtins == NULL) {
75		PyErr_SetString(PyExc_RuntimeError, "lost __builtin__");
76		return NULL;
77	}
78
79	/* Print value except if None */
80	/* After printing, also assign to '_' */
81	/* Before, set '_' to None to avoid recursion */
82	if (o == Py_None) {
83		Py_INCREF(Py_None);
84		return Py_None;
85	}
86	if (PyObject_SetAttrString(builtins, "_", Py_None) != 0)
87		return NULL;
88	if (Py_FlushLine() != 0)
89		return NULL;
90	outf = PySys_GetObject("stdout");
91	if (outf == NULL) {
92		PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
93		return NULL;
94	}
95	if (PyFile_WriteObject(o, outf, 0) != 0)
96		return NULL;
97	PyFile_SoftSpace(outf, 1);
98	if (Py_FlushLine() != 0)
99		return NULL;
100	if (PyObject_SetAttrString(builtins, "_", o) != 0)
101		return NULL;
102	Py_INCREF(Py_None);
103	return Py_None;
104}
105
106static char displayhook_doc[] =
107"displayhook(object) -> None\n"
108"\n"
109"Print an object to sys.stdout and also save it in __builtin__._\n";
110
111static PyObject *
112sys_excepthook(PyObject* self, PyObject* args)
113{
114	PyObject *exc, *value, *tb;
115	if (!PyArg_UnpackTuple(args, "excepthook", 3, 3, &exc, &value, &tb))
116		return NULL;
117	PyErr_Display(exc, value, tb);
118	Py_INCREF(Py_None);
119	return Py_None;
120}
121
122static char excepthook_doc[] =
123"excepthook(exctype, value, traceback) -> None\n"
124"\n"
125"Handle an exception by displaying it with a traceback on sys.stderr.\n";
126
127static PyObject *
128sys_exc_info(PyObject *self)
129{
130	PyThreadState *tstate;
131	tstate = PyThreadState_Get();
132	return Py_BuildValue(
133		"(OOO)",
134		tstate->exc_type != NULL ? tstate->exc_type : Py_None,
135		tstate->exc_value != NULL ? tstate->exc_value : Py_None,
136		tstate->exc_traceback != NULL ?
137			tstate->exc_traceback : Py_None);
138}
139
140static char exc_info_doc[] =
141"exc_info() -> (type, value, traceback)\n\
142\n\
143Return information about the exception that is currently being handled.\n\
144This should be called from inside an except clause only.";
145
146static PyObject *
147sys_exit(PyObject *self, PyObject *args)
148{
149	/* Raise SystemExit so callers may catch it or clean up. */
150	PyErr_SetObject(PyExc_SystemExit, args);
151	return NULL;
152}
153
154static char exit_doc[] =
155"exit([status])\n\
156\n\
157Exit the interpreter by raising SystemExit(status).\n\
158If the status is omitted or None, it defaults to zero (i.e., success).\n\
159If the status numeric, it will be used as the system exit status.\n\
160If it is another kind of object, it will be printed and the system\n\
161exit status will be one (i.e., failure).";
162
163#ifdef Py_USING_UNICODE
164
165static PyObject *
166sys_getdefaultencoding(PyObject *self)
167{
168	return PyString_FromString(PyUnicode_GetDefaultEncoding());
169}
170
171static char getdefaultencoding_doc[] =
172"getdefaultencoding() -> string\n\
173\n\
174Return the current default string encoding used by the Unicode \n\
175implementation.";
176
177static PyObject *
178sys_setdefaultencoding(PyObject *self, PyObject *args)
179{
180	char *encoding;
181	if (!PyArg_ParseTuple(args, "s:setdefaultencoding", &encoding))
182		return NULL;
183	if (PyUnicode_SetDefaultEncoding(encoding))
184	    	return NULL;
185	Py_INCREF(Py_None);
186	return Py_None;
187}
188
189static char setdefaultencoding_doc[] =
190"setdefaultencoding(encoding)\n\
191\n\
192Set the current default string encoding used by the Unicode implementation.";
193
194#endif
195
196/*
197 * Cached interned string objects used for calling the profile and
198 * trace functions.  Initialized by trace_init().
199 */
200static PyObject *whatstrings[4] = {NULL, NULL, NULL, NULL};
201
202static int
203trace_init(void)
204{
205	static char *whatnames[4] = {"call", "exception", "line", "return"};
206	PyObject *name;
207	int i;
208	for (i = 0; i < 4; ++i) {
209		if (whatstrings[i] == NULL) {
210			name = PyString_InternFromString(whatnames[i]);
211			if (name == NULL)
212				return -1;
213			whatstrings[i] = name;
214                }
215	}
216	return 0;
217}
218
219
220static PyObject *
221call_trampoline(PyThreadState *tstate, PyObject* callback,
222		PyFrameObject *frame, int what, PyObject *arg)
223{
224	PyObject *args = PyTuple_New(3);
225	PyObject *whatstr;
226	PyObject *result;
227
228	if (args == NULL)
229		return NULL;
230	Py_INCREF(frame);
231	whatstr = whatstrings[what];
232	Py_INCREF(whatstr);
233	if (arg == NULL)
234		arg = Py_None;
235	Py_INCREF(arg);
236	PyTuple_SET_ITEM(args, 0, (PyObject *)frame);
237	PyTuple_SET_ITEM(args, 1, whatstr);
238	PyTuple_SET_ITEM(args, 2, arg);
239
240	/* call the Python-level function */
241	PyFrame_FastToLocals(frame);
242	result = PyEval_CallObject(callback, args);
243	PyFrame_LocalsToFast(frame, 1);
244	if (result == NULL)
245		PyTraceBack_Here(frame);
246
247	/* cleanup */
248	Py_DECREF(args);
249	return result;
250}
251
252static int
253profile_trampoline(PyObject *self, PyFrameObject *frame,
254		   int what, PyObject *arg)
255{
256	PyThreadState *tstate = frame->f_tstate;
257	PyObject *result;
258
259	if (arg == NULL)
260		arg = Py_None;
261	result = call_trampoline(tstate, self, frame, what, arg);
262	if (result == NULL) {
263		PyEval_SetProfile(NULL, NULL);
264		return -1;
265	}
266	Py_DECREF(result);
267	return 0;
268}
269
270static int
271trace_trampoline(PyObject *self, PyFrameObject *frame,
272		 int what, PyObject *arg)
273{
274	PyThreadState *tstate = frame->f_tstate;
275	PyObject *callback;
276	PyObject *result;
277
278	if (what == PyTrace_CALL)
279		callback = self;
280	else
281		callback = frame->f_trace;
282	if (callback == NULL)
283		return 0;
284	result = call_trampoline(tstate, callback, frame, what, arg);
285	if (result == NULL) {
286		PyEval_SetTrace(NULL, NULL);
287		Py_XDECREF(frame->f_trace);
288		frame->f_trace = NULL;
289		return -1;
290	}
291	if (result != Py_None) {
292		PyObject *temp = frame->f_trace;
293		frame->f_trace = NULL;
294		Py_XDECREF(temp);
295		frame->f_trace = result;
296	}
297	else {
298		Py_DECREF(result);
299	}
300	return 0;
301}
302
303static PyObject *
304sys_settrace(PyObject *self, PyObject *args)
305{
306	if (trace_init() == -1)
307		return NULL;
308	if (args == Py_None)
309		PyEval_SetTrace(NULL, NULL);
310	else
311		PyEval_SetTrace(trace_trampoline, args);
312	Py_INCREF(Py_None);
313	return Py_None;
314}
315
316static char settrace_doc[] =
317"settrace(function)\n\
318\n\
319Set the global debug tracing function.  It will be called on each\n\
320function call.  See the debugger chapter in the library manual.";
321
322static PyObject *
323sys_setprofile(PyObject *self, PyObject *args)
324{
325	if (trace_init() == -1)
326		return NULL;
327	if (args == Py_None)
328		PyEval_SetProfile(NULL, NULL);
329	else
330		PyEval_SetProfile(profile_trampoline, args);
331	Py_INCREF(Py_None);
332	return Py_None;
333}
334
335static char setprofile_doc[] =
336"setprofile(function)\n\
337\n\
338Set the profiling function.  It will be called on each function call\n\
339and return.  See the profiler chapter in the library manual.";
340
341static PyObject *
342sys_setcheckinterval(PyObject *self, PyObject *args)
343{
344	PyThreadState *tstate = PyThreadState_Get();
345	if (!PyArg_ParseTuple(args, "i:setcheckinterval", &tstate->interp->checkinterval))
346		return NULL;
347	Py_INCREF(Py_None);
348	return Py_None;
349}
350
351static char setcheckinterval_doc[] =
352"setcheckinterval(n)\n\
353\n\
354Tell the Python interpreter to check for asynchronous events every\n\
355n instructions.  This also affects how often thread switches occur.";
356
357static PyObject *
358sys_setrecursionlimit(PyObject *self, PyObject *args)
359{
360	int new_limit;
361	if (!PyArg_ParseTuple(args, "i:setrecursionlimit", &new_limit))
362		return NULL;
363	if (new_limit <= 0) {
364		PyErr_SetString(PyExc_ValueError,
365				"recursion limit must be positive");
366		return NULL;
367	}
368	Py_SetRecursionLimit(new_limit);
369	Py_INCREF(Py_None);
370	return Py_None;
371}
372
373static char setrecursionlimit_doc[] =
374"setrecursionlimit(n)\n\
375\n\
376Set the maximum depth of the Python interpreter stack to n.  This\n\
377limit prevents infinite recursion from causing an overflow of the C\n\
378stack and crashing Python.  The highest possible limit is platform-\n\
379dependent.";
380
381static PyObject *
382sys_getrecursionlimit(PyObject *self)
383{
384	return PyInt_FromLong(Py_GetRecursionLimit());
385}
386
387static char getrecursionlimit_doc[] =
388"getrecursionlimit()\n\
389\n\
390Return the current value of the recursion limit, the maximum depth\n\
391of the Python interpreter stack.  This limit prevents infinite\n\
392recursion from causing an overflow of the C stack and crashing Python.";
393
394#ifdef HAVE_DLOPEN
395static PyObject *
396sys_setdlopenflags(PyObject *self, PyObject *args)
397{
398	int new_val;
399        PyThreadState *tstate = PyThreadState_Get();
400	if (!PyArg_ParseTuple(args, "i:setdlopenflags", &new_val))
401		return NULL;
402        if (!tstate)
403		return NULL;
404        tstate->interp->dlopenflags = new_val;
405	Py_INCREF(Py_None);
406	return Py_None;
407}
408
409static char setdlopenflags_doc[] =
410"setdlopenflags(n) -> None\n\
411\n\
412Set the flags that will be used for dlopen() calls. Among other\n\
413things, this will enable a lazy resolving of symbols when importing\n\
414a module, if called as sys.setdlopenflags(0)\n\
415To share symbols across extension modules, call as\n\
416sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)";
417
418static PyObject *
419sys_getdlopenflags(PyObject *self, PyObject *args)
420{
421        PyThreadState *tstate = PyThreadState_Get();
422        if (!tstate)
423		return NULL;
424        return PyInt_FromLong(tstate->interp->dlopenflags);
425}
426
427static char getdlopenflags_doc[] =
428"getdlopenflags() -> int\n\
429\n\
430Return the current value of the flags that are used for dlopen()\n\
431calls. The flag constants are defined in the dl module.";
432#endif
433
434#ifdef USE_MALLOPT
435/* Link with -lmalloc (or -lmpc) on an SGI */
436#include <malloc.h>
437
438static PyObject *
439sys_mdebug(PyObject *self, PyObject *args)
440{
441	int flag;
442	if (!PyArg_ParseTuple(args, "i:mdebug", &flag))
443		return NULL;
444	mallopt(M_DEBUG, flag);
445	Py_INCREF(Py_None);
446	return Py_None;
447}
448#endif /* USE_MALLOPT */
449
450static PyObject *
451sys_getrefcount(PyObject *self, PyObject *arg)
452{
453	return PyInt_FromLong(arg->ob_refcnt);
454}
455
456#ifdef Py_TRACE_REFS
457static PyObject *
458sys_gettotalrefcount(PyObject *self)
459{
460	extern long _Py_RefTotal;
461	return PyInt_FromLong(_Py_RefTotal);
462}
463
464#endif /* Py_TRACE_REFS */
465
466static char getrefcount_doc[] =
467"getrefcount(object) -> integer\n\
468\n\
469Return the current reference count for the object.  This includes the\n\
470temporary reference in the argument list, so it is at least 2.";
471
472#ifdef COUNT_ALLOCS
473static PyObject *
474sys_getcounts(PyObject *self)
475{
476	extern PyObject *get_counts(void);
477
478	return get_counts();
479}
480#endif
481
482static char getframe_doc[] =
483"_getframe([depth]) -> frameobject\n\
484\n\
485Return a frame object from the call stack.  If optional integer depth is\n\
486given, return the frame object that many calls below the top of the stack.\n\
487If that is deeper than the call stack, ValueError is raised.  The default\n\
488for depth is zero, returning the frame at the top of the call stack.\n\
489\n\
490This function should be used for internal and specialized\n\
491purposes only.";
492
493static PyObject *
494sys_getframe(PyObject *self, PyObject *args)
495{
496	PyFrameObject *f = PyThreadState_Get()->frame;
497	int depth = -1;
498
499	if (!PyArg_ParseTuple(args, "|i:_getframe", &depth))
500		return NULL;
501
502	while (depth > 0 && f != NULL) {
503		f = f->f_back;
504		--depth;
505	}
506	if (f == NULL) {
507		PyErr_SetString(PyExc_ValueError,
508				"call stack is not deep enough");
509		return NULL;
510	}
511	Py_INCREF(f);
512	return (PyObject*)f;
513}
514
515
516#ifdef Py_TRACE_REFS
517/* Defined in objects.c because it uses static globals if that file */
518extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
519#endif
520
521#ifdef DYNAMIC_EXECUTION_PROFILE
522/* Defined in ceval.c because it uses static globals if that file */
523extern PyObject *_Py_GetDXProfile(PyObject *,  PyObject *);
524#endif
525
526static PyMethodDef sys_methods[] = {
527	/* Might as well keep this in alphabetic order */
528	{"displayhook",	sys_displayhook, METH_O, displayhook_doc},
529	{"exc_info",	(PyCFunction)sys_exc_info, METH_NOARGS, exc_info_doc},
530	{"excepthook",	sys_excepthook, METH_VARARGS, excepthook_doc},
531	{"exit",	sys_exit, METH_OLDARGS, exit_doc},
532#ifdef Py_USING_UNICODE
533	{"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, METH_NOARGS,
534	 getdefaultencoding_doc},
535#endif
536#ifdef HAVE_DLOPEN
537	{"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS,
538	 getdlopenflags_doc},
539#endif
540#ifdef COUNT_ALLOCS
541	{"getcounts",	(PyCFunction)sys_getcounts, METH_NOARGS},
542#endif
543#ifdef DYNAMIC_EXECUTION_PROFILE
544	{"getdxp",	_Py_GetDXProfile, METH_VARARGS},
545#endif
546#ifdef Py_TRACE_REFS
547	{"getobjects",	_Py_GetObjects, METH_VARARGS},
548	{"gettotalrefcount", (PyCFunction)sys_gettotalrefcount, METH_NOARGS},
549#endif
550	{"getrefcount",	(PyCFunction)sys_getrefcount, METH_O, getrefcount_doc},
551	{"getrecursionlimit", (PyCFunction)sys_getrecursionlimit, METH_NOARGS,
552	 getrecursionlimit_doc},
553	{"_getframe", sys_getframe, METH_VARARGS, getframe_doc},
554#ifdef USE_MALLOPT
555	{"mdebug",	sys_mdebug, METH_VARARGS},
556#endif
557#ifdef Py_USING_UNICODE
558	{"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS,
559	 setdefaultencoding_doc},
560#endif
561	{"setcheckinterval",	sys_setcheckinterval, METH_VARARGS,
562	 setcheckinterval_doc},
563#ifdef HAVE_DLOPEN
564	{"setdlopenflags", sys_setdlopenflags, METH_VARARGS,
565	 setdlopenflags_doc},
566#endif
567	{"setprofile",	sys_setprofile, METH_OLDARGS, setprofile_doc},
568	{"setrecursionlimit", sys_setrecursionlimit, METH_VARARGS,
569	 setrecursionlimit_doc},
570	{"settrace",	sys_settrace, METH_OLDARGS, settrace_doc},
571	{NULL,		NULL}		/* sentinel */
572};
573
574static PyObject *
575list_builtin_module_names(void)
576{
577	PyObject *list = PyList_New(0);
578	int i;
579	if (list == NULL)
580		return NULL;
581	for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
582		PyObject *name = PyString_FromString(
583			PyImport_Inittab[i].name);
584		if (name == NULL)
585			break;
586		PyList_Append(list, name);
587		Py_DECREF(name);
588	}
589	if (PyList_Sort(list) != 0) {
590		Py_DECREF(list);
591		list = NULL;
592	}
593	if (list) {
594		PyObject *v = PyList_AsTuple(list);
595		Py_DECREF(list);
596		list = v;
597	}
598	return list;
599}
600
601static PyObject *warnoptions = NULL;
602
603void
604PySys_ResetWarnOptions(void)
605{
606	if (warnoptions == NULL || !PyList_Check(warnoptions))
607		return;
608	PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
609}
610
611void
612PySys_AddWarnOption(char *s)
613{
614	PyObject *str;
615
616	if (warnoptions == NULL || !PyList_Check(warnoptions)) {
617		Py_XDECREF(warnoptions);
618		warnoptions = PyList_New(0);
619		if (warnoptions == NULL)
620			return;
621	}
622	str = PyString_FromString(s);
623	if (str != NULL) {
624		PyList_Append(warnoptions, str);
625		Py_DECREF(str);
626	}
627}
628
629/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
630   Two literals concatenated works just fine.  If you have a K&R compiler
631   or other abomination that however *does* understand longer strings,
632   get rid of the !!! comment in the middle and the quotes that surround it. */
633static char sys_doc[] =
634"This module provides access to some objects used or maintained by the\n\
635interpreter and to functions that interact strongly with the interpreter.\n\
636\n\
637Dynamic objects:\n\
638\n\
639argv -- command line arguments; argv[0] is the script pathname if known\n\
640path -- module search path; path[0] is the script directory, else ''\n\
641modules -- dictionary of loaded modules\n\
642\n\
643displayhook -- called to show results in an interactive session\n\
644excepthook -- called to handle any uncaught exception other than SystemExit\n\
645  To customize printing in an interactive session or to install a custom\n\
646  top-level exception handler, assign other functions to replace these.\n\
647\n\
648exitfunc -- if sys.exitfunc exists, this routine is called when Python exits\n\
649  Assigning to sys.exitfunc is deprecated; use the atexit module instead.\n\
650\n\
651stdin -- standard input file object; used by raw_input() and input()\n\
652stdout -- standard output file object; used by the print statement\n\
653stderr -- standard error object; used for error messages\n\
654  By assigning other file objects (or objects that behave like files)\n\
655  to these, it is possible to redirect all of the interpreter's I/O.\n\
656\n\
657last_type -- type of last uncaught exception\n\
658last_value -- value of last uncaught exception\n\
659last_traceback -- traceback of last uncaught exception\n\
660  These three are only available in an interactive session after a\n\
661  traceback has been printed.\n\
662\n\
663exc_type -- type of exception currently being handled\n\
664exc_value -- value of exception currently being handled\n\
665exc_traceback -- traceback of exception currently being handled\n\
666  The function exc_info() should be used instead of these three,\n\
667  because it is thread-safe.\n\
668"
669#ifndef MS_WIN16
670/* concatenating string here */
671"\n\
672Static objects:\n\
673\n\
674maxint -- the largest supported integer (the smallest is -maxint-1)\n\
675maxunicode -- the largest supported character\n\
676builtin_module_names -- tuple of module names built into this interpreter\n\
677version -- the version of this interpreter as a string\n\
678version_info -- version information as a tuple\n\
679hexversion -- version information encoded as a single integer\n\
680copyright -- copyright notice pertaining to this interpreter\n\
681platform -- platform identifier\n\
682executable -- pathname of this Python interpreter\n\
683prefix -- prefix used to find the Python library\n\
684exec_prefix -- prefix used to find the machine-specific Python library\n\
685"
686#ifdef MS_WINDOWS
687/* concatenating string here */
688"dllhandle -- [Windows only] integer handle of the Python DLL\n\
689winver -- [Windows only] version number of the Python DLL\n\
690"
691#endif /* MS_WINDOWS */
692"__stdin__ -- the original stdin; don't touch!\n\
693__stdout__ -- the original stdout; don't touch!\n\
694__stderr__ -- the original stderr; don't touch!\n\
695__displayhook__ -- the original displayhook; don't touch!\n\
696__excepthook__ -- the original excepthook; don't touch!\n\
697\n\
698Functions:\n\
699\n\
700displayhook() -- print an object to the screen, and save it in __builtin__._\n\
701excepthook() -- print an exception and its traceback to sys.stderr\n\
702exc_info() -- return thread-safe information about the current exception\n\
703exit() -- exit the interpreter by raising SystemExit\n\
704getdlopenflags() -- returns flags to be used for dlopen() calls\n\
705getrefcount() -- return the reference count for an object (plus one :-)\n\
706getrecursionlimit() -- return the max recursion depth for the interpreter\n\
707setcheckinterval() -- control how often the interpreter checks for events\n\
708setdlopenflags() -- set the flags to be used for dlopen() calls\n\
709setprofile() -- set the global profiling function\n\
710setrecursionlimit() -- set the max recursion depth for the interpreter\n\
711settrace() -- set the global debug tracing function\n\
712"
713#endif /* MS_WIN16 */
714/* end of sys_doc */ ;
715
716PyObject *
717_PySys_Init(void)
718{
719	PyObject *m, *v, *sysdict;
720	PyObject *sysin, *sysout, *syserr;
721	char *s;
722
723	m = Py_InitModule3("sys", sys_methods, sys_doc);
724	sysdict = PyModule_GetDict(m);
725
726	sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL);
727	sysout = PyFile_FromFile(stdout, "<stdout>", "w", NULL);
728	syserr = PyFile_FromFile(stderr, "<stderr>", "w", NULL);
729	if (PyErr_Occurred())
730		return NULL;
731	PyDict_SetItemString(sysdict, "stdin", sysin);
732	PyDict_SetItemString(sysdict, "stdout", sysout);
733	PyDict_SetItemString(sysdict, "stderr", syserr);
734	/* Make backup copies for cleanup */
735	PyDict_SetItemString(sysdict, "__stdin__", sysin);
736	PyDict_SetItemString(sysdict, "__stdout__", sysout);
737	PyDict_SetItemString(sysdict, "__stderr__", syserr);
738	PyDict_SetItemString(sysdict, "__displayhook__",
739                             PyDict_GetItemString(sysdict, "displayhook"));
740	PyDict_SetItemString(sysdict, "__excepthook__",
741                             PyDict_GetItemString(sysdict, "excepthook"));
742	Py_XDECREF(sysin);
743	Py_XDECREF(sysout);
744	Py_XDECREF(syserr);
745	PyDict_SetItemString(sysdict, "version",
746			     v = PyString_FromString(Py_GetVersion()));
747	Py_XDECREF(v);
748	PyDict_SetItemString(sysdict, "hexversion",
749			     v = PyInt_FromLong(PY_VERSION_HEX));
750	Py_XDECREF(v);
751	/*
752	 * These release level checks are mutually exclusive and cover
753	 * the field, so don't get too fancy with the pre-processor!
754	 */
755#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
756	s = "alpha";
757#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
758	s = "beta";
759#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
760	s = "candidate";
761#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
762	s = "final";
763#endif
764	PyDict_SetItemString(sysdict, "version_info",
765			     v = Py_BuildValue("iiisi", PY_MAJOR_VERSION,
766					       PY_MINOR_VERSION,
767					       PY_MICRO_VERSION, s,
768					       PY_RELEASE_SERIAL));
769	Py_XDECREF(v);
770	PyDict_SetItemString(sysdict, "copyright",
771			     v = PyString_FromString(Py_GetCopyright()));
772	Py_XDECREF(v);
773	PyDict_SetItemString(sysdict, "platform",
774			     v = PyString_FromString(Py_GetPlatform()));
775	Py_XDECREF(v);
776	PyDict_SetItemString(sysdict, "executable",
777			     v = PyString_FromString(Py_GetProgramFullPath()));
778	Py_XDECREF(v);
779	PyDict_SetItemString(sysdict, "prefix",
780			     v = PyString_FromString(Py_GetPrefix()));
781	Py_XDECREF(v);
782	PyDict_SetItemString(sysdict, "exec_prefix",
783		   v = PyString_FromString(Py_GetExecPrefix()));
784	Py_XDECREF(v);
785	PyDict_SetItemString(sysdict, "maxint",
786			     v = PyInt_FromLong(PyInt_GetMax()));
787	Py_XDECREF(v);
788#ifdef Py_USING_UNICODE
789	PyDict_SetItemString(sysdict, "maxunicode",
790			     v = PyInt_FromLong(PyUnicode_GetMax()));
791	Py_XDECREF(v);
792#endif
793	PyDict_SetItemString(sysdict, "builtin_module_names",
794		   v = list_builtin_module_names());
795	Py_XDECREF(v);
796	{
797		/* Assumes that longs are at least 2 bytes long.
798		   Should be safe! */
799		unsigned long number = 1;
800		char *value;
801
802		s = (char *) &number;
803		if (s[0] == 0)
804			value = "big";
805		else
806			value = "little";
807		PyDict_SetItemString(sysdict, "byteorder",
808				     v = PyString_FromString(value));
809		Py_XDECREF(v);
810	}
811#ifdef MS_COREDLL
812	PyDict_SetItemString(sysdict, "dllhandle",
813			     v = PyLong_FromVoidPtr(PyWin_DLLhModule));
814	Py_XDECREF(v);
815	PyDict_SetItemString(sysdict, "winver",
816			     v = PyString_FromString(PyWin_DLLVersionString));
817	Py_XDECREF(v);
818#endif
819	if (warnoptions == NULL) {
820		warnoptions = PyList_New(0);
821	}
822	else {
823		Py_INCREF(warnoptions);
824	}
825	if (warnoptions != NULL) {
826		PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
827	}
828
829	if (PyErr_Occurred())
830		return NULL;
831	return m;
832}
833
834static PyObject *
835makepathobject(char *path, int delim)
836{
837	int i, n;
838	char *p;
839	PyObject *v, *w;
840
841	n = 1;
842	p = path;
843	while ((p = strchr(p, delim)) != NULL) {
844		n++;
845		p++;
846	}
847	v = PyList_New(n);
848	if (v == NULL)
849		return NULL;
850	for (i = 0; ; i++) {
851		p = strchr(path, delim);
852		if (p == NULL)
853			p = strchr(path, '\0'); /* End of string */
854		w = PyString_FromStringAndSize(path, (int) (p - path));
855		if (w == NULL) {
856			Py_DECREF(v);
857			return NULL;
858		}
859		PyList_SetItem(v, i, w);
860		if (*p == '\0')
861			break;
862		path = p+1;
863	}
864	return v;
865}
866
867void
868PySys_SetPath(char *path)
869{
870	PyObject *v;
871	if ((v = makepathobject(path, DELIM)) == NULL)
872		Py_FatalError("can't create sys.path");
873	if (PySys_SetObject("path", v) != 0)
874		Py_FatalError("can't assign sys.path");
875	Py_DECREF(v);
876}
877
878static PyObject *
879makeargvobject(int argc, char **argv)
880{
881	PyObject *av;
882	if (argc <= 0 || argv == NULL) {
883		/* Ensure at least one (empty) argument is seen */
884		static char *empty_argv[1] = {""};
885		argv = empty_argv;
886		argc = 1;
887	}
888	av = PyList_New(argc);
889	if (av != NULL) {
890		int i;
891		for (i = 0; i < argc; i++) {
892			PyObject *v = PyString_FromString(argv[i]);
893			if (v == NULL) {
894				Py_DECREF(av);
895				av = NULL;
896				break;
897			}
898			PyList_SetItem(av, i, v);
899		}
900	}
901	return av;
902}
903
904void
905PySys_SetArgv(int argc, char **argv)
906{
907	PyObject *av = makeargvobject(argc, argv);
908	PyObject *path = PySys_GetObject("path");
909	if (av == NULL)
910		Py_FatalError("no mem for sys.argv");
911	if (PySys_SetObject("argv", av) != 0)
912		Py_FatalError("can't assign sys.argv");
913	if (path != NULL) {
914		char *argv0 = argv[0];
915		char *p = NULL;
916		int n = 0;
917		PyObject *a;
918#ifdef HAVE_READLINK
919		char link[MAXPATHLEN+1];
920		char argv0copy[2*MAXPATHLEN+1];
921		int nr = 0;
922		if (argc > 0 && argv0 != NULL)
923			nr = readlink(argv0, link, MAXPATHLEN);
924		if (nr > 0) {
925			/* It's a symlink */
926			link[nr] = '\0';
927			if (link[0] == SEP)
928				argv0 = link; /* Link to absolute path */
929			else if (strchr(link, SEP) == NULL)
930				; /* Link without path */
931			else {
932				/* Must join(dirname(argv0), link) */
933				char *q = strrchr(argv0, SEP);
934				if (q == NULL)
935					argv0 = link; /* argv0 without path */
936				else {
937					/* Must make a copy */
938					strcpy(argv0copy, argv0);
939					q = strrchr(argv0copy, SEP);
940					strcpy(q+1, link);
941					argv0 = argv0copy;
942				}
943			}
944		}
945#endif /* HAVE_READLINK */
946#if SEP == '\\' /* Special case for MS filename syntax */
947		if (argc > 0 && argv0 != NULL) {
948			char *q;
949			p = strrchr(argv0, SEP);
950			/* Test for alternate separator */
951			q = strrchr(p ? p : argv0, '/');
952			if (q != NULL)
953				p = q;
954			if (p != NULL) {
955				n = p + 1 - argv0;
956				if (n > 1 && p[-1] != ':')
957					n--; /* Drop trailing separator */
958			}
959		}
960#else /* All other filename syntaxes */
961		if (argc > 0 && argv0 != NULL)
962			p = strrchr(argv0, SEP);
963		if (p != NULL) {
964#ifndef RISCOS
965			n = p + 1 - argv0;
966#else /* don't include trailing separator */
967			n = p - argv0;
968#endif /* RISCOS */
969#if SEP == '/' /* Special case for Unix filename syntax */
970			if (n > 1)
971				n--; /* Drop trailing separator */
972#endif /* Unix */
973		}
974#endif /* All others */
975		a = PyString_FromStringAndSize(argv0, n);
976		if (a == NULL)
977			Py_FatalError("no mem for sys.path insertion");
978		if (PyList_Insert(path, 0, a) < 0)
979			Py_FatalError("sys.path.insert(0) failed");
980		Py_DECREF(a);
981	}
982	Py_DECREF(av);
983}
984
985
986/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
987   Adapted from code submitted by Just van Rossum.
988
989   PySys_WriteStdout(format, ...)
990   PySys_WriteStderr(format, ...)
991
992      The first function writes to sys.stdout; the second to sys.stderr.  When
993      there is a problem, they write to the real (C level) stdout or stderr;
994      no exceptions are raised.
995
996      Both take a printf-style format string as their first argument followed
997      by a variable length argument list determined by the format string.
998
999      *** WARNING ***
1000
1001      The format should limit the total size of the formatted output string to
1002      1000 bytes.  In particular, this means that no unrestricted "%s" formats
1003      should occur; these should be limited using "%.<N>s where <N> is a
1004      decimal number calculated so that <N> plus the maximum size of other
1005      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
1006      which can print hundreds of digits for very large numbers.
1007
1008 */
1009
1010static void
1011mywrite(char *name, FILE *fp, const char *format, va_list va)
1012{
1013	PyObject *file;
1014	PyObject *error_type, *error_value, *error_traceback;
1015
1016	PyErr_Fetch(&error_type, &error_value, &error_traceback);
1017	file = PySys_GetObject(name);
1018	if (file == NULL || PyFile_AsFile(file) == fp)
1019		vfprintf(fp, format, va);
1020	else {
1021		char buffer[1001];
1022		const int written = PyOS_vsnprintf(buffer, sizeof(buffer),
1023						   format, va);
1024		if (PyFile_WriteString(buffer, file) != 0) {
1025			PyErr_Clear();
1026			fputs(buffer, fp);
1027		}
1028		if (written < 0 || written >= sizeof(buffer)) {
1029			const char *truncated = "... truncated";
1030			if (PyFile_WriteString(truncated, file) != 0) {
1031				PyErr_Clear();
1032				fputs(truncated, fp);
1033			}
1034		}
1035	}
1036	PyErr_Restore(error_type, error_value, error_traceback);
1037}
1038
1039void
1040PySys_WriteStdout(const char *format, ...)
1041{
1042	va_list va;
1043
1044	va_start(va, format);
1045	mywrite("stdout", stdout, format, va);
1046	va_end(va);
1047}
1048
1049void
1050PySys_WriteStderr(const char *format, ...)
1051{
1052	va_list va;
1053
1054	va_start(va, format);
1055	mywrite("stderr", stderr, format, va);
1056	va_end(va);
1057}
1058