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#include <coreruncommon.h>
6#include <string>
7#include <string.h>
8#include <sys/stat.h>
9
10// Display the command line options
11void DisplayUsage()
12{
13 fprintf(
14 stderr,
15 "Usage: corerun [OPTIONS] assembly [ARGUMENTS]\n"
16 "Execute the specified managed assembly with the passed in arguments\n\n"
17 "Options:\n"
18 "-c, --clr-path path to the libcoreclr.so and the managed CLR assemblies\n");
19}
20
21// Parse the command line arguments
22bool ParseArguments(
23 const int argc,
24 const char* argv[],
25 const char** clrFilesPath,
26 const char** managedAssemblyPath,
27 int* managedAssemblyArgc,
28 const char*** managedAssemblyArgv)
29{
30 bool success = false;
31
32 *clrFilesPath = nullptr;
33 *managedAssemblyPath = nullptr;
34 *managedAssemblyArgv = nullptr;
35 *managedAssemblyArgc = 0;
36
37 // The command line must contain at least the current exe name and the managed assembly path
38 if (argc >= 2)
39 {
40 for (int i = 1; i < argc; i++)
41 {
42 // Check for an option
43 if (argv[i][0] == '-')
44 {
45 // Path to the libcoreclr.so and the managed CLR assemblies
46 if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--clr-path") == 0)
47 {
48 i++;
49 if (i < argc)
50 {
51 *clrFilesPath = argv[i];
52 }
53 else
54 {
55 fprintf(stderr, "Option %s: missing path\n", argv[i - 1]);
56 break;
57 }
58 }
59 else if (strcmp(argv[i], "-?") == 0 || strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
60 {
61 DisplayUsage();
62 break;
63 }
64 else
65 {
66 fprintf(stderr, "Unknown option %s\n", argv[i]);
67 break;
68 }
69 }
70 else
71 {
72 // First argument that is not an option is the managed assembly to execute
73 *managedAssemblyPath = argv[i];
74
75 int managedArgvOffset = (i + 1);
76 *managedAssemblyArgc = argc - managedArgvOffset;
77 if (*managedAssemblyArgc != 0)
78 {
79 *managedAssemblyArgv = &argv[managedArgvOffset];
80 }
81 success = true;
82 break;
83 }
84 }
85 }
86 else
87 {
88 DisplayUsage();
89 }
90
91 return success;
92}
93
94int corerun(const int argc, const char* argv[])
95{
96 const char* clrFilesPath;
97 const char* managedAssemblyPath;
98 const char** managedAssemblyArgv;
99 int managedAssemblyArgc;
100
101 if (!ParseArguments(
102 argc,
103 argv,
104 &clrFilesPath,
105 &managedAssemblyPath,
106 &managedAssemblyArgc,
107 &managedAssemblyArgv))
108 {
109 // Invalid command line
110 return -1;
111 }
112
113 // Check if the specified managed assembly file exists
114 struct stat sb;
115 if (stat(managedAssemblyPath, &sb) == -1)
116 {
117 perror("Managed assembly not found");
118 return -1;
119 }
120
121 // Verify that the managed assembly path points to a file
122 if (!S_ISREG(sb.st_mode))
123 {
124 fprintf(stderr, "The specified managed assembly is not a file\n");
125 return -1;
126 }
127
128 // Make sure we have a full path for argv[0].
129 std::string argv0AbsolutePath;
130 if (!GetEntrypointExecutableAbsolutePath(argv0AbsolutePath))
131 {
132 perror("Could not get full path");
133 return -1;
134 }
135
136 std::string clrFilesAbsolutePath;
137 if(!GetClrFilesAbsolutePath(argv0AbsolutePath.c_str(), clrFilesPath, clrFilesAbsolutePath))
138 {
139 return -1;
140 }
141
142 std::string managedAssemblyAbsolutePath;
143 if (!GetAbsolutePath(managedAssemblyPath, managedAssemblyAbsolutePath))
144 {
145 perror("Failed to convert managed assembly path to absolute path");
146 return -1;
147 }
148
149 int exitCode = ExecuteManagedAssembly(
150 argv0AbsolutePath.c_str(),
151 clrFilesAbsolutePath.c_str(),
152 managedAssemblyAbsolutePath.c_str(),
153 managedAssemblyArgc,
154 managedAssemblyArgv);
155
156 return exitCode;
157}
158
159int main(const int argc, const char* argv[])
160{
161 return corerun(argc, argv);
162}
163