sysmodule.c revision bb5c6f8529c89d2396a3e3c06cf575a130ff7a0e
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 51PyObject *_PySys_TraceFunc, *_PySys_ProfileFunc; 52int _PySys_CheckInterval = 10; 53 54#if HAVE_UNISTD_H 55#include <unistd.h> 56#endif 57 58static PyObject *sysdict; 59 60#ifdef MS_COREDLL 61extern void *PyWin_DLLhModule; 62#endif 63 64PyObject * 65PySys_GetObject(name) 66 char *name; 67{ 68 return PyDict_GetItemString(sysdict, name); 69} 70 71FILE * 72PySys_GetFile(name, def) 73 char *name; 74 FILE *def; 75{ 76 FILE *fp = NULL; 77 PyObject *v = PySys_GetObject(name); 78 if (v != NULL && PyFile_Check(v)) 79 fp = PyFile_AsFile(v); 80 if (fp == NULL) 81 fp = def; 82 return fp; 83} 84 85int 86PySys_SetObject(name, v) 87 char *name; 88 PyObject *v; 89{ 90 if (v == NULL) { 91 if (PyDict_GetItemString(sysdict, name) == NULL) 92 return 0; 93 else 94 return PyDict_DelItemString(sysdict, name); 95 } 96 else 97 return PyDict_SetItemString(sysdict, name, v); 98} 99 100static PyObject * 101sys_exit(self, args) 102 PyObject *self; 103 PyObject *args; 104{ 105 /* Raise SystemExit so callers may catch it or clean up. */ 106 PyErr_SetObject(PyExc_SystemExit, args); 107 return NULL; 108} 109 110static PyObject * 111sys_settrace(self, args) 112 PyObject *self; 113 PyObject *args; 114{ 115 if (args == Py_None) 116 args = NULL; 117 else 118 Py_XINCREF(args); 119 Py_XDECREF(_PySys_TraceFunc); 120 _PySys_TraceFunc = args; 121 Py_INCREF(Py_None); 122 return Py_None; 123} 124 125static PyObject * 126sys_setprofile(self, args) 127 PyObject *self; 128 PyObject *args; 129{ 130 if (args == Py_None) 131 args = NULL; 132 else 133 Py_XINCREF(args); 134 Py_XDECREF(_PySys_ProfileFunc); 135 _PySys_ProfileFunc = args; 136 Py_INCREF(Py_None); 137 return Py_None; 138} 139 140static PyObject * 141sys_setcheckinterval(self, args) 142 PyObject *self; 143 PyObject *args; 144{ 145 if (!PyArg_ParseTuple(args, "i", &_PySys_CheckInterval)) 146 return NULL; 147 Py_INCREF(Py_None); 148 return Py_None; 149} 150 151#ifdef USE_MALLOPT 152/* Link with -lmalloc (or -lmpc) on an SGI */ 153#include <malloc.h> 154 155static PyObject * 156sys_mdebug(self, args) 157 PyObject *self; 158 PyObject *args; 159{ 160 int flag; 161 if (!PyArg_Parse(args, "i", &flag)) 162 return NULL; 163 mallopt(M_DEBUG, flag); 164 Py_INCREF(Py_None); 165 return Py_None; 166} 167#endif /* USE_MALLOPT */ 168 169static PyObject * 170sys_getrefcount(self, args) 171 PyObject *self; 172 PyObject *args; 173{ 174 PyObject *arg; 175 if (!PyArg_Parse(args, "O", &arg)) 176 return NULL; 177 return PyInt_FromLong((long) arg->ob_refcnt); 178} 179 180#ifdef COUNT_ALLOCS 181static PyObject * 182sys_getcounts(self, args) 183 PyObject *self, *args; 184{ 185 extern PyObject *get_counts Py_PROTO((void)); 186 187 if (!PyArg_Parse(args, "")) 188 return NULL; 189 return get_counts(); 190} 191#endif 192 193#ifdef Py_TRACE_REFS 194/* Defined in objects.c because it uses static globals if that file */ 195extern PyObject *_Py_GetObjects Py_PROTO((PyObject *, PyObject *)); 196#endif 197 198#ifdef DYNAMIC_EXECUTION_PROFILE 199/* Defined in ceval.c because it uses static globals if that file */ 200extern PyObject *_Py_GetDXProfile Py_PROTO((PyObject *, PyObject *)); 201#endif 202 203static PyMethodDef sys_methods[] = { 204 /* Might as well keep this in alphabetic order */ 205 {"exit", sys_exit, 0}, 206#ifdef COUNT_ALLOCS 207 {"getcounts", sys_getcounts, 0}, 208#endif 209#ifdef DYNAMIC_EXECUTION_PROFILE 210 {"getdxp", _Py_GetDXProfile, 1}, 211#endif 212#ifdef Py_TRACE_REFS 213 {"getobjects", _Py_GetObjects, 1}, 214#endif 215 {"getrefcount", sys_getrefcount, 0}, 216#ifdef USE_MALLOPT 217 {"mdebug", sys_mdebug, 0}, 218#endif 219 {"setcheckinterval", sys_setcheckinterval, 1}, 220 {"setprofile", sys_setprofile, 0}, 221 {"settrace", sys_settrace, 0}, 222 {NULL, NULL} /* sentinel */ 223}; 224 225static PyObject *sysin, *sysout, *syserr; 226 227static PyObject * 228list_builtin_module_names() 229{ 230 PyObject *list = PyList_New(0); 231 int i; 232 if (list == NULL) 233 return NULL; 234 for (i = 0; _PyImport_Inittab[i].name != NULL; i++) { 235 PyObject *name = PyString_FromString(_PyImport_Inittab[i].name); 236 if (name == NULL) 237 break; 238 PyList_Append(list, name); 239 Py_DECREF(name); 240 } 241 if (PyList_Sort(list) != 0) { 242 Py_DECREF(list); 243 list = NULL; 244 } 245 if (list) { 246 PyObject *v = PyList_AsTuple(list); 247 Py_DECREF(list); 248 list = v; 249 } 250 return list; 251} 252 253void 254PySys_Init() 255{ 256 extern long PyInt_GetMax Py_PROTO((void)); 257 extern char *Py_GetVersion Py_PROTO((void)); 258 extern char *Py_GetCopyright Py_PROTO((void)); 259 extern char *Py_GetPlatform Py_PROTO((void)); 260 extern char *Py_GetPrefix Py_PROTO((void)); 261 extern char *Py_GetExecPrefix Py_PROTO((void)); 262 extern int fclose Py_PROTO((FILE *)); 263 PyObject *m = Py_InitModule("sys", sys_methods); 264 PyObject *v; 265 sysdict = PyModule_GetDict(m); 266 Py_INCREF(sysdict); 267 /* NB keep an extra ref to the std files to avoid closing them 268 when the user deletes them */ 269 sysin = PyFile_FromFile(stdin, "<stdin>", "r", fclose); 270 sysout = PyFile_FromFile(stdout, "<stdout>", "w", fclose); 271 syserr = PyFile_FromFile(stderr, "<stderr>", "w", fclose); 272 if (PyErr_Occurred()) 273 Py_FatalError("can't initialize sys.std{in,out,err}"); 274 PyDict_SetItemString(sysdict, "stdin", sysin); 275 PyDict_SetItemString(sysdict, "stdout", sysout); 276 PyDict_SetItemString(sysdict, "stderr", syserr); 277 PyDict_SetItemString(sysdict, "version", 278 v = PyString_FromString(Py_GetVersion())); 279 Py_XDECREF(v); 280 PyDict_SetItemString(sysdict, "copyright", 281 v = PyString_FromString(Py_GetCopyright())); 282 Py_XDECREF(v); 283 PyDict_SetItemString(sysdict, "platform", 284 v = PyString_FromString(Py_GetPlatform())); 285 Py_XDECREF(v); 286 PyDict_SetItemString(sysdict, "prefix", 287 v = PyString_FromString(Py_GetPrefix())); 288 Py_XDECREF(v); 289 PyDict_SetItemString(sysdict, "exec_prefix", 290 v = PyString_FromString(Py_GetExecPrefix())); 291 Py_XDECREF(v); 292 PyDict_SetItemString(sysdict, "maxint", 293 v = PyInt_FromLong(PyInt_GetMax())); 294 Py_XDECREF(v); 295 PyDict_SetItemString(sysdict, "modules", PyImport_GetModuleDict()); 296 PyDict_SetItemString(sysdict, "builtin_module_names", 297 v = list_builtin_module_names()); 298 Py_XDECREF(v); 299#ifdef MS_COREDLL 300 PyDict_SetItemString(sysdict, "dllhandle", 301 v = PyInt_FromLong((int)PyWin_DLLhModule)); 302 Py_XDECREF(v); 303 PyDict_SetItemString(sysdict, "winver", 304 v = PyString_FromString(MS_DLL_ID)); 305 Py_XDECREF(v); 306#endif 307 if (PyErr_Occurred()) 308 Py_FatalError("can't insert sys.* objects in sys dict"); 309} 310 311static PyObject * 312makepathobject(path, delim) 313 char *path; 314 int delim; 315{ 316 int i, n; 317 char *p; 318 PyObject *v, *w; 319 320 n = 1; 321 p = path; 322 while ((p = strchr(p, delim)) != NULL) { 323 n++; 324 p++; 325 } 326 v = PyList_New(n); 327 if (v == NULL) 328 return NULL; 329 for (i = 0; ; i++) { 330 p = strchr(path, delim); 331 if (p == NULL) 332 p = strchr(path, '\0'); /* End of string */ 333 w = PyString_FromStringAndSize(path, (int) (p - path)); 334 if (w == NULL) { 335 Py_DECREF(v); 336 return NULL; 337 } 338 PyList_SetItem(v, i, w); 339 if (*p == '\0') 340 break; 341 path = p+1; 342 } 343 return v; 344} 345 346void 347PySys_SetPath(path) 348 char *path; 349{ 350 PyObject *v; 351 if ((v = makepathobject(path, DELIM)) == NULL) 352 Py_FatalError("can't create sys.path"); 353 if (PySys_SetObject("path", v) != 0) 354 Py_FatalError("can't assign sys.path"); 355 Py_DECREF(v); 356} 357 358static PyObject * 359makeargvobject(argc, argv) 360 int argc; 361 char **argv; 362{ 363 PyObject *av; 364 if (argc <= 0 || argv == NULL) { 365 /* Ensure at least one (empty) argument is seen */ 366 static char *empty_argv[1] = {""}; 367 argv = empty_argv; 368 argc = 1; 369 } 370 av = PyList_New(argc); 371 if (av != NULL) { 372 int i; 373 for (i = 0; i < argc; i++) { 374 PyObject *v = PyString_FromString(argv[i]); 375 if (v == NULL) { 376 Py_DECREF(av); 377 av = NULL; 378 break; 379 } 380 PyList_SetItem(av, i, v); 381 } 382 } 383 return av; 384} 385 386void 387PySys_SetArgv(argc, argv) 388 int argc; 389 char **argv; 390{ 391 PyObject *av = makeargvobject(argc, argv); 392 PyObject *path = PySys_GetObject("path"); 393 if (av == NULL) 394 Py_FatalError("no mem for sys.argv"); 395 if (PySys_SetObject("argv", av) != 0) 396 Py_FatalError("can't assign sys.argv"); 397 if (path != NULL) { 398 char *argv0 = argv[0]; 399 char *p = NULL; 400 int n = 0; 401 PyObject *a; 402#ifdef HAVE_READLINK 403 char link[MAXPATHLEN+1]; 404 char argv0copy[2*MAXPATHLEN+1]; 405 int nr = 0; 406 if (argc > 0 && argv0 != NULL) 407 nr = readlink(argv0, link, MAXPATHLEN); 408 if (nr > 0) { 409 /* It's a symlink */ 410 link[nr] = '\0'; 411 if (link[0] == SEP) 412 argv0 = link; /* Link to absolute path */ 413 else if (strchr(link, SEP) == NULL) 414 ; /* Link without path */ 415 else { 416 /* Must join(dirname(argv0), link) */ 417 char *q = strrchr(argv0, SEP); 418 if (q == NULL) 419 argv0 = link; /* argv0 without path */ 420 else { 421 /* Must make a copy */ 422 strcpy(argv0copy, argv0); 423 q = strrchr(argv0copy, SEP); 424 strcpy(q+1, link); 425 argv0 = argv0copy; 426 } 427 } 428 } 429#endif /* HAVE_READLINK */ 430#if SEP == '\\' /* Special case for MS filename syntax */ 431 if (argc > 0 && argv0 != NULL) { 432 char *q; 433 p = strrchr(argv0, SEP); 434 /* Test for alternate separator */ 435 q = strrchr(p ? p : argv0, '/'); 436 if (q != NULL) 437 p = q; 438 if (p != NULL) { 439 n = p + 1 - argv0; 440 if (n > 1 && p[-1] != ':') 441 n--; /* Drop trailing separator */ 442 } 443 } 444#else /* All other filename syntaxes */ 445 if (argc > 0 && argv0 != NULL) 446 p = strrchr(argv0, SEP); 447 if (p != NULL) { 448 n = p + 1 - argv0; 449#if SEP == '/' /* Special case for Unix filename syntax */ 450 if (n > 1) 451 n--; /* Drop trailing separator */ 452#endif /* Unix */ 453 } 454#endif /* All others */ 455 a = PyString_FromStringAndSize(argv0, n); 456 if (a == NULL) 457 Py_FatalError("no mem for sys.path insertion"); 458 if (PyList_Insert(path, 0, a) < 0) 459 Py_FatalError("sys.path.insert(0) failed"); 460 Py_DECREF(a); 461 } 462 Py_DECREF(av); 463} 464