@@ -88,7 +88,8 @@ public static void main(String[] args) {
8888 @ Override
8989 protected List <String > preprocessArguments (List <String > givenArgs , Map <String , String > polyglotOptions ) {
9090 ArrayList <String > unrecognized = new ArrayList <>();
91- ArrayList <String > inputArgs = new ArrayList <>();
91+ List <String > defaultEnvironmentArgs = getDefaultEnvironmentArgs ();
92+ ArrayList <String > inputArgs = new ArrayList <>(defaultEnvironmentArgs );
9293 inputArgs .addAll (givenArgs );
9394 givenArguments = new ArrayList <>(inputArgs );
9495 List <String > arguments = new ArrayList <>(inputArgs );
@@ -308,10 +309,19 @@ private String[] getExecutableList() {
308309 ArrayList <String > exec_list = new ArrayList <>();
309310 sb .append (System .getProperty ("java.home" )).append (File .separator ).append ("bin" ).append (File .separator ).append ("java" );
310311 exec_list .add (sb .toString ());
312+ String javaOptions = System .getenv ("_JAVA_OPTIONS" );
313+ String javaToolOptions = System .getenv ("JAVA_TOOL_OPTIONS" );
311314 for (String arg : ManagementFactory .getRuntimeMXBean ().getInputArguments ()) {
312315 if (arg .matches ("-Xrunjdwp:transport=dt_socket,server=y,address=\\ d+,suspend=y" )) {
313316 arg = arg .replace ("suspend=y" , "suspend=n" );
314317 }
318+ if ((javaOptions != null && javaOptions .contains (arg )) || (javaToolOptions != null && javaToolOptions .contains (arg ))) {
319+ // both _JAVA_OPTIONS and JAVA_TOOL_OPTIONS are adeed during
320+ // JVM startup automatically. We do not want to repeat these
321+ // for subprocesses, because they should also pick up those
322+ // variables.
323+ continue ;
324+ }
315325 exec_list .add (arg );
316326 }
317327 exec_list .add ("-classpath" );
@@ -576,6 +586,10 @@ protected void printHelp(OptionCategory maxCategory) {
576586 " as specifying the -R option: a random value is used to seed the hashes of\n " +
577587 " str, bytes and datetime objects. It can also be set to an integer\n " +
578588 " in the range [0,4294967295] to get hash values with a predictable seed.\n " +
589+ "GRAAL_PYTHON_ARGS: the value is added as arguments as if passed on the\n " +
590+ " commandline. There is one special case: any `$$' in the value is replaced\n " +
591+ " with the current process id. To pass a literal `$$', you must escape the\n " +
592+ " second `$' like so: `$\\ $'\n " +
579593 (wantsExperimental ? "\n Arguments specific to the Graal Python launcher:\n " +
580594 "--show-version : print the Python version number and continue.\n " +
581595 "-CC : run the C compiler used for generating GraalPython C extensions.\n " +
@@ -808,6 +822,72 @@ private static final class ExitException extends RuntimeException {
808822 }
809823 }
810824
825+ private static enum State {
826+ NORMAL ,
827+ SINGLE_QUOTE ,
828+ DOUBLE_QUOTE ,
829+ ESCAPE_SINGLE_QUOTE ,
830+ ESCAPE_DOUBLE_QUOTE ,
831+ }
832+
833+ private static List <String > getDefaultEnvironmentArgs () {
834+ String pid ;
835+ if (isAOT ()) {
836+ pid = String .valueOf (ProcessProperties .getProcessID ());
837+ } else {
838+ pid = ManagementFactory .getRuntimeMXBean ().getName ().split ("@" )[0 ];
839+ }
840+ String envArgsOpt = System .getenv ("GRAAL_PYTHON_ARGS" );
841+ ArrayList <String > envArgs = new ArrayList <>();
842+ State s = State .NORMAL ;
843+ StringBuilder sb = new StringBuilder ();
844+ if (envArgsOpt != null ) {
845+ for (char x : envArgsOpt .toCharArray ()) {
846+ if (s == State .NORMAL && Character .isWhitespace (x )) {
847+ addArgument (pid , envArgs , sb );
848+ } else {
849+ if (x == '"' ) {
850+ if (s == State .NORMAL ) {
851+ s = State .DOUBLE_QUOTE ;
852+ } else if (s == State .DOUBLE_QUOTE ) {
853+ s = State .NORMAL ;
854+ } else if (s == State .ESCAPE_DOUBLE_QUOTE ) {
855+ s = State .DOUBLE_QUOTE ;
856+ sb .append (x );
857+ }
858+ } else if (x == '\'' ) {
859+ if (s == State .NORMAL ) {
860+ s = State .SINGLE_QUOTE ;
861+ } else if (s == State .SINGLE_QUOTE ) {
862+ s = State .NORMAL ;
863+ } else if (s == State .ESCAPE_SINGLE_QUOTE ) {
864+ s = State .SINGLE_QUOTE ;
865+ sb .append (x );
866+ }
867+ } else if (x == '\\' ) {
868+ if (s == State .SINGLE_QUOTE ) {
869+ s = State .ESCAPE_SINGLE_QUOTE ;
870+ } else if (s == State .DOUBLE_QUOTE ) {
871+ s = State .ESCAPE_DOUBLE_QUOTE ;
872+ }
873+ } else {
874+ sb .append (x );
875+ }
876+ }
877+ }
878+ addArgument (pid , envArgs , sb );
879+ }
880+ return envArgs ;
881+ }
882+
883+ private static void addArgument (String pid , ArrayList <String > envArgs , StringBuilder sb ) {
884+ if (sb .length () > 0 ) {
885+ String arg = sb .toString ().replace ("$$" , pid ).replace ("\\ $" , "$" );
886+ envArgs .add (arg );
887+ sb .setLength (0 );
888+ }
889+ }
890+
811891 private static boolean doEcho (@ SuppressWarnings ("unused" ) Context context ) {
812892 return true ;
813893 }
0 commit comments