jruby-launcher 0.9.9-java
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +826 -0
- data/Makefile +106 -0
- data/README.txt +61 -0
- data/Rakefile +27 -0
- data/argnames.h +37 -0
- data/argparser.cpp +559 -0
- data/argparser.h +76 -0
- data/extconf.rb +6 -0
- data/inc/Makefile-conf.mk +75 -0
- data/inc/Makefile-impl.mk +107 -0
- data/inc/Makefile-rules.mk +40 -0
- data/jruby.cpp +77 -0
- data/jrubyexe.cpp +84 -0
- data/jvmlauncher.cpp +421 -0
- data/jvmlauncher.h +141 -0
- data/lib/jruby-launcher.rb +3 -0
- data/lib/rubygems/defaults/jruby_native.rb +4 -0
- data/nbexecloader.h +43 -0
- data/ng.c +642 -0
- data/platformlauncher.cpp +239 -0
- data/platformlauncher.h +73 -0
- data/rb_w32_cmdvector.h +287 -0
- data/resources/jruby.ico +0 -0
- data/resources/jruby.rc +25 -0
- data/spec/launcher_spec.rb +134 -0
- data/spec/spec_helper.rb +61 -0
- data/strlcpy.c +69 -0
- data/unixlauncher.cpp +81 -0
- data/unixlauncher.h +22 -0
- data/utilsfuncs.cpp +269 -0
- data/utilsfuncs.h +84 -0
- data/utilsfuncswin.cpp +229 -0
- metadata +96 -0
data/resources/jruby.ico
ADDED
Binary file
|
data/resources/jruby.rc
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
id ICON "jruby.ico"
|
2
|
+
|
3
|
+
1 VERSIONINFO
|
4
|
+
FILEVERSION 1,0,0,0
|
5
|
+
PRODUCTVERSION 1,0,0,0
|
6
|
+
BEGIN
|
7
|
+
BLOCK "StringFileInfo"
|
8
|
+
BEGIN
|
9
|
+
BLOCK "000004b0"
|
10
|
+
BEGIN
|
11
|
+
VALUE "CompanyName", "http://www.jruby.org/\0"
|
12
|
+
VALUE "FileDescription", "Windows JRuby Launcher\0"
|
13
|
+
VALUE "FileVersion", "1.0\0"
|
14
|
+
VALUE "InternalName", "jruby.exe\0"
|
15
|
+
VALUE "LegalCopyright", "Copyright (C) The JRuby Team\0"
|
16
|
+
VALUE "OriginalFilename", "jruby.exe\0"
|
17
|
+
VALUE "ProductName", "JRuby\0"
|
18
|
+
VALUE "ProductVersion", "1.0\0"
|
19
|
+
END
|
20
|
+
END
|
21
|
+
BLOCK "VarFileInfo"
|
22
|
+
BEGIN
|
23
|
+
VALUE "Translation", 0x0, 0x4b0
|
24
|
+
END
|
25
|
+
END
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
describe "JRuby native launcher" do
|
4
|
+
it "should run org.jruby.Main" do
|
5
|
+
jruby_launcher_args("").last.should == "org/jruby/Main"
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should pass unrecognized arguments to JRuby" do
|
9
|
+
jruby_launcher_args("-J-Dsome.option -v --help")[-3..-1].should == ["org/jruby/Main", "-v", "--help"]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should print help message" do
|
13
|
+
jruby_launcher("-Xhelp 2>&1").should =~ /JRuby Launcher usage/
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should use $JAVA_HOME/bin/java when JAVA_HOME is specified" do
|
17
|
+
with_environment "JAVA_HOME" => File.join("some", "java", "home") do
|
18
|
+
if windows?
|
19
|
+
jruby_launcher_args("-v 2>&1").join.should =~ %r{some/java/home}
|
20
|
+
else
|
21
|
+
jruby_launcher_args("-v").first.should == File.join("some", "java", "home", "bin", "java")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should use -Xjdkhome argument above JAVA_HOME" do
|
27
|
+
with_environment "JAVA_HOME" => File.join("env", "java", "home") do
|
28
|
+
if windows?
|
29
|
+
jruby_launcher_args("-Xjdkhome some/java/home 2>&1").join.should =~ %r{some/java/home}
|
30
|
+
else
|
31
|
+
jruby_launcher_args("-Xjdkhome some/java/home").first.should == File.join("some", "java", "home", "bin", "java")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should complain about a missing log argument" do
|
37
|
+
jruby_launcher("-Xtrace 2>&1").should =~ /Argument is missing for "-Xtrace"/
|
38
|
+
jruby_launcher("-Xtrace -- 2>&1").should =~ /Argument is missing for "-Xtrace"/
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should complain about a missing jdkhome argument" do
|
42
|
+
jruby_launcher("-Xjdkhome 2>&1").should =~ /Argument is missing/
|
43
|
+
jruby_launcher("-Xjdkhome -- 2>&1").should =~ /Argument is missing/
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should complain about a missing classpath append argument" do
|
47
|
+
jruby_launcher("-Xcp:a 2>&1").should =~ /Argument is missing/
|
48
|
+
jruby_launcher("-Xcp:a -- 2>&1").should =~ /Argument is missing/
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should run nailgun server with --ng-server option" do
|
52
|
+
jruby_launcher_args("--ng-server").last.should == "com/martiansoftware/nailgun/NGServer"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should run nailgun client with --ng option" do
|
56
|
+
jruby_launcher_args('--ng -e "puts 1"').should == ["org.jruby.util.NailMain", "-e", "puts 1"]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should handle -J JVM options" do
|
60
|
+
jruby_launcher_args("-J-Darg1=value1 -J-Darg2=value2").should include("-Darg1=value1", "-Darg2=value2")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should default to 500m max heap" do
|
64
|
+
jruby_launcher_args("").should include("-Xmx500m", "-Djruby.memory.max=500m")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should allow max heap to be overridden" do
|
68
|
+
jruby_launcher_args("-J-Xmx256m").should include("-Xmx256m", "-Djruby.memory.max=256m")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should default to 1024k max stack" do
|
72
|
+
jruby_launcher_args("").should include("-Xss1024k", "-Djruby.stack.max=1024k")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should allow max stack to be overridden" do
|
76
|
+
jruby_launcher_args("-J-Xss512k").should include("-Xss512k", "-Djruby.stack.max=512k")
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should add the contents of the CLASSPATH environment variable" do
|
80
|
+
with_environment "CLASSPATH" => "some.jar" do
|
81
|
+
classpath_arg = jruby_launcher_args("").detect{|a| a =~ /java\.class\.path/}
|
82
|
+
classpath_arg.should =~ /-Djava.class.path=.*some.jar/
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should add the classpath elements in proper order" do
|
87
|
+
s = File::PATH_SEPARATOR
|
88
|
+
with_environment "CLASSPATH" => "some-env.jar" do
|
89
|
+
classpath_arg = jruby_launcher_args("-Xcp:a some-other.jar -Xcp:p some.jar").detect{|a| a =~ /java\.class\.path/}
|
90
|
+
classpath_arg.should =~ /-Djava.class.path=some.jar.*#{s}some-env.jar#{s}some-other.jar/
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should use the --server compiler" do
|
95
|
+
jruby_launcher_args("--server").should include("-server")
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should use the --client compiler" do
|
99
|
+
jruby_launcher_args("--client").should include("-client")
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should set the JMX settings when --manage is present" do
|
103
|
+
jruby_launcher_args("--manage").should include("-Dcom.sun.management.jmxremote", "-Djruby.management.enabled=true")
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should set the headless flag when --headless is present" do
|
107
|
+
jruby_launcher_args("--headless").should include("-Djava.awt.headless=true")
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should pass -Xprof when --sample is present" do
|
111
|
+
jruby_launcher_args("--sample").should include("-Xprof")
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should stop argument processing when a -- is seen" do
|
115
|
+
jruby_launcher_args("-- -Xhelp -Xtrace --headless").should include("-Xhelp", "-Xtrace", "--headless")
|
116
|
+
end
|
117
|
+
|
118
|
+
# JRUBY-4151
|
119
|
+
it "should properly handle single quotes" do
|
120
|
+
jruby_launcher_args("-e 'ABC DEF'").should include("ABC DEF")
|
121
|
+
end
|
122
|
+
|
123
|
+
# JRUBY-4581
|
124
|
+
it "should prepend JRUBY_OPTS to the start of the argument list to process" do
|
125
|
+
with_environment "JRUBY_OPTS" => "--server -J-Dsome.key=val -rubygems" do
|
126
|
+
jruby_launcher_args("-e 'ABC DEF'").should include("-server", "-Dsome.key=val", "-rubygems", "-e", "ABC DEF")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# JRUBY-4611
|
131
|
+
it "stops argument processing on first non-option argument" do
|
132
|
+
jruby_launcher_args("foo.rb --profile")[-2..-1].should == ["foo.rb", "--profile"]
|
133
|
+
end
|
134
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'rbconfig'
|
3
|
+
|
4
|
+
if defined?(JRUBY_VERSION)
|
5
|
+
require 'jruby'
|
6
|
+
JRuby.runtime.instance_config.run_ruby_in_process = false
|
7
|
+
end
|
8
|
+
|
9
|
+
module JRubyLauncherHelper
|
10
|
+
JRUBY_EXE = File.expand_path("../../jruby", __FILE__) + Config::CONFIG['EXEEXT']
|
11
|
+
WINDOWS = Config::CONFIG['target_os'] =~ /mswin/
|
12
|
+
|
13
|
+
def self.check_executable_built
|
14
|
+
unless File.executable?(JRUBY_EXE)
|
15
|
+
raise "Error: launcher executable not built; type `make' before continuing."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def jruby_launcher(args)
|
20
|
+
`#{JRUBY_EXE} #{args}`
|
21
|
+
end
|
22
|
+
|
23
|
+
def jruby_launcher_args(args)
|
24
|
+
jruby_launcher("-Xcommand #{args}").split("\n")
|
25
|
+
end
|
26
|
+
|
27
|
+
def last_exit_code
|
28
|
+
$?.exitstatus
|
29
|
+
end
|
30
|
+
|
31
|
+
def windows?
|
32
|
+
WINDOWS
|
33
|
+
end
|
34
|
+
|
35
|
+
def with_environment(pairs = {})
|
36
|
+
prev_env = {}
|
37
|
+
pairs.each_pair do |k,v|
|
38
|
+
prev_env[k] = ENV[k] if ENV.has_key?(k)
|
39
|
+
ENV[k] = v
|
40
|
+
end
|
41
|
+
begin
|
42
|
+
yield
|
43
|
+
ensure
|
44
|
+
pairs.keys.each {|k| ENV.delete(k)}
|
45
|
+
ENV.update(prev_env)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Spec::Runner.configure do |config|
|
51
|
+
config.before(:all) do
|
52
|
+
JRubyLauncherHelper.check_executable_built
|
53
|
+
# clear environment for better control
|
54
|
+
ENV.delete("JAVA_HOME")
|
55
|
+
ENV.delete("JRUBY_HOME")
|
56
|
+
ENV.delete("JAVA_OPTS")
|
57
|
+
ENV.delete("JRUBY_OPTS")
|
58
|
+
ENV.delete("CLASSPATH")
|
59
|
+
end
|
60
|
+
config.include(JRubyLauncherHelper)
|
61
|
+
end
|
data/strlcpy.c
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */
|
2
|
+
|
3
|
+
/*
|
4
|
+
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
5
|
+
* All rights reserved.
|
6
|
+
*
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
8
|
+
* modification, are permitted provided that the following conditions
|
9
|
+
* are met:
|
10
|
+
* 1. Redistributions of source code must retain the above copyright
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
12
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
13
|
+
* notice, this list of conditions and the following disclaimer in the
|
14
|
+
* documentation and/or other materials provided with the distribution.
|
15
|
+
* 3. The name of the author may not be used to endorse or promote products
|
16
|
+
* derived from this software without specific prior written permission.
|
17
|
+
*
|
18
|
+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
19
|
+
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
20
|
+
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
21
|
+
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
22
|
+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
23
|
+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
24
|
+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
25
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
26
|
+
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
27
|
+
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
*/
|
29
|
+
|
30
|
+
#if defined(LIBC_SCCS) && !defined(lint)
|
31
|
+
static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $";
|
32
|
+
#endif /* LIBC_SCCS and not lint */
|
33
|
+
|
34
|
+
#include <sys/types.h>
|
35
|
+
#include <string.h>
|
36
|
+
|
37
|
+
/*
|
38
|
+
* Copy src to string dst of size siz. At most siz-1 characters
|
39
|
+
* will be copied. Always NUL terminates (unless siz == 0).
|
40
|
+
* Returns strlen(src); if retval >= siz, truncation occurred.
|
41
|
+
*/
|
42
|
+
size_t
|
43
|
+
strlcpy(dst, src, siz)
|
44
|
+
char *dst;
|
45
|
+
const char *src;
|
46
|
+
size_t siz;
|
47
|
+
{
|
48
|
+
register char *d = dst;
|
49
|
+
register const char *s = src;
|
50
|
+
register size_t n = siz;
|
51
|
+
|
52
|
+
/* Copy as many bytes as will fit */
|
53
|
+
if (n != 0 && --n != 0) {
|
54
|
+
do {
|
55
|
+
if ((*d++ = *s++) == 0)
|
56
|
+
break;
|
57
|
+
} while (--n != 0);
|
58
|
+
}
|
59
|
+
|
60
|
+
/* Not enough room in dst, add NUL and traverse rest of src */
|
61
|
+
if (n == 0) {
|
62
|
+
if (siz != 0)
|
63
|
+
*d = '\0'; /* NUL-terminate dst */
|
64
|
+
while (*s++)
|
65
|
+
;
|
66
|
+
}
|
67
|
+
|
68
|
+
return(s - src - 1); /* count does not include NUL */
|
69
|
+
}
|
data/unixlauncher.cpp
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#include <stdlib.h>
|
2
|
+
#include "unixlauncher.h"
|
3
|
+
#include "utilsfuncs.h"
|
4
|
+
|
5
|
+
using namespace std;
|
6
|
+
|
7
|
+
extern "C" int nailgunClientMain(int argc, char *argv[], char *env[]);
|
8
|
+
|
9
|
+
UnixLauncher::UnixLauncher()
|
10
|
+
: ArgParser()
|
11
|
+
{
|
12
|
+
}
|
13
|
+
|
14
|
+
UnixLauncher::UnixLauncher(const UnixLauncher& orig)
|
15
|
+
: ArgParser(orig)
|
16
|
+
{
|
17
|
+
}
|
18
|
+
|
19
|
+
UnixLauncher::~UnixLauncher() {
|
20
|
+
}
|
21
|
+
|
22
|
+
int UnixLauncher::run(int argc, char* argv[], char* envp[]) {
|
23
|
+
platformDir = argv[0];
|
24
|
+
if (!initPlatformDir() || !parseArgs(argc - 1, argv + 1)) {
|
25
|
+
return 255;
|
26
|
+
}
|
27
|
+
|
28
|
+
if (nailgunClient) {
|
29
|
+
progArgs.push_front("org.jruby.util.NailMain");
|
30
|
+
char ** nailArgv = convertToArgvArray(progArgs);
|
31
|
+
if (printCommandLine) {
|
32
|
+
return printArgvToConsole(nailArgv);
|
33
|
+
}
|
34
|
+
return nailgunClientMain(progArgs.size(), (char**)nailArgv, envp);
|
35
|
+
}
|
36
|
+
|
37
|
+
prepareOptions();
|
38
|
+
|
39
|
+
string java("");
|
40
|
+
|
41
|
+
if (!jdkhome.empty()) {
|
42
|
+
java = jdkhome + "/bin/java";
|
43
|
+
} else if (getenv("JAVA_HOME") != NULL) {
|
44
|
+
java = string(getenv("JAVA_HOME")) + "/bin/java";
|
45
|
+
} else {
|
46
|
+
java = findOnPath("java");
|
47
|
+
}
|
48
|
+
|
49
|
+
if (java.empty()) {
|
50
|
+
printToConsole("No `java' executable found on PATH.");
|
51
|
+
return 255;
|
52
|
+
}
|
53
|
+
|
54
|
+
list<string> commandLine;
|
55
|
+
commandLine.push_back(java);
|
56
|
+
addOptionsToCommandLine(commandLine);
|
57
|
+
|
58
|
+
logMsg("Command line:");
|
59
|
+
for (list<string>::iterator it = commandLine.begin(); it != commandLine.end(); ++it) {
|
60
|
+
logMsg(it->c_str());
|
61
|
+
}
|
62
|
+
|
63
|
+
char** newArgv = convertToArgvArray(commandLine);
|
64
|
+
|
65
|
+
if (printCommandLine) {
|
66
|
+
return printArgvToConsole(newArgv);
|
67
|
+
}
|
68
|
+
|
69
|
+
|
70
|
+
if (!fileExists(java.c_str())) {
|
71
|
+
string msg = "No `java' exists at " + java + ", please double-check JAVA_HOME.\n";
|
72
|
+
printToConsole(msg.c_str());
|
73
|
+
return 255;
|
74
|
+
}
|
75
|
+
|
76
|
+
execv(java.c_str(), newArgv);
|
77
|
+
|
78
|
+
// shouldn't get here unless something bad happened with execv
|
79
|
+
logErr(true, true, "execv failed:");
|
80
|
+
return 255;
|
81
|
+
}
|
data/unixlauncher.h
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2009-2010 JRuby Team (www.jruby.org).
|
3
|
+
*/
|
4
|
+
|
5
|
+
|
6
|
+
#ifndef _UNIXLAUNCHER_H_
|
7
|
+
#define _UNIXLAUNCHER_H_
|
8
|
+
|
9
|
+
#include "argparser.h"
|
10
|
+
|
11
|
+
class UnixLauncher : public ArgParser {
|
12
|
+
public:
|
13
|
+
UnixLauncher();
|
14
|
+
virtual ~UnixLauncher();
|
15
|
+
|
16
|
+
int run(int argc, char* argv[], char* envp[]);
|
17
|
+
|
18
|
+
private:
|
19
|
+
UnixLauncher(const UnixLauncher& orig);
|
20
|
+
};
|
21
|
+
|
22
|
+
#endif // ! _UNIXLAUNCHER_H_
|
data/utilsfuncs.cpp
ADDED
@@ -0,0 +1,269 @@
|
|
1
|
+
/*
|
2
|
+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
3
|
+
*
|
4
|
+
* Copyright 2009-2010 JRuby Team (www.jruby.org).
|
5
|
+
* Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
|
6
|
+
*
|
7
|
+
* The contents of this file are subject to the terms of either the GNU
|
8
|
+
* General Public License Version 2 only ("GPL") or the Common
|
9
|
+
* Development and Distribution License("CDDL") (collectively, the
|
10
|
+
* "License"). You may not use this file except in compliance with the
|
11
|
+
* License. You can obtain a copy of the License at
|
12
|
+
* http://www.netbeans.org/cddl-gplv2.html
|
13
|
+
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
|
14
|
+
* specific language governing permissions and limitations under the
|
15
|
+
* License. When distributing the software, include this License Header
|
16
|
+
* Notice in each file and include the License file at
|
17
|
+
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
|
18
|
+
* particular file as subject to the "Classpath" exception as provided
|
19
|
+
* by Sun in the GPL Version 2 section of the License file that
|
20
|
+
* accompanied this code. If applicable, add the following below the
|
21
|
+
* License Header, with the fields enclosed by brackets [] replaced by
|
22
|
+
* your own identifying information:
|
23
|
+
* "Portions Copyrighted [year] [name of copyright owner]"
|
24
|
+
*
|
25
|
+
* Contributor(s):
|
26
|
+
*
|
27
|
+
* The Original Software is NetBeans. The Initial Developer of the Original
|
28
|
+
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun
|
29
|
+
* Microsystems, Inc. All Rights Reserved.
|
30
|
+
*
|
31
|
+
* If you wish your version of this file to be governed by only the CDDL
|
32
|
+
* or only the GPL Version 2, indicate your decision by adding
|
33
|
+
* "[Contributor] elects to include this software in this distribution
|
34
|
+
* under the [CDDL or GPL Version 2] license." If you do not indicate a
|
35
|
+
* single choice of license, a recipient has the option to distribute
|
36
|
+
* your version of this file under either the CDDL, the GPL Version 2 or
|
37
|
+
* to extend the choice of license to its licensees as provided above.
|
38
|
+
* However, if you add GPL Version 2 code and therefore, elected the GPL
|
39
|
+
* Version 2 license, then the option applies only if the new code is
|
40
|
+
* made subject to such option by the copyright holder.
|
41
|
+
*
|
42
|
+
* Author: Tomas Holy
|
43
|
+
*/
|
44
|
+
|
45
|
+
#include <stdio.h>
|
46
|
+
#include <stdarg.h>
|
47
|
+
#include <cstring>
|
48
|
+
#include <cstdlib>
|
49
|
+
#include <memory>
|
50
|
+
#include "utilsfuncs.h"
|
51
|
+
#include "argnames.h"
|
52
|
+
|
53
|
+
#ifndef WIN32
|
54
|
+
#include <sys/stat.h>
|
55
|
+
#include <errno.h>
|
56
|
+
#include <string.h>
|
57
|
+
#endif
|
58
|
+
|
59
|
+
#ifdef __SUNOS__
|
60
|
+
#include <sys/varargs.h>
|
61
|
+
#endif
|
62
|
+
|
63
|
+
using namespace std;
|
64
|
+
|
65
|
+
bool checkExists(const char* path, unsigned int flags) {
|
66
|
+
#ifdef WIN32
|
67
|
+
WIN32_FIND_DATA fd = {0};
|
68
|
+
HANDLE hFind = 0;
|
69
|
+
hFind = FindFirstFile(path, &fd);
|
70
|
+
if (hFind == INVALID_HANDLE_VALUE) {
|
71
|
+
return false;
|
72
|
+
}
|
73
|
+
FindClose(hFind);
|
74
|
+
if (flags == 0) {
|
75
|
+
return true;
|
76
|
+
}
|
77
|
+
return (fd.dwFileAttributes & flags) != 0;
|
78
|
+
#else
|
79
|
+
struct stat dir;
|
80
|
+
if (stat(path, &dir) != 0) {
|
81
|
+
return false;
|
82
|
+
}
|
83
|
+
if (flags == 0) {
|
84
|
+
return true;
|
85
|
+
}
|
86
|
+
return dir.st_mode & flags;
|
87
|
+
#endif
|
88
|
+
}
|
89
|
+
|
90
|
+
bool checkDirectory(const char* path) {
|
91
|
+
#ifdef WIN32
|
92
|
+
unsigned int flags = FILE_ATTRIBUTE_DIRECTORY;
|
93
|
+
#else
|
94
|
+
unsigned int flags = S_IFDIR;
|
95
|
+
#endif
|
96
|
+
return checkExists(path, flags);
|
97
|
+
}
|
98
|
+
|
99
|
+
bool dirExists(const char *path) {
|
100
|
+
if (!checkDirectory(path)) {
|
101
|
+
logMsg("Dir \"%s\" does not exist", path);
|
102
|
+
return false;
|
103
|
+
}
|
104
|
+
logMsg("Dir \"%s\" exists", path);
|
105
|
+
return true;
|
106
|
+
}
|
107
|
+
|
108
|
+
bool fileExists(const char *path) {
|
109
|
+
if (!checkExists(path, 0)) {
|
110
|
+
logMsg("File \"%s\" does not exist", path);
|
111
|
+
return false;
|
112
|
+
}
|
113
|
+
logMsg("File \"%s\" exists", path);
|
114
|
+
return true;
|
115
|
+
}
|
116
|
+
|
117
|
+
char* findOnPath(const char* name) {
|
118
|
+
string path(getenv("PATH"));
|
119
|
+
size_t start = 0;
|
120
|
+
size_t sep;
|
121
|
+
char * found;
|
122
|
+
|
123
|
+
while (start < path.length()) {
|
124
|
+
sep = path.find(PATH_SEP, start);
|
125
|
+
if (sep == string::npos) {
|
126
|
+
sep = path.length();
|
127
|
+
}
|
128
|
+
|
129
|
+
string elem(path.substr(start, sep - start));
|
130
|
+
if (elem[elem.length() - 1] != FILE_SEP) {
|
131
|
+
elem += FILE_SEP;
|
132
|
+
}
|
133
|
+
elem += name;
|
134
|
+
|
135
|
+
if (checkExists(elem.c_str(), 0)) {
|
136
|
+
found = (char*) malloc(elem.length());
|
137
|
+
strncpy(found, elem.c_str(), elem.length() + 1);
|
138
|
+
return found;
|
139
|
+
}
|
140
|
+
|
141
|
+
start = sep + 1;
|
142
|
+
}
|
143
|
+
return NULL;
|
144
|
+
}
|
145
|
+
|
146
|
+
const char* getSysError(char *str, int strSize) {
|
147
|
+
#ifdef WIN32
|
148
|
+
int err = GetLastError();
|
149
|
+
LPTSTR lpMsgBuf;
|
150
|
+
FormatMessage(
|
151
|
+
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
152
|
+
FORMAT_MESSAGE_FROM_SYSTEM |
|
153
|
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
154
|
+
NULL,
|
155
|
+
err,
|
156
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
157
|
+
(LPTSTR) & lpMsgBuf,
|
158
|
+
0,
|
159
|
+
NULL
|
160
|
+
);
|
161
|
+
LPTSTR tmp = strchr(lpMsgBuf, '\r');
|
162
|
+
if (tmp != NULL) {
|
163
|
+
*tmp = '\0';
|
164
|
+
}
|
165
|
+
|
166
|
+
_snprintf(str, strSize, " %s (%u)", lpMsgBuf, err);
|
167
|
+
LocalFree(lpMsgBuf);
|
168
|
+
#else
|
169
|
+
const char* error = strerror(errno);
|
170
|
+
snprintf(str, strSize, " %s (%u)", error, errno);
|
171
|
+
#endif
|
172
|
+
return str;
|
173
|
+
}
|
174
|
+
|
175
|
+
string gLogFileName;
|
176
|
+
|
177
|
+
void logV(bool appendSysError, bool showMsgBox, const char *format, va_list args) {
|
178
|
+
char msg[4096] = "";
|
179
|
+
vsnprintf(msg, 4096, format, args);
|
180
|
+
|
181
|
+
if (appendSysError) {
|
182
|
+
char sysErr[512] = "";
|
183
|
+
getSysError(sysErr, 512);
|
184
|
+
strncat(msg, sysErr, 4096 - strlen(msg));
|
185
|
+
}
|
186
|
+
|
187
|
+
if (!gLogFileName.empty()) {
|
188
|
+
FILE *file = fopen(gLogFileName.c_str(), "a");
|
189
|
+
if (file) {
|
190
|
+
fprintf(file, "%s\n", msg);
|
191
|
+
fclose(file);
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
if (showMsgBox) {
|
196
|
+
#ifdef WIN32
|
197
|
+
// Pop-up the message box only if there is no console
|
198
|
+
if (!isConsoleAttached()) {
|
199
|
+
::MessageBox(NULL, msg, "JRuby Error", MB_OK | MB_ICONSTOP);
|
200
|
+
}
|
201
|
+
#endif
|
202
|
+
fprintf(stderr, "%s\n", msg);
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
void logErr(bool appendSysError, bool showMsgBox, const char *format, ...) {
|
207
|
+
va_list args;
|
208
|
+
va_start(args, format);
|
209
|
+
logV(appendSysError, showMsgBox, format, args);
|
210
|
+
}
|
211
|
+
|
212
|
+
void logMsg(const char *format, ...) {
|
213
|
+
va_list args;
|
214
|
+
va_start(args, format);
|
215
|
+
logV(false, false, format, args);
|
216
|
+
}
|
217
|
+
|
218
|
+
bool checkLoggingArg(int argc, char *argv[], bool delFile) {
|
219
|
+
for (int i = 0; i < argc; i++) {
|
220
|
+
if (strcmp("--", argv[i]) == 0) {
|
221
|
+
break;
|
222
|
+
}
|
223
|
+
if (strcmp(ARG_NAME_LAUNCHER_LOG, argv[i]) == 0) {
|
224
|
+
if (i+1 == argc || *argv[i+1] == '-') {
|
225
|
+
return false;
|
226
|
+
}
|
227
|
+
gLogFileName = argv[++i];
|
228
|
+
if (delFile) {
|
229
|
+
#ifdef WIN32
|
230
|
+
DeleteFile(gLogFileName.c_str());
|
231
|
+
#else
|
232
|
+
unlink(gLogFileName.c_str());
|
233
|
+
#endif
|
234
|
+
}
|
235
|
+
break;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
return true;
|
239
|
+
}
|
240
|
+
|
241
|
+
bool printToConsole(const char *msg) {
|
242
|
+
fprintf(stderr, "%s", msg);
|
243
|
+
return false;
|
244
|
+
}
|
245
|
+
|
246
|
+
char** convertToArgvArray(list<string> args) {
|
247
|
+
char ** argv = (char**) malloc(sizeof (char*) * args.size() + 1);
|
248
|
+
int i = 0;
|
249
|
+
for (list<string>::iterator it = args.begin(); it != args.end(); ++it, ++i) {
|
250
|
+
argv[i] = (char*) malloc(sizeof(char) * it->length() + 1);
|
251
|
+
strncpy(argv[i], it->c_str(), it->length() + 1);
|
252
|
+
}
|
253
|
+
argv[i] = NULL;
|
254
|
+
return argv;
|
255
|
+
}
|
256
|
+
|
257
|
+
void addToArgList(list<string> & args, int argc, char ** argv) {
|
258
|
+
for (int i = 0; i < argc; i++) {
|
259
|
+
args.push_back(argv[i]);
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
int printArgvToConsole(char** argv) {
|
264
|
+
while (*argv) {
|
265
|
+
printf("%s\n", *argv);
|
266
|
+
argv++;
|
267
|
+
}
|
268
|
+
return 0;
|
269
|
+
}
|