1 /*
2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
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
23 * questions.
24 */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <sys/stat.h>
30 #include <ctype.h>
31
32 #ifdef DEBUG_ARGFILE
33 #ifndef NO_JNI
34 #define NO_JNI
35 #endif
36 #define JLI_ReportMessage(...) printf(__VA_ARGS__)
37 #define JDK_JAVA_OPTIONS "JDK_JAVA_OPTIONS"
38 int IsWhiteSpaceOption(const char* name) { return 1; }
39 #else
40 #include "java.h"
41 #endif
42
43 #include "jli_util.h"
44 #include "emessages.h"
45
46 #define MAX_ARGF_SIZE 0x7fffffffL
47
48 static char* clone_substring(const char *begin, size_t len) {
49 char *rv = (char *) JLI_MemAlloc(len + 1);
50 memcpy(rv, begin, len);
51 rv[len] = '\0';
52 return rv;
53 }
54
55 enum STATE {
56 FIND_NEXT,
57 IN_COMMENT,
58 IN_QUOTE,
59 IN_ESCAPE,
60 SKIP_LEAD_WS,
61 IN_TOKEN
62 };
63
64 typedef struct {
65 enum STATE state;
66 const char* cptr;
67 const char* eob;
68 char quote_char;
69 JLI_List parts;
70 } __ctx_args;
71
72 #define NOT_FOUND -1
73 static int firstAppArgIndex = NOT_FOUND;
74
75 static jboolean expectingNoDashArg = JNI_FALSE;
76 // Initialize to 1, as the first argument is the app name and not preprocessed
77 static size_t argsCount = 1;
78 static jboolean stopExpansion = JNI_FALSE;
79 static jboolean relaunch = JNI_FALSE;
80
81 void JLI_InitArgProcessing(jboolean hasJavaArgs, jboolean disableArgFile) {
82 // No expansion for relaunch
83 if (argsCount != 1) {
84 relaunch = JNI_TRUE;
85 stopExpansion = JNI_TRUE;
86 argsCount = 1;
87 } else {
88 stopExpansion = disableArgFile;
89 }
90
91 expectingNoDashArg = JNI_FALSE;
92
93 // for tools, this value remains 0 all the time.
94 firstAppArgIndex = hasJavaArgs ? 0: NOT_FOUND;
95 }
96
97 int JLI_GetAppArgIndex() {
98 // Will be 0 for tools
99 return firstAppArgIndex;
100 }
101
102 static void checkArg(const char *arg) {
103 size_t idx = 0;
104 argsCount++;
105
106 // All arguments arrive here must be a launcher argument,
107 // ie. by now, all argfile expansions must have been performed.
108 if (*arg == '-') {
109 expectingNoDashArg = JNI_FALSE;
110 if (IsWhiteSpaceOption(arg)) {
111 // expect an argument
112 expectingNoDashArg = JNI_TRUE;
113
114 if (JLI_StrCmp(arg, "-jar") == 0 ||
115 JLI_StrCmp(arg, "--module") == 0 ||
116 JLI_StrCmp(arg, "-m") == 0) {
117 // This is tricky, we do expect NoDashArg
356
357 fptr = fopen(arg, "r");
358 /* arg file cannot be openned */
359 if (fptr == NULL) {
360 JLI_ReportMessage(CFG_ERROR6, arg);
361 exit(1);
362 }
363
364 rv = readArgFile(fptr);
365 fclose(fptr);
366
367 /* error occurred reading the file */
368 if (rv == NULL) {
369 JLI_ReportMessage(DLL_ERROR4, arg);
370 exit(1);
371 }
372
373 return rv;
374 }
375
376 JLI_List JLI_PreprocessArg(const char *arg)
377 {
378 JLI_List rv;
379
380 if (firstAppArgIndex > 0) {
381 // In user application arg, no more work.
382 return NULL;
383 }
384
385 if (stopExpansion) {
386 // still looking for user application arg
387 checkArg(arg);
388 return NULL;
389 }
390
391 if (arg[0] != '@') {
392 checkArg(arg);
393 return NULL;
394 }
395
396 if (arg[1] == '\0') {
411 return rv;
412 }
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
|
1 /*
2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
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
23 * questions.
24 */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <sys/stat.h>
30 #include <ctype.h>
31
32 #ifdef DEBUG_ARGFILE
33 #ifndef NO_JNI
34 #define NO_JNI
35 #endif
36 #define JLI_ReportMessage(...) printf(__VA_ARGS__)
37 #define JDK_JAVA_OPTIONS "JDK_JAVA_OPTIONS"
38 int IsWhiteSpaceOption(const char* name) { return 1; }
39 #else
40 #include "java.h"
41 #include "jni.h"
42 #endif
43
44 #include "jli_util.h"
45 #include "emessages.h"
46
47 #define MAX_ARGF_SIZE 0x7fffffffL
48
49 static char* clone_substring(const char *begin, size_t len) {
50 char *rv = (char *) JLI_MemAlloc(len + 1);
51 memcpy(rv, begin, len);
52 rv[len] = '\0';
53 return rv;
54 }
55
56 enum STATE {
57 FIND_NEXT,
58 IN_COMMENT,
59 IN_QUOTE,
60 IN_ESCAPE,
61 SKIP_LEAD_WS,
62 IN_TOKEN
63 };
64
65 typedef struct {
66 enum STATE state;
67 const char* cptr;
68 const char* eob;
69 char quote_char;
70 JLI_List parts;
71 } __ctx_args;
72
73 #define NOT_FOUND -1
74 static int firstAppArgIndex = NOT_FOUND;
75
76 static jboolean expectingNoDashArg = JNI_FALSE;
77 // Initialize to 1, as the first argument is the app name and not preprocessed
78 static size_t argsCount = 1;
79 static jboolean stopExpansion = JNI_FALSE;
80 static jboolean relaunch = JNI_FALSE;
81
82 JNIEXPORT void JNICALL
83 JLI_InitArgProcessing(jboolean hasJavaArgs, jboolean disableArgFile) {
84 // No expansion for relaunch
85 if (argsCount != 1) {
86 relaunch = JNI_TRUE;
87 stopExpansion = JNI_TRUE;
88 argsCount = 1;
89 } else {
90 stopExpansion = disableArgFile;
91 }
92
93 expectingNoDashArg = JNI_FALSE;
94
95 // for tools, this value remains 0 all the time.
96 firstAppArgIndex = hasJavaArgs ? 0: NOT_FOUND;
97 }
98
99 JNIEXPORT int JNICALL
100 JLI_GetAppArgIndex() {
101 // Will be 0 for tools
102 return firstAppArgIndex;
103 }
104
105 static void checkArg(const char *arg) {
106 size_t idx = 0;
107 argsCount++;
108
109 // All arguments arrive here must be a launcher argument,
110 // ie. by now, all argfile expansions must have been performed.
111 if (*arg == '-') {
112 expectingNoDashArg = JNI_FALSE;
113 if (IsWhiteSpaceOption(arg)) {
114 // expect an argument
115 expectingNoDashArg = JNI_TRUE;
116
117 if (JLI_StrCmp(arg, "-jar") == 0 ||
118 JLI_StrCmp(arg, "--module") == 0 ||
119 JLI_StrCmp(arg, "-m") == 0) {
120 // This is tricky, we do expect NoDashArg
359
360 fptr = fopen(arg, "r");
361 /* arg file cannot be openned */
362 if (fptr == NULL) {
363 JLI_ReportMessage(CFG_ERROR6, arg);
364 exit(1);
365 }
366
367 rv = readArgFile(fptr);
368 fclose(fptr);
369
370 /* error occurred reading the file */
371 if (rv == NULL) {
372 JLI_ReportMessage(DLL_ERROR4, arg);
373 exit(1);
374 }
375
376 return rv;
377 }
378
379 JNIEXPORT JLI_List JNICALL
380 JLI_PreprocessArg(const char *arg)
381 {
382 JLI_List rv;
383
384 if (firstAppArgIndex > 0) {
385 // In user application arg, no more work.
386 return NULL;
387 }
388
389 if (stopExpansion) {
390 // still looking for user application arg
391 checkArg(arg);
392 return NULL;
393 }
394
395 if (arg[0] != '@') {
396 checkArg(arg);
397 return NULL;
398 }
399
400 if (arg[1] == '\0') {
415 return rv;
416 }
417
418 int isTerminalOpt(char *arg) {
419 return JLI_StrCmp(arg, "-jar") == 0 ||
420 JLI_StrCmp(arg, "-m") == 0 ||
421 JLI_StrCmp(arg, "--module") == 0 ||
422 JLI_StrCmp(arg, "--dry-run") == 0 ||
423 JLI_StrCmp(arg, "-h") == 0 ||
424 JLI_StrCmp(arg, "-?") == 0 ||
425 JLI_StrCmp(arg, "-help") == 0 ||
426 JLI_StrCmp(arg, "--help") == 0 ||
427 JLI_StrCmp(arg, "-X") == 0 ||
428 JLI_StrCmp(arg, "--help-extra") == 0 ||
429 JLI_StrCmp(arg, "-version") == 0 ||
430 JLI_StrCmp(arg, "--version") == 0 ||
431 JLI_StrCmp(arg, "-fullversion") == 0 ||
432 JLI_StrCmp(arg, "--full-version") == 0;
433 }
434
435 JNIEXPORT jboolean JNICALL
436 JLI_AddArgsFromEnvVar(JLI_List args, const char *var_name) {
437 char *env = getenv(var_name);
438 char *p, *arg;
439 char quote;
440 JLI_List argsInFile;
441
442 if (firstAppArgIndex == 0) {
443 // Not 'java', return
444 return JNI_FALSE;
445 }
446
447 if (relaunch) {
448 return JNI_FALSE;
449 }
450
451 if (NULL == env) {
452 return JNI_FALSE;
453 }
454
455 JLI_ReportMessage(ARG_INFO_ENVVAR, var_name, env);
456
|