jdk/src/java.base/share/native/libjli/args.c
changeset 43325 033e4cced1dc
parent 40261 86a49ba76f52
child 43340 4d25acf48a0b
equal deleted inserted replaced
43324:10c580b0c3f4 43325:033e4cced1dc
     1 /*
     1 /*
     2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
       
    26 #include <stdlib.h>
    26 #include <stdio.h>
    27 #include <stdio.h>
    27 #include <assert.h>
    28 #include <assert.h>
    28 #include <sys/stat.h>
    29 #include <sys/stat.h>
       
    30 #include <ctype.h>
    29 
    31 
    30 #ifdef DEBUG_ARGFILE
    32 #ifdef DEBUG_ARGFILE
    31   #ifndef NO_JNI
    33   #ifndef NO_JNI
    32     #define NO_JNI
    34     #define NO_JNI
    33   #endif
    35   #endif
    34   #define JLI_ReportMessage(p1, p2) printf((p1), (p2))
    36   #define JLI_ReportMessage(...) printf(__VA_ARGS__)
       
    37   #define JAVA_OPTIONS "JAVA_OPTIONS"
       
    38   int IsWhiteSpaceOption(const char* name) { return 1; }
    35 #else
    39 #else
    36   #include "java.h"
    40   #include "java.h"
    37 #endif
    41 #endif
    38 
    42 
    39 #include "jli_util.h"
    43 #include "jli_util.h"
    67 
    71 
    68 #define NOT_FOUND -1
    72 #define NOT_FOUND -1
    69 static int firstAppArgIndex = NOT_FOUND;
    73 static int firstAppArgIndex = NOT_FOUND;
    70 
    74 
    71 static jboolean expectingNoDashArg = JNI_FALSE;
    75 static jboolean expectingNoDashArg = JNI_FALSE;
    72 static size_t argsCount = 0;
    76 // Initialize to 1, as the first argument is the app name and not preprocessed
       
    77 static size_t argsCount = 1;
    73 static jboolean stopExpansion = JNI_FALSE;
    78 static jboolean stopExpansion = JNI_FALSE;
       
    79 static jboolean relaunch = JNI_FALSE;
    74 
    80 
    75 void JLI_InitArgProcessing(jboolean isJava, jboolean disableArgFile) {
    81 void JLI_InitArgProcessing(jboolean isJava, jboolean disableArgFile) {
    76     // No expansion for relaunch
    82     // No expansion for relaunch
    77     if (argsCount != 0) {
    83     if (argsCount != 1) {
       
    84         relaunch = JNI_TRUE;
    78         stopExpansion = JNI_TRUE;
    85         stopExpansion = JNI_TRUE;
    79         argsCount = 0;
    86         argsCount = 1;
    80     } else {
    87     } else {
    81         stopExpansion = disableArgFile;
    88         stopExpansion = disableArgFile;
    82     }
    89     }
    83 
    90 
    84     expectingNoDashArg = JNI_FALSE;
    91     expectingNoDashArg = JNI_FALSE;
    93 }
   100 }
    94 
   101 
    95 static void checkArg(const char *arg) {
   102 static void checkArg(const char *arg) {
    96     size_t idx = 0;
   103     size_t idx = 0;
    97     argsCount++;
   104     argsCount++;
    98     if (argsCount == 1) {
       
    99         // ignore first argument, the application name
       
   100         return;
       
   101     }
       
   102 
   105 
   103     // All arguments arrive here must be a launcher argument,
   106     // All arguments arrive here must be a launcher argument,
   104     // ie. by now, all argfile expansions must have been performed.
   107     // ie. by now, all argfile expansions must have been performed.
   105     if (*arg == '-') {
   108     if (*arg == '-') {
   106         expectingNoDashArg = JNI_FALSE;
   109         expectingNoDashArg = JNI_FALSE;
   107         if (IsWhiteSpaceOption(arg)) {
   110         if (IsWhiteSpaceOption(arg)) {
   108             // expect an argument
   111             // expect an argument
   109             expectingNoDashArg = JNI_TRUE;
   112             expectingNoDashArg = JNI_TRUE;
   110 
   113 
   111             if (JLI_StrCmp(arg, "-jar") == 0 ||
   114             if (JLI_StrCmp(arg, "-jar") == 0 ||
       
   115                 JLI_StrCmp(arg, "--module") == 0 ||
   112                 JLI_StrCmp(arg, "-m") == 0) {
   116                 JLI_StrCmp(arg, "-m") == 0) {
   113                 // This is tricky, we do expect NoDashArg
   117                 // This is tricky, we do expect NoDashArg
   114                 // But that is considered main class to stop expansion
   118                 // But that is considered main class to stop expansion
   115                 expectingNoDashArg = JNI_FALSE;
   119                 expectingNoDashArg = JNI_FALSE;
   116                 // We can not just update the idx here because if -jar @file
   120                 // We can not just update the idx here because if -jar @file
   117                 // still need expansion of @file to get the argument for -jar
   121                 // still need expansion of @file to get the argument for -jar
   118             }
   122             }
   119         } else if (JLI_StrCmp(arg, "-Xdisable-@files") == 0) {
   123         } else if (JLI_StrCmp(arg, "--disable-@files") == 0) {
   120             stopExpansion = JNI_TRUE;
   124             stopExpansion = JNI_TRUE;
   121         }
   125         }
   122     } else {
   126     } else {
   123         if (!expectingNoDashArg) {
   127         if (!expectingNoDashArg) {
   124             // this is main class, argsCount is index to next arg
   128             // this is main class, argsCount is index to next arg
   405         rv = expandArgFile(arg);
   409         rv = expandArgFile(arg);
   406     }
   410     }
   407     return rv;
   411     return rv;
   408 }
   412 }
   409 
   413 
       
   414 int isTerminalOpt(char *arg) {
       
   415     return JLI_StrCmp(arg, "-jar") == 0 ||
       
   416            JLI_StrCmp(arg, "-m") == 0 ||
       
   417            JLI_StrCmp(arg, "--module") == 0 ||
       
   418            JLI_StrCmp(arg, "--dry-run") == 0 ||
       
   419            JLI_StrCmp(arg, "-h") == 0 ||
       
   420            JLI_StrCmp(arg, "-?") == 0 ||
       
   421            JLI_StrCmp(arg, "-help") == 0 ||
       
   422            JLI_StrCmp(arg, "--help") == 0 ||
       
   423            JLI_StrCmp(arg, "-X") == 0 ||
       
   424            JLI_StrCmp(arg, "--help-extra") == 0 ||
       
   425            JLI_StrCmp(arg, "-version") == 0 ||
       
   426            JLI_StrCmp(arg, "--version") == 0 ||
       
   427            JLI_StrCmp(arg, "-fullversion") == 0 ||
       
   428            JLI_StrCmp(arg, "--full-version") == 0;
       
   429 }
       
   430 
       
   431 jboolean JLI_AddArgsFromEnvVar(JLI_List args, const char *var_name) {
       
   432     char *env = getenv(var_name);
       
   433     char *p, *arg;
       
   434     char quote;
       
   435     JLI_List argsInFile;
       
   436 
       
   437     if (firstAppArgIndex == 0) {
       
   438         // Not 'java', return
       
   439         return JNI_FALSE;
       
   440     }
       
   441 
       
   442     if (relaunch) {
       
   443         return JNI_FALSE;
       
   444     }
       
   445 
       
   446     if (NULL == env) {
       
   447         return JNI_FALSE;
       
   448     }
       
   449 
       
   450     JLI_ReportMessage(ARG_INFO_ENVVAR, var_name, env);
       
   451 
       
   452     // This is retained until the process terminates as it is saved as the args
       
   453     p = JLI_MemAlloc(JLI_StrLen(env) + 1);
       
   454     while (*env != '\0') {
       
   455         while (*env != '\0' && isspace(*env)) {
       
   456             env++;
       
   457         }
       
   458 
       
   459         arg = p;
       
   460         while (*env != '\0' && !isspace(*env)) {
       
   461             if (*env == '"' || *env == '\'') {
       
   462                 quote = *env++;
       
   463                 while (*env != quote && *env != '\0') {
       
   464                     *p++ = *env++;
       
   465                 }
       
   466 
       
   467                 if (*env == '\0') {
       
   468                     JLI_ReportMessage(ARG_ERROR8, var_name);
       
   469                     exit(1);
       
   470                 }
       
   471                 env++;
       
   472             } else {
       
   473                 *p++ = *env++;
       
   474             }
       
   475         }
       
   476 
       
   477         *p++ = '\0';
       
   478 
       
   479         argsInFile = JLI_PreprocessArg(arg);
       
   480 
       
   481         if (NULL == argsInFile) {
       
   482             if (isTerminalOpt(arg)) {
       
   483                 JLI_ReportMessage(ARG_ERROR9, arg, var_name);
       
   484                 exit(1);
       
   485             }
       
   486             JLI_List_add(args, arg);
       
   487         } else {
       
   488             size_t cnt, idx;
       
   489             char *argFile = arg;
       
   490             cnt = argsInFile->size;
       
   491             for (idx = 0; idx < cnt; idx++) {
       
   492                 arg = argsInFile->elements[idx];
       
   493                 if (isTerminalOpt(arg)) {
       
   494                     JLI_ReportMessage(ARG_ERROR10, arg, argFile, var_name);
       
   495                     exit(1);
       
   496                 }
       
   497                 JLI_List_add(args, arg);
       
   498             }
       
   499             // Shallow free, we reuse the string to avoid copy
       
   500             JLI_MemFree(argsInFile->elements);
       
   501             JLI_MemFree(argsInFile);
       
   502         }
       
   503         /*
       
   504          * Check if main-class is specified after argument being checked. It
       
   505          * must always appear after expansion, as a main-class could be specified
       
   506          * indirectly into environment variable via an @argfile, and it must be
       
   507          * caught now.
       
   508          */
       
   509         if (firstAppArgIndex != NOT_FOUND) {
       
   510             JLI_ReportMessage(ARG_ERROR11, var_name);
       
   511             exit(1);
       
   512         }
       
   513 
       
   514         assert (*env == '\0' || isspace(*env));
       
   515     }
       
   516 
       
   517     return JNI_TRUE;
       
   518 }
       
   519 
   410 #ifdef DEBUG_ARGFILE
   520 #ifdef DEBUG_ARGFILE
   411 /*
   521 /*
   412  * Stand-alone sanity test, build with following command line
   522  * Stand-alone sanity test, build with following command line
   413  * $ CC -DDEBUG_ARGFILE -DNO_JNI -g args.c jli_util.c
   523  * $ CC -DDEBUG_ARGFILE -DNO_JNI -g args.c jli_util.c
   414  */
   524  */