|
29 | 29 | #include "../SwiftShims/RuntimeStubs.h"
|
30 | 30 | #include "../SwiftShims/GlobalObjects.h"
|
31 | 31 |
|
| 32 | +#if defined(_WIN32) |
| 33 | +#define WIN32_LEAN_AND_MEAN |
| 34 | +#include <Windows.h> |
| 35 | +#include <shellapi.h> |
| 36 | +#endif |
| 37 | + |
32 | 38 | // Backing storage for overrides of `Swift.CommandLine.arguments`.
|
33 | 39 | static char **_swift_stdlib_ProcessOverrideUnsafeArgv = nullptr;
|
34 | 40 | static int _swift_stdlib_ProcessOverrideUnsafeArgc = 0;
|
@@ -101,8 +107,53 @@ char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) {
|
101 | 107 | return _swift_stdlib_ProcessOverrideUnsafeArgv;
|
102 | 108 | }
|
103 | 109 |
|
104 |
| - *outArgLen = __argc; |
105 |
| - return __argv; |
| 110 | + *outArgLen = 0; |
| 111 | + |
| 112 | + |
| 113 | + LPWSTR *szArgList; |
| 114 | + int nArgs; |
| 115 | + szArgList = CommandLineToArgvW(GetCommandLineW(), &nArgs); |
| 116 | + if (szArgList == nullptr) |
| 117 | + return nullptr; |
| 118 | + |
| 119 | + std::vector<char *> argv; |
| 120 | + for (int i = 0; i < nArgs; ++i) { |
| 121 | + int szBufferSize = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, |
| 122 | + szArgList[i], -1, nullptr, 0, |
| 123 | + nullptr, nullptr); |
| 124 | + if (szBufferSize == 0) { |
| 125 | + for (char *arg : argv) |
| 126 | + free(arg); |
| 127 | + return nullptr; |
| 128 | + } |
| 129 | + |
| 130 | + char *buffer = static_cast<char *>(calloc(static_cast<size_t>(szBufferSize), |
| 131 | + sizeof(char))); |
| 132 | + if (buffer == nullptr) { |
| 133 | + for (char *arg : argv) |
| 134 | + free(arg); |
| 135 | + return nullptr; |
| 136 | + } |
| 137 | + |
| 138 | + if (!WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, szArgList[i], -1, |
| 139 | + buffer, szBufferSize, nullptr, nullptr)) { |
| 140 | + for (char *arg : argv) |
| 141 | + free(arg); |
| 142 | + return nullptr; |
| 143 | + } |
| 144 | + |
| 145 | + argv.push_back(buffer); |
| 146 | + } |
| 147 | + |
| 148 | + LocalFree(szArgList); |
| 149 | + |
| 150 | + char **args = static_cast<char **>(calloc(argv.size() + 1, sizeof(char *))); |
| 151 | + std::copy(argv.begin(), argv.end(), args); |
| 152 | + args[argv.size()] = nullptr; |
| 153 | + |
| 154 | + assert(argv.size() < INT_MAX && "overflow"); |
| 155 | + *outArgLen = static_cast<int>(argv.size()); |
| 156 | + return args; |
106 | 157 | }
|
107 | 158 | #elif defined(__FreeBSD__)
|
108 | 159 | #include <errno.h>
|
|
0 commit comments