//===--- CommandLine.cpp - OS-specific command line arguments -------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // OS-specific command line argument handling is defined here. // //===----------------------------------------------------------------------===// #include #include #include #include #include #include #include #include #include #include "swift/Runtime/Debug.h" #include "../SwiftShims/RuntimeStubs.h" #include "../SwiftShims/GlobalObjects.h" // Backing storage for overrides of `Swift.CommandLine.arguments`. static char **_swift_stdlib_ProcessOverrideUnsafeArgv = nullptr; static int _swift_stdlib_ProcessOverrideUnsafeArgc = 0; SWIFT_RUNTIME_STDLIB_INTERFACE extern "C" void _swift_stdlib_overrideUnsafeArgvArgc(char **argv, int argc) { _swift_stdlib_ProcessOverrideUnsafeArgv = argv; _swift_stdlib_ProcessOverrideUnsafeArgc = argc; } #if defined(__APPLE__) // NOTE: forward declare this rather than including crt_externs.h as not all // SDKs provide it extern "C" char ***_NSGetArgv(void); extern "C" int *_NSGetArgc(void); SWIFT_RUNTIME_STDLIB_INTERFACE extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { assert(outArgLen != nullptr); if (_swift_stdlib_ProcessOverrideUnsafeArgv) { *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; return _swift_stdlib_ProcessOverrideUnsafeArgv; } *outArgLen = *_NSGetArgc(); return *_NSGetArgv(); } #elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) #if defined(__FreeBSD__) # define PROCFS_CMDLINE_PATH "/proc/curproc/cmdline" #else # define PROCFS_CMDLINE_PATH "/proc/self/cmdline" #endif SWIFT_RUNTIME_STDLIB_INTERFACE extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { assert(outArgLen != nullptr); if (_swift_stdlib_ProcessOverrideUnsafeArgv) { *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; return _swift_stdlib_ProcessOverrideUnsafeArgv; } FILE *cmdline = fopen(PROCFS_CMDLINE_PATH, "rb"); if (!cmdline) { swift::fatalError(0, "fatal error: Unable to open interface to '" PROCFS_CMDLINE_PATH "'.\n"); } char *arg = nullptr; size_t size = 0; std::vector argvec; while (getdelim(&arg, &size, 0, cmdline) != -1) { argvec.push_back(strdup(arg)); } if (arg) { free(arg); } fclose(cmdline); *outArgLen = argvec.size(); char **outBuf = (char **)calloc(argvec.size() + 1, sizeof(char *)); std::copy(argvec.begin(), argvec.end(), outBuf); outBuf[argvec.size()] = nullptr; return outBuf; } #elif defined (_MSC_VER) #include SWIFT_RUNTIME_STDLIB_INTERFACE extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { assert(outArgLen != nullptr); if (_swift_stdlib_ProcessOverrideUnsafeArgv) { *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; return _swift_stdlib_ProcessOverrideUnsafeArgv; } *outArgLen = __argc; return __argv; } #else // __ANDROID__; Add your favorite arch's command line arg grabber here. SWIFT_RUNTIME_STDLIB_INTERFACE extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) { if (_swift_stdlib_ProcessOverrideUnsafeArgv) { *outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc; return _swift_stdlib_ProcessOverrideUnsafeArgv; } swift::fatalError(0, "fatal error: Command line arguments not supported on this platform.\n"); } #endif