|
| 1 | +//===--- CommandLine.cpp - OS-specific command line arguments -------------===// |
| 2 | +// |
| 3 | +// This source file is part of the Swift.org open source project |
| 4 | +// |
| 5 | +// Copyright (c) 2016 Apple Inc. and the Swift project authors |
| 6 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 7 | +// |
| 8 | +// See http://swift.org/LICENSE.txt for license information |
| 9 | +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | +// |
| 13 | +// OS-specific command line argument handling is defined here. |
| 14 | +// |
| 15 | +//===----------------------------------------------------------------------===// |
| 16 | + |
| 17 | +#include <vector> |
| 18 | +#include <string> |
| 19 | +#include <cassert> |
| 20 | +#include <climits> |
| 21 | +#include <cstdarg> |
| 22 | +#include <cstdint> |
| 23 | +#include <cstdio> |
| 24 | +#include <cstdlib> |
| 25 | +#include <cstring> |
| 26 | + |
| 27 | +#include "swift/Runtime/Debug.h" |
| 28 | + |
| 29 | +#include "../SwiftShims/RuntimeStubs.h" |
| 30 | +#include "../SwiftShims/GlobalObjects.h" |
| 31 | + |
| 32 | +// Backing storage for overrides of `Swift.Process.arguments`. |
| 33 | +static char **_swift_stdlib_ProcessOverrideUnsafeArgv = nullptr; |
| 34 | +static int _swift_stdlib_ProcessOverrideUnsafeArgc = 0; |
| 35 | + |
| 36 | +SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE |
| 37 | +extern "C" void _swift_stdlib_overrideUnsafeArgvArgc(char **argv, int argc) { |
| 38 | + _swift_stdlib_ProcessOverrideUnsafeArgv = argv; |
| 39 | + _swift_stdlib_ProcessOverrideUnsafeArgc = argc; |
| 40 | +} |
| 41 | + |
| 42 | +#if defined(__APPLE__) |
| 43 | +// NOTE: forward declare this rather than including crt_externs.h as not all |
| 44 | +// SDKs provide it |
| 45 | +extern "C" char ***_NSGetArgv(void); |
| 46 | +extern "C" int *_NSGetArgc(void); |
| 47 | + |
| 48 | +SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE |
| 49 | +extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { |
| 50 | + assert(outArgLen != nullptr); |
| 51 | + |
| 52 | + if (_swift_stdlib_ProcessOverrideUnsafeArgv) { |
| 53 | + *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; |
| 54 | + return _swift_stdlib_ProcessOverrideUnsafeArgv; |
| 55 | + } |
| 56 | + |
| 57 | + *outArgLen = *_NSGetArgc(); |
| 58 | + return *_NSGetArgv(); |
| 59 | +} |
| 60 | +#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) |
| 61 | +SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE |
| 62 | +extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { |
| 63 | + assert(outArgLen != nullptr); |
| 64 | + |
| 65 | + if (_swift_stdlib_ProcessOverrideUnsafeArgv) { |
| 66 | + *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; |
| 67 | + return _swift_stdlib_ProcessOverrideUnsafeArgv; |
| 68 | + } |
| 69 | + |
| 70 | + FILE *cmdline = fopen("/proc/self/cmdline", "rb"); |
| 71 | + if (!cmdline) { |
| 72 | + swift::fatalError(0, |
| 73 | + "fatal error: Unable to open interface to '/proc/self/cmdline'.\n"); |
| 74 | + } |
| 75 | + char *arg = nullptr; |
| 76 | + size_t size = 0; |
| 77 | + std::vector<char *> argvec; |
| 78 | + while (getdelim(&arg, &size, 0, cmdline) != -1) { |
| 79 | + argvec.push_back(strdup(arg)); |
| 80 | + } |
| 81 | + if (arg) { |
| 82 | + free(arg); |
| 83 | + } |
| 84 | + fclose(cmdline); |
| 85 | + *outArgLen = argvec.size(); |
| 86 | + char **outBuf = (char **)calloc(argvec.size() + 1, sizeof(char *)); |
| 87 | + std::copy(argvec.begin(), argvec.end(), outBuf); |
| 88 | + outBuf[argvec.size()] = nullptr; |
| 89 | + |
| 90 | + return outBuf; |
| 91 | +} |
| 92 | +#elif defined (_MSC_VER) |
| 93 | +extern int *__argc; |
| 94 | +extern char **__argv; |
| 95 | + |
| 96 | +SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE |
| 97 | +extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { |
| 98 | + assert(outArgLen != nullptr); |
| 99 | + |
| 100 | + if (_swift_stdlib_ProcessOverrideUnsafeArgv) { |
| 101 | + *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; |
| 102 | + return _swift_stdlib_ProcessOverrideUnsafeArgv; |
| 103 | + } |
| 104 | + |
| 105 | + *outArgLen = __argc; |
| 106 | + return __argv; |
| 107 | +} |
| 108 | +#else // __ANDROID__; Add your favorite arch's command line arg grabber here. |
| 109 | +SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE |
| 110 | +extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { |
| 111 | + if (_swift_stdlib_ProcessOverrideUnsafeArgv) { |
| 112 | + *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; |
| 113 | + return _swift_stdlib_ProcessOverrideUnsafeArgv; |
| 114 | + } |
| 115 | + |
| 116 | + swift::fatalError(0, |
| 117 | + "fatal error: Command line arguments not supported on this platform.\n"); |
| 118 | +} |
| 119 | +#endif |
| 120 | + |
0 commit comments