1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | // |
6 | // A simple CoreCLR host that runs a managed binary with the same name as this executable but with the *.dll extension |
7 | // The dll binary must contain a main entry point. |
8 | // |
9 | |
10 | #include <coreruncommon.h> |
11 | #include <string> |
12 | #include <string.h> |
13 | #include <sys/stat.h> |
14 | |
15 | // Display the help text |
16 | void DisplayUsage() |
17 | { |
18 | fprintf( |
19 | stderr, |
20 | "Runs executables on CoreCLR\n\n" |
21 | "Usage: <program> [OPTIONS] [ARGUMENTS]\n" |
22 | "Runs <program>.dll on CoreCLR.\n\n" |
23 | "Options:\n" |
24 | "-_c path to libcoreclr.so and the managed CLR assemblies.\n" |
25 | "-_h show this help message. \n" ); |
26 | } |
27 | |
28 | // Parse the command line arguments |
29 | bool ParseArguments( |
30 | const int argc, |
31 | const char* argv[], |
32 | const char** clrFilesPath, |
33 | int* managedAssemblyArgc, |
34 | const char*** managedAssemblyArgv) |
35 | { |
36 | bool success = true; |
37 | |
38 | *clrFilesPath = nullptr; |
39 | *managedAssemblyArgv = nullptr; |
40 | *managedAssemblyArgc = 0; |
41 | |
42 | for (int i = 1; i < argc; i++) |
43 | { |
44 | // Check for options. Options to the Unix coreconsole are prefixed with '-_' to match the convention |
45 | // used in the Windows version of coreconsole. |
46 | if (strncmp(argv[i], "-_" , 2) == 0) |
47 | { |
48 | // Path to the libcoreclr.so and the managed CLR assemblies |
49 | if (strcmp(argv[i], "-_c" ) == 0) |
50 | { |
51 | i++; |
52 | if (i < argc) |
53 | { |
54 | *clrFilesPath = argv[i]; |
55 | } |
56 | else |
57 | { |
58 | fprintf(stderr, "Option %s: missing path\n" , argv[i - 1]); |
59 | success = false; |
60 | break; |
61 | } |
62 | } |
63 | else if (strcmp(argv[i], "-_h" ) == 0) |
64 | { |
65 | DisplayUsage(); |
66 | success = false; |
67 | break; |
68 | } |
69 | else |
70 | { |
71 | fprintf(stderr, "Unknown option %s\n" , argv[i]); |
72 | success = false; |
73 | break; |
74 | } |
75 | } |
76 | else |
77 | { |
78 | // We treat everything starting from the first non-option argument as arguments |
79 | // to the managed assembly. |
80 | *managedAssemblyArgc = argc - i; |
81 | if (*managedAssemblyArgc != 0) |
82 | { |
83 | *managedAssemblyArgv = &argv[i]; |
84 | } |
85 | |
86 | break; |
87 | } |
88 | } |
89 | |
90 | return success; |
91 | } |
92 | |
93 | int main(const int argc, const char* argv[]) |
94 | { |
95 | // Make sure we have a full path for argv[0]. |
96 | std::string entryPointExecutablePath; |
97 | |
98 | if (!GetEntrypointExecutableAbsolutePath(entryPointExecutablePath)) |
99 | { |
100 | perror("Could not get full path to current executable" ); |
101 | return -1; |
102 | } |
103 | |
104 | // We will try to load the managed assembly with the same name as this executable |
105 | // but with the .dll extension. |
106 | std::string programPath(entryPointExecutablePath); |
107 | programPath.append(".dll" ); |
108 | const char* managedAssemblyAbsolutePath = programPath.c_str(); |
109 | |
110 | // Check if the specified managed assembly file exists |
111 | struct stat sb; |
112 | if (stat(managedAssemblyAbsolutePath, &sb) == -1) |
113 | { |
114 | perror("Managed assembly not found" ); |
115 | return -1; |
116 | } |
117 | |
118 | // Verify that the managed assembly path points to a file |
119 | if (!S_ISREG(sb.st_mode)) |
120 | { |
121 | fprintf(stderr, "The specified managed assembly is not a file\n" ); |
122 | return -1; |
123 | } |
124 | |
125 | const char* clrFilesPath; |
126 | const char** managedAssemblyArgv; |
127 | int managedAssemblyArgc; |
128 | |
129 | if (!ParseArguments( |
130 | argc, |
131 | argv, |
132 | &clrFilesPath, |
133 | &managedAssemblyArgc, |
134 | &managedAssemblyArgv |
135 | )) |
136 | { |
137 | // Invalid command line |
138 | return -1; |
139 | } |
140 | |
141 | std::string clrFilesAbsolutePath; |
142 | if(!GetClrFilesAbsolutePath(entryPointExecutablePath.c_str(), clrFilesPath, clrFilesAbsolutePath)) |
143 | { |
144 | return -1; |
145 | } |
146 | |
147 | int exitCode = ExecuteManagedAssembly( |
148 | entryPointExecutablePath.c_str(), |
149 | clrFilesAbsolutePath.c_str(), |
150 | managedAssemblyAbsolutePath, |
151 | managedAssemblyArgc, |
152 | managedAssemblyArgv); |
153 | |
154 | return exitCode; |
155 | } |
156 | |