sysmodule.c revision e0d7dae3b8008b5037df6cb212ca6efacf7a012d
1/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5                        All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
32/* System module */
33
34/*
35Various bits of information used by the interpreter are collected in
36module 'sys'.
37Function member:
38- exit(sts): raise SystemExit
39Data members:
40- stdin, stdout, stderr: standard file objects
41- modules: the table of modules (dictionary)
42- path: module search path (list of strings)
43- argv: script arguments (list of strings)
44- ps1, ps2: optional primary and secondary prompts (strings)
45*/
46
47#include "Python.h"
48
49#include "osdefs.h"
50
51#ifdef HAVE_UNISTD_H
52#include <unistd.h>
53#endif
54
55#ifdef MS_COREDLL
56extern void *PyWin_DLLhModule;
57/* A string loaded from the DLL at startup: */
58extern const char *PyWin_DLLVersionString;
59#endif
60
61PyObject *
62PySys_GetObject(name)
63	char *name;
64{
65	PyThreadState *tstate = PyThreadState_Get();
66	PyObject *sd = tstate->interp->sysdict;
67	return PyDict_GetItemString(sd, name);
68}
69
70FILE *
71PySys_GetFile(name, def)
72	char *name;
73	FILE *def;
74{
75	FILE *fp = NULL;
76	PyObject *v = PySys_GetObject(name);
77	if (v != NULL && PyFile_Check(v))
78		fp = PyFile_AsFile(v);
79	if (fp == NULL)
80		fp = def;
81	return fp;
82}
83
84int
85PySys_SetObject(name, v)
86	char *name;
87	PyObject *v;
88{
89	PyThreadState *tstate = PyThreadState_Get();
90	PyObject *sd = tstate->interp->sysdict;
91	if (v == NULL) {
92		if (PyDict_GetItemString(sd, name) == NULL)
93			return 0;
94		else
95			return PyDict_DelItemString(sd, name);
96	}
97	else
98		return PyDict_SetItemString(sd, name, v);
99}
100
101static PyObject *
102sys_exc_info(self, args)
103	PyObject *self;
104	PyObject *args;
105{
106	PyThreadState *tstate;
107	if (!PyArg_Parse(args, ""))
108		return NULL;
109	tstate = PyThreadState_Get();
110	return Py_BuildValue(
111		"(OOO)",
112		tstate->exc_type != NULL ? tstate->exc_type : Py_None,
113		tstate->exc_value != NULL ? tstate->exc_value : Py_None,
114		tstate->exc_traceback != NULL ?
115			tstate->exc_traceback : Py_None);
116}
117
118static char exc_info_doc[] =
119"exc_info() -> (type, value, traceback)\n\
120\n\
121Return information about the exception that is currently being handled.\n\
122This should be called from inside an except clause only.";
123
124static PyObject *
125sys_exit(self, args)
126	PyObject *self;
127	PyObject *args;
128{
129	/* Raise SystemExit so callers may catch it or clean up. */
130	PyErr_SetObject(PyExc_SystemExit, args);
131	return NULL;
132}
133
134static char exit_doc[] =
135"exit([status])\n\
136\n\
137Exit the interpreter by raising SystemExit(status).\n\
138If the status is omitted or None, it defaults to zero (i.e., success).\n\
139If the status numeric, it will be used as the system exit status.\n\
140If it is another kind of object, it will be printed and the system\n\
141exit status will be one (i.e., failure).";
142
143static PyObject *
144sys_settrace(self, args)
145	PyObject *self;
146	PyObject *args;
147{
148	PyThreadState *tstate = PyThreadState_Get();
149	if (args == Py_None)
150		args = NULL;
151	else
152		Py_XINCREF(args);
153	Py_XDECREF(tstate->sys_tracefunc);
154	tstate->sys_tracefunc = args;
155	Py_INCREF(Py_None);
156	return Py_None;
157}
158
159static char settrace_doc[] =
160"settrace(function)\n\
161\n\
162Set the global debug tracing function.  It will be called on each\n\
163function call.  See the debugger chapter in the library manual.";
164
165static PyObject *
166sys_setprofile(self, args)
167	PyObject *self;
168	PyObject *args;
169{
170	PyThreadState *tstate = PyThreadState_Get();
171	if (args == Py_None)
172		args = NULL;
173	else
174		Py_XINCREF(args);
175	Py_XDECREF(tstate->sys_profilefunc);
176	tstate->sys_profilefunc = args;
177	Py_INCREF(Py_None);
178	return Py_None;
179}
180
181static char setprofile_doc[] =
182"setprofile(function)\n\
183\n\
184Set the profiling function.  It will be called on each function call\n\
185and return.  See the profiler chapter in the library manual.";
186
187static PyObject *
188sys_setcheckinterval(self, args)
189	PyObject *self;
190	PyObject *args;
191{
192	PyThreadState *tstate = PyThreadState_Get();
193	if (!PyArg_ParseTuple(args, "i", &tstate->interp->checkinterval))
194		return NULL;
195	Py_INCREF(Py_None);
196	return Py_None;
197}
198
199static char setcheckinterval_doc[] =
200"setcheckinterval(n)\n\
201\n\
202Tell the Python interpreter to check for asynchronous events every\n\
203n instructions.  This also affects how often thread switches occur.";
204
205#ifdef USE_MALLOPT
206/* Link with -lmalloc (or -lmpc) on an SGI */
207#include <malloc.h>
208
209static PyObject *
210sys_mdebug(self, args)
211	PyObject *self;
212	PyObject *args;
213{
214	int flag;
215	if (!PyArg_Parse(args, "i", &flag))
216		return NULL;
217	mallopt(M_DEBUG, flag);
218	Py_INCREF(Py_None);
219	return Py_None;
220}
221#endif /* USE_MALLOPT */
222
223static PyObject *
224sys_getrefcount(self, args)
225	PyObject *self;
226	PyObject *args;
227{
228	PyObject *arg;
229	if (!PyArg_Parse(args, "O", &arg))
230		return NULL;
231	return PyInt_FromLong((long) arg->ob_refcnt);
232}
233
234static char getrefcount_doc[] =
235"getrefcount(object) -> integer\n\
236\n\
237Return the current reference count for the object.  This includes the\n\
238temporary reference in the argument list, so it is at least 2.";
239
240#ifdef COUNT_ALLOCS
241static PyObject *
242sys_getcounts(self, args)
243	PyObject *self, *args;
244{
245	extern PyObject *get_counts Py_PROTO((void));
246
247	if (!PyArg_Parse(args, ""))
248		return NULL;
249	return get_counts();
250}
251#endif
252
253#ifdef Py_TRACE_REFS
254/* Defined in objects.c because it uses static globals if that file */
255extern PyObject *_Py_GetObjects Py_PROTO((PyObject *, PyObject *));
256#endif
257
258#ifdef DYNAMIC_EXECUTION_PROFILE
259/* Defined in ceval.c because it uses static globals if that file */
260extern PyObject *_Py_GetDXProfile Py_PROTO((PyObject *,  PyObject *));
261#endif
262
263static PyMethodDef sys_methods[] = {
264	/* Might as well keep this in alphabetic order */
265	{"exc_info",	sys_exc_info, 0, exc_info_doc},
266	{"exit",	sys_exit, 0, exit_doc},
267#ifdef COUNT_ALLOCS
268	{"getcounts",	sys_getcounts, 0},
269#endif
270#ifdef DYNAMIC_EXECUTION_PROFILE
271	{"getdxp",	_Py_GetDXProfile, 1},
272#endif
273#ifdef Py_TRACE_REFS
274	{"getobjects",	_Py_GetObjects, 1},
275#endif
276	{"getrefcount",	sys_getrefcount, 0, getrefcount_doc},
277#ifdef USE_MALLOPT
278	{"mdebug",	sys_mdebug, 0},
279#endif
280	{"setcheckinterval",	sys_setcheckinterval, 1, setcheckinterval_doc},
281	{"setprofile",	sys_setprofile, 0, setprofile_doc},
282	{"settrace",	sys_settrace, 0, settrace_doc},
283	{NULL,		NULL}		/* sentinel */
284};
285
286static PyObject *
287list_builtin_module_names()
288{
289	PyObject *list = PyList_New(0);
290	int i;
291	if (list == NULL)
292		return NULL;
293	for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
294		PyObject *name = PyString_FromString(
295			PyImport_Inittab[i].name);
296		if (name == NULL)
297			break;
298		PyList_Append(list, name);
299		Py_DECREF(name);
300	}
301	if (PyList_Sort(list) != 0) {
302		Py_DECREF(list);
303		list = NULL;
304	}
305	if (list) {
306		PyObject *v = PyList_AsTuple(list);
307		Py_DECREF(list);
308		list = v;
309	}
310	return list;
311}
312
313/* XXX This doc string is too long to be a single string literal in VC++ 5.0.
314   Two literals concatenated works just fine.  If you have a K&R compiler
315   or other abomination that however *does* understand longer strings,
316   get rid of the !!! comment in the middle and the quotes that surround it. */
317static char sys_doc[] =
318"This module provides access to some objects used or maintained by the\n\
319interpreter and to functions that interact strongly with the interpreter.\n\
320\n\
321Dynamic objects:\n\
322\n\
323argv -- command line arguments; argv[0] is the script pathname if known\n\
324path -- module search path; path[0] is the script directory, else ''\n\
325modules -- dictionary of loaded modules\n\
326exitfunc -- you may set this to a function to be called when Python exits\n\
327\n\
328stdin -- standard input file object; used by raw_input() and input()\n\
329stdout -- standard output file object; used by the print statement\n\
330stderr -- standard error object; used for error messages\n\
331  By assigning another file object (or an object that behaves like a file)\n\
332  to one of these, it is possible to redirect all of the interpreter's I/O.\n\
333\n\
334last_type -- type of last uncaught exception\n\
335last_value -- value of last uncaught exception\n\
336last_traceback -- traceback of last uncaught exception\n\
337  These three are only available in an interactive session after a\n\
338  traceback has been printed.\n\
339\n\
340exc_type -- type of exception currently being handled\n\
341exc_value -- value of exception currently being handled\n\
342exc_traceback -- traceback of exception currently being handled\n\
343  The function exc_info() should be used instead of these three,\n\
344  because it is thread-safe.\n\
345" /* !!! */ "\n\
346Static objects:\n\
347\n\
348maxint -- the largest supported integer (the smallest is -maxint-1)\n\
349builtin_module_names -- tuple of module names built into this intepreter\n\
350version -- the version of this interpreter\n\
351copyright -- copyright notice pertaining to this interpreter\n\
352platform -- platform identifier\n\
353executable -- pathname of this Python interpreter\n\
354prefix -- prefix used to find the Python library\n\
355exec_prefix -- prefix used to find the machine-specific Python library\n\
356dllhandle -- [Windows only] integer handle of the Python DLL\n\
357winver -- [Windows only] version number of the Python DLL\n\
358__stdin__ -- the original stdin; don't use!\n\
359__stdout__ -- the original stdout; don't use!\n\
360__stderr__ -- the original stderr; don't use!\n\
361\n\
362Functions:\n\
363\n\
364exc_info() -- return thread-safe information about the current exception\n\
365exit() -- exit the interpreter by raising SystemExit\n\
366getrefcount() -- return the reference count for an object (plus one :-)\n\
367setcheckinterval() -- control how often the interpreter checks for events\n\
368setprofile() -- set the global profiling function\n\
369settrace() -- set the global debug tracing function\n\
370";
371
372PyObject *
373_PySys_Init()
374{
375	extern int fclose Py_PROTO((FILE *));
376	PyObject *m, *v, *sysdict;
377	PyObject *sysin, *sysout, *syserr;
378
379	m = Py_InitModule3("sys", sys_methods, sys_doc);
380	sysdict = PyModule_GetDict(m);
381
382	sysin = PyFile_FromFile(stdin, "<stdin>", "r", NULL);
383	sysout = PyFile_FromFile(stdout, "<stdout>", "w", NULL);
384	syserr = PyFile_FromFile(stderr, "<stderr>", "w", NULL);
385	if (PyErr_Occurred())
386		return NULL;
387	PyDict_SetItemString(sysdict, "stdin", sysin);
388	PyDict_SetItemString(sysdict, "stdout", sysout);
389	PyDict_SetItemString(sysdict, "stderr", syserr);
390	/* Make backup copies for cleanup */
391	PyDict_SetItemString(sysdict, "__stdin__", sysin);
392	PyDict_SetItemString(sysdict, "__stdout__", sysout);
393	PyDict_SetItemString(sysdict, "__stderr__", syserr);
394	Py_XDECREF(sysin);
395	Py_XDECREF(sysout);
396	Py_XDECREF(syserr);
397	PyDict_SetItemString(sysdict, "version",
398			     v = PyString_FromString(Py_GetVersion()));
399	PyDict_SetItemString(sysdict, "hexversion",
400			     v = PyInt_FromLong(PY_VERSION_HEX));
401	Py_XDECREF(v);
402	PyDict_SetItemString(sysdict, "copyright",
403			     v = PyString_FromString(Py_GetCopyright()));
404	Py_XDECREF(v);
405	PyDict_SetItemString(sysdict, "platform",
406			     v = PyString_FromString(Py_GetPlatform()));
407	Py_XDECREF(v);
408	PyDict_SetItemString(sysdict, "executable",
409			     v = PyString_FromString(Py_GetProgramFullPath()));
410	Py_XDECREF(v);
411	PyDict_SetItemString(sysdict, "prefix",
412			     v = PyString_FromString(Py_GetPrefix()));
413	Py_XDECREF(v);
414	PyDict_SetItemString(sysdict, "exec_prefix",
415		   v = PyString_FromString(Py_GetExecPrefix()));
416	Py_XDECREF(v);
417	PyDict_SetItemString(sysdict, "maxint",
418			     v = PyInt_FromLong(PyInt_GetMax()));
419	Py_XDECREF(v);
420	PyDict_SetItemString(sysdict, "builtin_module_names",
421		   v = list_builtin_module_names());
422	Py_XDECREF(v);
423#ifdef MS_COREDLL
424	PyDict_SetItemString(sysdict, "dllhandle",
425			     v = PyInt_FromLong((int)PyWin_DLLhModule));
426	Py_XDECREF(v);
427	PyDict_SetItemString(sysdict, "winver",
428			     v = PyString_FromString(PyWin_DLLVersionString));
429	Py_XDECREF(v);
430#endif
431	if (PyErr_Occurred())
432		return NULL;
433	return m;
434}
435
436static PyObject *
437makepathobject(path, delim)
438	char *path;
439	int delim;
440{
441	int i, n;
442	char *p;
443	PyObject *v, *w;
444
445	n = 1;
446	p = path;
447	while ((p = strchr(p, delim)) != NULL) {
448		n++;
449		p++;
450	}
451	v = PyList_New(n);
452	if (v == NULL)
453		return NULL;
454	for (i = 0; ; i++) {
455		p = strchr(path, delim);
456		if (p == NULL)
457			p = strchr(path, '\0'); /* End of string */
458		w = PyString_FromStringAndSize(path, (int) (p - path));
459		if (w == NULL) {
460			Py_DECREF(v);
461			return NULL;
462		}
463		PyList_SetItem(v, i, w);
464		if (*p == '\0')
465			break;
466		path = p+1;
467	}
468	return v;
469}
470
471void
472PySys_SetPath(path)
473	char *path;
474{
475	PyObject *v;
476	if ((v = makepathobject(path, DELIM)) == NULL)
477		Py_FatalError("can't create sys.path");
478	if (PySys_SetObject("path", v) != 0)
479		Py_FatalError("can't assign sys.path");
480	Py_DECREF(v);
481}
482
483static PyObject *
484makeargvobject(argc, argv)
485	int argc;
486	char **argv;
487{
488	PyObject *av;
489	if (argc <= 0 || argv == NULL) {
490		/* Ensure at least one (empty) argument is seen */
491		static char *empty_argv[1] = {""};
492		argv = empty_argv;
493		argc = 1;
494	}
495	av = PyList_New(argc);
496	if (av != NULL) {
497		int i;
498		for (i = 0; i < argc; i++) {
499			PyObject *v = PyString_FromString(argv[i]);
500			if (v == NULL) {
501				Py_DECREF(av);
502				av = NULL;
503				break;
504			}
505			PyList_SetItem(av, i, v);
506		}
507	}
508	return av;
509}
510
511void
512PySys_SetArgv(argc, argv)
513	int argc;
514	char **argv;
515{
516	PyObject *av = makeargvobject(argc, argv);
517	PyObject *path = PySys_GetObject("path");
518	if (av == NULL)
519		Py_FatalError("no mem for sys.argv");
520	if (PySys_SetObject("argv", av) != 0)
521		Py_FatalError("can't assign sys.argv");
522	if (path != NULL) {
523		char *argv0 = argv[0];
524		char *p = NULL;
525		int n = 0;
526		PyObject *a;
527#ifdef HAVE_READLINK
528		char link[MAXPATHLEN+1];
529		char argv0copy[2*MAXPATHLEN+1];
530		int nr = 0;
531		if (argc > 0 && argv0 != NULL)
532			nr = readlink(argv0, link, MAXPATHLEN);
533		if (nr > 0) {
534			/* It's a symlink */
535			link[nr] = '\0';
536			if (link[0] == SEP)
537				argv0 = link; /* Link to absolute path */
538			else if (strchr(link, SEP) == NULL)
539				; /* Link without path */
540			else {
541				/* Must join(dirname(argv0), link) */
542				char *q = strrchr(argv0, SEP);
543				if (q == NULL)
544					argv0 = link; /* argv0 without path */
545				else {
546					/* Must make a copy */
547					strcpy(argv0copy, argv0);
548					q = strrchr(argv0copy, SEP);
549					strcpy(q+1, link);
550					argv0 = argv0copy;
551				}
552			}
553		}
554#endif /* HAVE_READLINK */
555#if SEP == '\\' /* Special case for MS filename syntax */
556		if (argc > 0 && argv0 != NULL) {
557			char *q;
558			p = strrchr(argv0, SEP);
559			/* Test for alternate separator */
560			q = strrchr(p ? p : argv0, '/');
561			if (q != NULL)
562				p = q;
563			if (p != NULL) {
564				n = p + 1 - argv0;
565				if (n > 1 && p[-1] != ':')
566					n--; /* Drop trailing separator */
567			}
568		}
569#else /* All other filename syntaxes */
570		if (argc > 0 && argv0 != NULL)
571			p = strrchr(argv0, SEP);
572		if (p != NULL) {
573			n = p + 1 - argv0;
574#if SEP == '/' /* Special case for Unix filename syntax */
575			if (n > 1)
576				n--; /* Drop trailing separator */
577#endif /* Unix */
578		}
579#endif /* All others */
580		a = PyString_FromStringAndSize(argv0, n);
581		if (a == NULL)
582			Py_FatalError("no mem for sys.path insertion");
583		if (PyList_Insert(path, 0, a) < 0)
584			Py_FatalError("sys.path.insert(0) failed");
585		Py_DECREF(a);
586	}
587	Py_DECREF(av);
588}
589
590
591/* APIs to write to sys.stdout or sys.stderr using a printf-like interface.
592   Adapted from code submitted by Just van Rossum.
593
594   PySys_WriteStdout(format, ...)
595   PySys_WriteStderr(format, ...)
596
597      The first function writes to sys.stdout; the second to sys.stderr.  When
598      there is a problem, they write to the real (C level) stdout or stderr;
599      no exceptions are raised.
600
601      Both take a printf-style format string as their first argument followed
602      by a variable length argument list determined by the format string.
603
604      *** WARNING ***
605
606      The format should limit the total size of the formatted output string to
607      1000 bytes.  In particular, this means that no unrestricted "%s" formats
608      should occur; these should be limited using "%.<N>s where <N> is a
609      decimal number calculated so that <N> plus the maximum size of other
610      formatted text does not exceed 1000 bytes.  Also watch out for "%f",
611      which can print hundreds of digits for very large numbers.
612
613 */
614
615static void
616mywrite(name, fp, format, va)
617	char *name;
618	FILE *fp;
619	const char *format;
620	va_list va;
621{
622	PyObject *file;
623	PyObject *error_type, *error_value, *error_traceback;
624
625	PyErr_Fetch(&error_type, &error_value, &error_traceback);
626	file = PySys_GetObject(name);
627	if (file == NULL || PyFile_AsFile(file) == fp)
628		vfprintf(fp, format, va);
629	else {
630		char buffer[1001];
631		if (vsprintf(buffer, format, va) >= sizeof(buffer))
632		    Py_FatalError("PySys_WriteStdout/err: buffer overrun");
633		if (PyFile_WriteString(buffer, file) != 0) {
634			PyErr_Clear();
635			fputs(buffer, fp);
636		}
637	}
638	PyErr_Restore(error_type, error_value, error_traceback);
639}
640
641void
642#ifdef HAVE_STDARG_PROTOTYPES
643PySys_WriteStdout(const char *format, ...)
644#else
645PySys_WriteStdout(va_alist)
646	va_dcl
647#endif
648{
649	va_list va;
650
651#ifdef HAVE_STDARG_PROTOTYPES
652	va_start(va, format);
653#else
654	char *format;
655	va_start(va);
656	format = va_arg(va, char *);
657#endif
658	mywrite("stdout", stdout, format, va);
659	va_end(va);
660}
661
662void
663#ifdef HAVE_STDARG_PROTOTYPES
664PySys_WriteStderr(const char *format, ...)
665#else
666PySys_WriteStderr(va_alist)
667	va_dcl
668#endif
669{
670	va_list va;
671
672#ifdef HAVE_STDARG_PROTOTYPES
673	va_start(va, format);
674#else
675	char *format;
676	va_start(va);
677	format = va_arg(va, char *);
678#endif
679	mywrite("stderr", stderr, format, va);
680	va_end(va);
681}
682