Home | History | Annotate | Download | only in Launcher
      1 // Copyright 2017 Google Inc. All rights reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include <Python.h>
     16 #include <android-base/file.h>
     17 #include <osdefs.h>
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <string>
     21 
     22 int main(int argc, char *argv[]) {
     23   // PYTHONEXECUTABLE is only used on MacOs X, when the Python interpreter
     24   // embedded in an application bundle. It is not sure that we have this use case
     25   // for Android hermetic Python. So remove this environment variable to make
     26   // our self-contained environment more strict.
     27   // For user (.py) program, it can access hermetic .par file path through
     28   // sys.argv[0].
     29   unsetenv(const_cast<char *>("PYTHONEXECUTABLE"));
     30 
     31   // Always enable Python "-s" option. We don't need user-site directories,
     32   // everything's supposed to be hermetic.
     33   Py_NoUserSiteDirectory = 1;
     34 
     35   // Ignore PYTHONPATH and PYTHONHOME from the environment. Unless we're not
     36   // running from inside the zip file, in which case the user may have
     37   // specified a PYTHONPATH.
     38 #ifdef ANDROID_AUTORUN
     39   Py_IgnoreEnvironmentFlag = 1;
     40 #endif
     41 
     42   Py_DontWriteBytecodeFlag = 1;
     43 
     44   // Resolving absolute path based on argv[0] is not reliable since it may
     45   // include something unusable, too bad.
     46   // android::base::GetExecutablePath() also handles for Darwin/Windows.
     47   std::string executable_path = android::base::GetExecutablePath();
     48 
     49   // Set the equivalent of PYTHONHOME internally.
     50   Py_SetPythonHome(strdup(executable_path.c_str()));
     51 
     52 #ifdef ANDROID_AUTORUN
     53   argc += 1;
     54   char **new_argv = reinterpret_cast<char**>(calloc(argc, sizeof(*argv)));
     55 
     56   // Inject the path to our binary into argv[1] so the Py_Main won't parse any
     57   // other options, and will execute the __main__.py script inside the zip file
     58   // attached to our executable.
     59   new_argv[0] = argv[0];
     60   new_argv[1] = strdup(executable_path.c_str());
     61   for (int i = 1; i < argc - 1; i++) {
     62     new_argv[i+1] = argv[i];
     63   }
     64   argv = new_argv;
     65 #endif
     66 
     67   return Py_Main(argc, argv);
     68 }
     69