diff --git a/Include/pygetopt.h b/Include/pygetopt.h index 80908bea982..9860d360e1e 100644 --- a/Include/pygetopt.h +++ b/Include/pygetopt.h @@ -9,6 +9,7 @@ PyAPI_DATA(int) _PyOS_opterr; PyAPI_DATA(int) _PyOS_optind; PyAPI_DATA(char *) _PyOS_optarg; +PyAPI_FUNC(void) _PyOS_ResetGetOpt(void); PyAPI_FUNC(int) _PyOS_GetOpt(int argc, char **argv, char *optstring); #ifdef __cplusplus diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 7a29c085f68..6bfc1750500 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -128,6 +128,7 @@ PyAPI_FUNC(int) _PyInt_Init(void); PyAPI_FUNC(int) _PyLong_Init(void); PyAPI_FUNC(void) _PyFloat_Init(void); PyAPI_FUNC(int) PyByteArray_Init(void); +PyAPI_FUNC(void) _PyRandom_Init(void); /* Various internal finalizers */ PyAPI_FUNC(void) _PyExc_Fini(void); diff --git a/Modules/main.c b/Modules/main.c index 824badafbe0..b57241ea435 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -262,7 +262,33 @@ Py_Main(int argc, char **argv) Py_RISCOSWimpFlag = 0; #endif + /* Hash randomization needed early for all string operations + (including -W and -X options). */ + while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) { + if (c == 'm' || c == 'c') { + /* -c / -m is the last option: following arguments are + not interpreter options. */ + break; + } + switch (c) { + case 'E': + Py_IgnoreEnvironmentFlag++; + break; + case 'R': + Py_HashRandomizationFlag++; + break; + } + } + /* The variable is only tested for existence here; _PyRandom_Init will + check its value further. */ + if (!Py_HashRandomizationFlag && + (p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') + Py_HashRandomizationFlag = 1; + + _PyRandom_Init(); + PySys_ResetWarnOptions(); + _PyOS_ResetGetOpt(); while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) { if (c == 'c') { @@ -356,7 +382,7 @@ Py_Main(int argc, char **argv) break; case 'E': - Py_IgnoreEnvironmentFlag++; + /* Already handled above */ break; case 't': @@ -406,7 +432,7 @@ Py_Main(int argc, char **argv) break; case 'R': - Py_HashRandomizationFlag++; + /* Already handled above */ break; /* This space reserved for other options */ diff --git a/Python/getopt.c b/Python/getopt.c index 093c3dada29..e96eb6ccc3d 100644 --- a/Python/getopt.c +++ b/Python/getopt.c @@ -37,10 +37,18 @@ extern "C" { int _PyOS_opterr = 1; /* generate error messages */ int _PyOS_optind = 1; /* index into argv array */ char *_PyOS_optarg = NULL; /* optional argument */ +static char *opt_ptr = ""; + +void _PyOS_ResetGetOpt(void) +{ + _PyOS_opterr = 1; + _PyOS_optind = 1; + _PyOS_optarg = NULL; + opt_ptr = ""; +} int _PyOS_GetOpt(int argc, char **argv, char *optstring) { - static char *opt_ptr = ""; char *ptr; int option; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 8e1cd6236c5..dcb2c0ebcc2 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -67,7 +67,6 @@ static void call_sys_exitfunc(void); static void call_ll_exitfuncs(void); extern void _PyUnicode_Init(void); extern void _PyUnicode_Fini(void); -extern void _PyRandom_Init(void); #ifdef WITH_THREAD extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *);