1 /* Python interpreter main program */
2 
3 #include "Python.h"
4 #include "osdefs.h"
5 #include "code.h" /* For CO_FUTURE_DIVISION */
6 #include "import.h"
7 
8 #ifdef __VMS
9 #include <unixlib.h>
10 #endif
11 
12 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
13 #ifdef HAVE_IO_H
14 #include <io.h>
15 #endif
16 #ifdef HAVE_FCNTL_H
17 #include <fcntl.h>
18 #endif
19 #endif
20 
21 #if (defined(PYOS_OS2) && !defined(PYCC_GCC)) || defined(MS_WINDOWS)
22 #define PYTHONHOMEHELP "<prefix>\\lib"
23 #else
24 #if defined(PYOS_OS2) && defined(PYCC_GCC)
25 #define PYTHONHOMEHELP "<prefix>/Lib"
26 #else
27 #define PYTHONHOMEHELP "<prefix>/pythonX.X"
28 #endif
29 #endif
30 
31 #include "pygetopt.h"
32 
33 #define COPYRIGHT \
34     "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
35     "for more information."
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /* For Py_GetArgcArgv(); set by main() */
42 static char **orig_argv;
43 static int  orig_argc;
44 
45 /* command line options */
46 #define BASE_OPTS "3bBc:dEhiJm:OQ:RsStuUvVW:xX?"
47 
48 #ifndef RISCOS
49 #define PROGRAM_OPTS BASE_OPTS
50 #else /*RISCOS*/
51 /* extra option saying that we are running under a special task window
52    frontend; especially my_readline will behave different */
53 #define PROGRAM_OPTS BASE_OPTS "w"
54 /* corresponding flag */
55 extern int Py_RISCOSWimpFlag;
56 #endif /*RISCOS*/
57 
58 /* Short usage message (with %s for argv0) */
59 static char *usage_line =
60 "usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
61 
62 /* Long usage message, split into parts < 512 bytes */
63 static char *usage_1 = "\
64 Options and arguments (and corresponding environment variables):\n\
65 -b     : issue warnings about comparing bytearray with unicode\n\
66          (-bb: issue errors)\n\
67 -B     : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\
68 -c cmd : program passed in as string (terminates option list)\n\
69 -d     : debug output from parser; also PYTHONDEBUG=x\n\
70 -E     : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
71 -h     : print this help message and exit (also --help)\n\
72 -i     : inspect interactively after running script; forces a prompt even\n\
73 ";
74 static char *usage_2 = "\
75          if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
76 -m mod : run library module as a script (terminates option list)\n\
77 -O     : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\
78 -OO    : remove doc-strings in addition to the -O optimizations\n\
79 -R     : use a pseudo-random salt to make hash() values of various types be\n\
80          unpredictable between separate invocations of the interpreter, as\n\
81          a defense against denial-of-service attacks\n\
82 -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\
83 -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
84 -S     : don't imply 'import site' on initialization\n\
85 -t     : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
86 ";
87 static char *usage_3 = "\
88 -u     : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\
89          see man page for details on internal buffering relating to '-u'\n\
90 -v     : verbose (trace import statements); also PYTHONVERBOSE=x\n\
91          can be supplied multiple times to increase verbosity\n\
92 -V     : print the Python version number and exit (also --version)\n\
93 -W arg : warning control; arg is action:message:category:module:lineno\n\
94          also PYTHONWARNINGS=arg\n\
95 -x     : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
96 ";
97 static char *usage_4 = "\
98 -3     : warn about Python 3.x incompatibilities that 2to3 cannot trivially fix\n\
99 file   : program read from script file\n\
100 -      : program read from stdin (default; interactive mode if a tty)\n\
101 arg ...: arguments passed to program in sys.argv[1:]\n\n\
102 Other environment variables:\n\
103 PYTHONSTARTUP: file executed on interactive startup (no default)\n\
104 PYTHONPATH   : '%c'-separated list of directories prefixed to the\n\
105                default module search path.  The result is sys.path.\n\
106 ";
107 static char *usage_5 = "\
108 PYTHONHOME   : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
109                The default module search path uses %s.\n\
110 PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
111 PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n\
112 ";
113 static char *usage_6 = "\
114 PYTHONHASHSEED: if this variable is set to 'random', the effect is the same\n\
115    as specifying the -R option: a random value is used to seed the hashes of\n\
116    str, bytes and datetime objects.  It can also be set to an integer\n\
117    in the range [0,4294967295] to get hash values with a predictable seed.\n\
118 ";
119 
120 
121 static int
usage(int exitcode,char * program)122 usage(int exitcode, char* program)
123 {
124     FILE *f = exitcode ? stderr : stdout;
125 
126     fprintf(f, usage_line, program);
127     if (exitcode)
128         fprintf(f, "Try `python -h' for more information.\n");
129     else {
130         fputs(usage_1, f);
131         fputs(usage_2, f);
132         fputs(usage_3, f);
133         fprintf(f, usage_4, DELIM);
134         fprintf(f, usage_5, DELIM, PYTHONHOMEHELP);
135         fputs(usage_6, f);
136     }
137 #if defined(__VMS)
138     if (exitcode == 0) {
139         /* suppress 'error' message */
140         return 1;
141     }
142     else {
143         /* STS$M_INHIB_MSG + SS$_ABORT */
144         return 0x1000002c;
145     }
146 #else
147     return exitcode;
148 #endif
149     /*NOTREACHED*/
150 }
151 
RunStartupFile(PyCompilerFlags * cf)152 static void RunStartupFile(PyCompilerFlags *cf)
153 {
154     char *startup = Py_GETENV("PYTHONSTARTUP");
155     if (startup != NULL && startup[0] != '\0') {
156         FILE *fp = fopen(startup, "r");
157         if (fp != NULL) {
158             (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
159             PyErr_Clear();
160             fclose(fp);
161         } else {
162             int save_errno;
163             save_errno = errno;
164             PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
165             errno = save_errno;
166             PyErr_SetFromErrnoWithFilename(PyExc_IOError,
167                                            startup);
168             PyErr_Print();
169             PyErr_Clear();
170         }
171     }
172 }
173 
174 
RunModule(char * module,int set_argv0)175 static int RunModule(char *module, int set_argv0)
176 {
177     PyObject *runpy, *runmodule, *runargs, *result;
178     runpy = PyImport_ImportModule("runpy");
179     if (runpy == NULL) {
180         fprintf(stderr, "Could not import runpy module\n");
181         return -1;
182     }
183     runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
184     if (runmodule == NULL) {
185         fprintf(stderr, "Could not access runpy._run_module_as_main\n");
186         Py_DECREF(runpy);
187         return -1;
188     }
189     runargs = Py_BuildValue("(si)", module, set_argv0);
190     if (runargs == NULL) {
191         fprintf(stderr,
192             "Could not create arguments for runpy._run_module_as_main\n");
193         Py_DECREF(runpy);
194         Py_DECREF(runmodule);
195         return -1;
196     }
197     result = PyObject_Call(runmodule, runargs, NULL);
198     if (result == NULL) {
199         PyErr_Print();
200     }
201     Py_DECREF(runpy);
202     Py_DECREF(runmodule);
203     Py_DECREF(runargs);
204     if (result == NULL) {
205         return -1;
206     }
207     Py_DECREF(result);
208     return 0;
209 }
210 
RunMainFromImporter(char * filename)211 static int RunMainFromImporter(char *filename)
212 {
213     PyObject *argv0 = NULL, *importer = NULL;
214 
215     if ((argv0 = PyString_FromString(filename)) &&
216         (importer = PyImport_GetImporter(argv0)) &&
217         (importer->ob_type != &PyNullImporter_Type))
218     {
219              /* argv0 is usable as an import source, so
220                     put it in sys.path[0] and import __main__ */
221         PyObject *sys_path = NULL;
222         if ((sys_path = PySys_GetObject("path")) &&
223             !PyList_SetItem(sys_path, 0, argv0))
224         {
225             Py_INCREF(argv0);
226             Py_DECREF(importer);
227             sys_path = NULL;
228             return RunModule("__main__", 0) != 0;
229         }
230     }
231     Py_XDECREF(argv0);
232     Py_XDECREF(importer);
233     if (PyErr_Occurred()) {
234         PyErr_Print();
235         return 1;
236     }
237     return -1;
238 }
239 
240 
241 /* Main program */
242 
243 int
Py_Main(int argc,char ** argv)244 Py_Main(int argc, char **argv)
245 {
246     int c;
247     int sts;
248     char *command = NULL;
249     char *filename = NULL;
250     char *module = NULL;
251     FILE *fp = stdin;
252     char *p;
253     int unbuffered = 0;
254     int skipfirstline = 0;
255     int stdin_is_interactive = 0;
256     int help = 0;
257     int version = 0;
258     int saw_unbuffered_flag = 0;
259     PyCompilerFlags cf;
260 
261     cf.cf_flags = 0;
262 
263     orig_argc = argc;           /* For Py_GetArgcArgv() */
264     orig_argv = argv;
265 
266 #ifdef RISCOS
267     Py_RISCOSWimpFlag = 0;
268 #endif
269 
270     /* Hash randomization needed early for all string operations
271        (including -W and -X options). */
272     _PyOS_opterr = 0;  /* prevent printing the error in 1st pass */
273     while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
274         if (c == 'm' || c == 'c') {
275             /* -c / -m is the last option: following arguments are
276                not interpreter options. */
277             break;
278         }
279         switch (c) {
280         case 'E':
281             Py_IgnoreEnvironmentFlag++;
282             break;
283         case 'R':
284             Py_HashRandomizationFlag++;
285             break;
286         }
287     }
288     /* The variable is only tested for existence here; _PyRandom_Init will
289        check its value further. */
290     if (!Py_HashRandomizationFlag &&
291         (p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0')
292         Py_HashRandomizationFlag = 1;
293 
294     _PyRandom_Init();
295 
296     PySys_ResetWarnOptions();
297     _PyOS_ResetGetOpt();
298 
299     while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
300         if (c == 'c') {
301             /* -c is the last option; following arguments
302                that look like options are left for the
303                command to interpret. */
304             command = (char *)malloc(strlen(_PyOS_optarg) + 2);
305             if (command == NULL)
306                 Py_FatalError(
307                    "not enough memory to copy -c argument");
308             strcpy(command, _PyOS_optarg);
309             strcat(command, "\n");
310             break;
311         }
312 
313         if (c == 'm') {
314             /* -m is the last option; following arguments
315                that look like options are left for the
316                module to interpret. */
317             module = (char *)malloc(strlen(_PyOS_optarg) + 2);
318             if (module == NULL)
319                 Py_FatalError(
320                    "not enough memory to copy -m argument");
321             strcpy(module, _PyOS_optarg);
322             break;
323         }
324 
325         switch (c) {
326         case 'b':
327             Py_BytesWarningFlag++;
328             break;
329 
330         case 'd':
331             Py_DebugFlag++;
332             break;
333 
334         case '3':
335             Py_Py3kWarningFlag++;
336             if (!Py_DivisionWarningFlag)
337                 Py_DivisionWarningFlag = 1;
338             break;
339 
340         case 'Q':
341             if (strcmp(_PyOS_optarg, "old") == 0) {
342                 Py_DivisionWarningFlag = 0;
343                 break;
344             }
345             if (strcmp(_PyOS_optarg, "warn") == 0) {
346                 Py_DivisionWarningFlag = 1;
347                 break;
348             }
349             if (strcmp(_PyOS_optarg, "warnall") == 0) {
350                 Py_DivisionWarningFlag = 2;
351                 break;
352             }
353             if (strcmp(_PyOS_optarg, "new") == 0) {
354                 /* This only affects __main__ */
355                 cf.cf_flags |= CO_FUTURE_DIVISION;
356                 /* And this tells the eval loop to treat
357                    BINARY_DIVIDE as BINARY_TRUE_DIVIDE */
358                 _Py_QnewFlag = 1;
359                 break;
360             }
361             fprintf(stderr,
362                 "-Q option should be `-Qold', "
363                 "`-Qwarn', `-Qwarnall', or `-Qnew' only\n");
364             return usage(2, argv[0]);
365             /* NOTREACHED */
366 
367         case 'i':
368             Py_InspectFlag++;
369             Py_InteractiveFlag++;
370             break;
371 
372         /* case 'J': reserved for Jython */
373 
374         case 'O':
375             Py_OptimizeFlag++;
376             break;
377 
378         case 'B':
379             Py_DontWriteBytecodeFlag++;
380             break;
381 
382         case 's':
383             Py_NoUserSiteDirectory++;
384             break;
385 
386         case 'S':
387             Py_NoSiteFlag++;
388             break;
389 
390         case 'E':
391             /* Already handled above */
392             break;
393 
394         case 't':
395             Py_TabcheckFlag++;
396             break;
397 
398         case 'u':
399             unbuffered++;
400             saw_unbuffered_flag = 1;
401             break;
402 
403         case 'v':
404             Py_VerboseFlag++;
405             break;
406 
407 #ifdef RISCOS
408         case 'w':
409             Py_RISCOSWimpFlag = 1;
410             break;
411 #endif
412 
413         case 'x':
414             skipfirstline = 1;
415             break;
416 
417         /* case 'X': reserved for implementation-specific arguments */
418 
419         case 'U':
420             Py_UnicodeFlag++;
421             break;
422         case 'h':
423         case '?':
424             help++;
425             break;
426         case 'V':
427             version++;
428             break;
429 
430         case 'W':
431             PySys_AddWarnOption(_PyOS_optarg);
432             break;
433 
434         case 'R':
435             /* Already handled above */
436             break;
437 
438         /* This space reserved for other options */
439 
440         default:
441             return usage(2, argv[0]);
442             /*NOTREACHED*/
443 
444         }
445     }
446 
447     if (help)
448         return usage(0, argv[0]);
449 
450     if (version) {
451         fprintf(stderr, "Python %s\n", PY_VERSION);
452         return 0;
453     }
454 
455     if (Py_Py3kWarningFlag && !Py_TabcheckFlag)
456         /* -3 implies -t (but not -tt) */
457         Py_TabcheckFlag = 1;
458 
459     if (!Py_InspectFlag &&
460         (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
461         Py_InspectFlag = 1;
462     if (!saw_unbuffered_flag &&
463         (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
464         unbuffered = 1;
465 
466     if (!Py_NoUserSiteDirectory &&
467         (p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0')
468         Py_NoUserSiteDirectory = 1;
469 
470     if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {
471         char *buf, *warning;
472 
473         buf = (char *)malloc(strlen(p) + 1);
474         if (buf == NULL)
475             Py_FatalError(
476                "not enough memory to copy PYTHONWARNINGS");
477         strcpy(buf, p);
478         for (warning = strtok(buf, ",");
479              warning != NULL;
480              warning = strtok(NULL, ","))
481             PySys_AddWarnOption(warning);
482         free(buf);
483     }
484 
485     if (command == NULL && module == NULL && _PyOS_optind < argc &&
486         strcmp(argv[_PyOS_optind], "-") != 0)
487     {
488 #ifdef __VMS
489         filename = decc$translate_vms(argv[_PyOS_optind]);
490         if (filename == (char *)0 || filename == (char *)-1)
491             filename = argv[_PyOS_optind];
492 
493 #else
494         filename = argv[_PyOS_optind];
495 #endif
496     }
497 
498     stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
499 
500     if (unbuffered) {
501 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
502         _setmode(fileno(stdin), O_BINARY);
503         _setmode(fileno(stdout), O_BINARY);
504 #endif
505 #ifdef HAVE_SETVBUF
506         setvbuf(stdin,  (char *)NULL, _IONBF, BUFSIZ);
507         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
508         setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
509 #else /* !HAVE_SETVBUF */
510         setbuf(stdin,  (char *)NULL);
511         setbuf(stdout, (char *)NULL);
512         setbuf(stderr, (char *)NULL);
513 #endif /* !HAVE_SETVBUF */
514     }
515     else if (Py_InteractiveFlag) {
516 #ifdef MS_WINDOWS
517         /* Doesn't have to have line-buffered -- use unbuffered */
518         /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
519         setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
520 #else /* !MS_WINDOWS */
521 #ifdef HAVE_SETVBUF
522         setvbuf(stdin,  (char *)NULL, _IOLBF, BUFSIZ);
523         setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
524 #endif /* HAVE_SETVBUF */
525 #endif /* !MS_WINDOWS */
526         /* Leave stderr alone - it should be unbuffered anyway. */
527     }
528 #ifdef __VMS
529     else {
530         setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);
531     }
532 #endif /* __VMS */
533 
534 #ifdef __APPLE__
535     /* On MacOS X, when the Python interpreter is embedded in an
536        application bundle, it gets executed by a bootstrapping script
537        that does os.execve() with an argv[0] that's different from the
538        actual Python executable. This is needed to keep the Finder happy,
539        or rather, to work around Apple's overly strict requirements of
540        the process name. However, we still need a usable sys.executable,
541        so the actual executable path is passed in an environment variable.
542        See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
543        script. */
544     if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0')
545         Py_SetProgramName(p);
546     else
547         Py_SetProgramName(argv[0]);
548 #else
549     Py_SetProgramName(argv[0]);
550 #endif
551     Py_Initialize();
552 
553     if (Py_VerboseFlag ||
554         (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) {
555         fprintf(stderr, "Python %s on %s\n",
556             Py_GetVersion(), Py_GetPlatform());
557         if (!Py_NoSiteFlag)
558             fprintf(stderr, "%s\n", COPYRIGHT);
559     }
560 
561     if (command != NULL) {
562         /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
563         _PyOS_optind--;
564         argv[_PyOS_optind] = "-c";
565     }
566 
567     if (module != NULL) {
568         /* Backup _PyOS_optind and force sys.argv[0] = '-c'
569            so that PySys_SetArgv correctly sets sys.path[0] to ''
570            rather than looking for a file called "-m". See
571            tracker issue #8202 for details. */
572         _PyOS_optind--;
573         argv[_PyOS_optind] = "-c";
574     }
575 
576     PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
577 
578     if ((Py_InspectFlag || (command == NULL && filename == NULL && module == NULL)) &&
579         isatty(fileno(stdin))) {
580         PyObject *v;
581         v = PyImport_ImportModule("readline");
582         if (v == NULL)
583             PyErr_Clear();
584         else
585             Py_DECREF(v);
586     }
587 
588     if (command) {
589         sts = PyRun_SimpleStringFlags(command, &cf) != 0;
590         free(command);
591     } else if (module) {
592         sts = (RunModule(module, 1) != 0);
593         free(module);
594     }
595     else {
596 
597         if (filename == NULL && stdin_is_interactive) {
598             Py_InspectFlag = 0; /* do exit on SystemExit */
599             RunStartupFile(&cf);
600         }
601         /* XXX */
602 
603         sts = -1;               /* keep track of whether we've already run __main__ */
604 
605         if (filename != NULL) {
606             sts = RunMainFromImporter(filename);
607         }
608 
609         if (sts==-1 && filename!=NULL) {
610             if ((fp = fopen(filename, "r")) == NULL) {
611                 fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
612                     argv[0], filename, errno, strerror(errno));
613 
614                 return 2;
615             }
616             else if (skipfirstline) {
617                 int ch;
618                 /* Push back first newline so line numbers
619                    remain the same */
620                 while ((ch = getc(fp)) != EOF) {
621                     if (ch == '\n') {
622                         (void)ungetc(ch, fp);
623                         break;
624                     }
625                 }
626             }
627             {
628                 /* XXX: does this work on Win/Win64? (see posix_fstat) */
629                 struct stat sb;
630                 if (fstat(fileno(fp), &sb) == 0 &&
631                     S_ISDIR(sb.st_mode)) {
632                     fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);
633                     fclose(fp);
634                     return 1;
635                 }
636             }
637         }
638 
639         if (sts==-1) {
640             /* call pending calls like signal handlers (SIGINT) */
641             if (Py_MakePendingCalls() == -1) {
642                 PyErr_Print();
643                 sts = 1;
644             } else {
645                 sts = PyRun_AnyFileExFlags(
646                     fp,
647                     filename == NULL ? "<stdin>" : filename,
648                     filename != NULL, &cf) != 0;
649             }
650         }
651 
652     }
653 
654     /* Check this environment variable at the end, to give programs the
655      * opportunity to set it from Python.
656      */
657     if (!Py_InspectFlag &&
658         (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
659     {
660         Py_InspectFlag = 1;
661     }
662 
663     if (Py_InspectFlag && stdin_is_interactive &&
664         (filename != NULL || command != NULL || module != NULL)) {
665         Py_InspectFlag = 0;
666         /* XXX */
667         sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
668     }
669 
670     Py_Finalize();
671 #ifdef RISCOS
672     if (Py_RISCOSWimpFlag)
673         fprintf(stderr, "\x0cq\x0c"); /* make frontend quit */
674 #endif
675 
676 #ifdef __INSURE__
677     /* Insure++ is a memory analysis tool that aids in discovering
678      * memory leaks and other memory problems.  On Python exit, the
679      * interned string dictionary is flagged as being in use at exit
680      * (which it is).  Under normal circumstances, this is fine because
681      * the memory will be automatically reclaimed by the system.  Under
682      * memory debugging, it's a huge source of useless noise, so we
683      * trade off slower shutdown for less distraction in the memory
684      * reports.  -baw
685      */
686     _Py_ReleaseInternedStrings();
687 #endif /* __INSURE__ */
688 
689     return sts;
690 }
691 
692 /* this is gonna seem *real weird*, but if you put some other code between
693    Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
694    while statement in Misc/gdbinit:ppystack */
695 
696 /* Make the *original* argc/argv available to other modules.
697    This is rare, but it is needed by the secureware extension. */
698 
699 void
Py_GetArgcArgv(int * argc,char *** argv)700 Py_GetArgcArgv(int *argc, char ***argv)
701 {
702     *argc = orig_argc;
703     *argv = orig_argv;
704 }
705 
706 #ifdef __cplusplus
707 }
708 #endif
709 
710