Skip to content

Commit ede70f2

Browse files
committed
rolled back FreeBSD /proc changes and rewrote as per @landonf suggestion, through sysctl() call. Kept the function as similar to the other functions as possible.
1 parent 69085ae commit ede70f2

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

stdlib/public/stubs/CommandLine.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,7 @@ extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) {
5757
*outArgLen = *_NSGetArgc();
5858
return *_NSGetArgv();
5959
}
60-
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__)
61-
#if defined(__FreeBSD__)
62-
# define PROCFS_CMDLINE_PATH "/proc/curproc/cmdline"
63-
#else
64-
# define PROCFS_CMDLINE_PATH "/proc/self/cmdline"
65-
#endif
60+
#elif defined(__linux__) || defined(__CYGWIN__)
6661
SWIFT_RUNTIME_STDLIB_INTERFACE
6762
extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) {
6863
assert(outArgLen != nullptr);
@@ -72,12 +67,10 @@ extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) {
7267
return _swift_stdlib_ProcessOverrideUnsafeArgv;
7368
}
7469

75-
FILE *cmdline = fopen(PROCFS_CMDLINE_PATH, "rb");
70+
FILE *cmdline = fopen("/proc/self/cmdline", "rb");
7671
if (!cmdline) {
7772
swift::fatalError(0,
78-
"fatal error: Unable to open interface to '"
79-
PROCFS_CMDLINE_PATH
80-
"'.\n");
73+
"fatal error: Unable to open interface to '/proc/self/cmdline'.\n");
8174
}
8275
char *arg = nullptr;
8376
size_t size = 0;
@@ -111,6 +104,42 @@ extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) {
111104
*outArgLen = __argc;
112105
return __argv;
113106
}
107+
#elif defined(__FreeBSD__)
108+
#include <errno.h>
109+
#include <unistd.h>
110+
#include <sys/types.h>
111+
#include <sys/param.h>
112+
#include <sys/sysctl.h>
113+
114+
SWIFT_RUNTIME_STDLIB_INTERFACE
115+
extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) {
116+
assert(outArgLen != nullptr);
117+
118+
if (_swift_stdlib_ProcessOverrideUnsafeArgv) {
119+
*outArgLen = _swift_stdlib_ProcessOverrideUnsafeArgc;
120+
return _swift_stdlib_ProcessOverrideUnsafeArgv;
121+
}
122+
123+
char argPtr[8192]; // or use ARG_MAX? 8192 is used in LLDB though..
124+
size_t argPtrSize = sizeof(argPtr);
125+
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, getpid() };
126+
if (sysctl(mib, 4, argPtr, &argPtrSize, NULL, 0) != 0)
127+
swift::fatalError(0, "fatal error: could not retrieve commandline "
128+
"arguments: sysctl: %s.\n", strerror(errno));
129+
130+
char *curPtr = argPtr;
131+
char *endPtr = argPtr + argPtrSize;
132+
133+
std::vector<char *> argvec;
134+
for (; curPtr < endPtr; curPtr += strlen(curPtr) + 1)
135+
argvec.push_back(strdup(curPtr));
136+
*outArgLen = argvec.size();
137+
char **outBuf = (char **)calloc(argvec.size() + 1, sizeof(char *));
138+
std::copy(argvec.begin(), argvec.end(), outBuf);
139+
outBuf[argvec.size()] = nullptr;
140+
141+
return outBuf;
142+
}
114143
#else // __ANDROID__; Add your favorite arch's command line arg grabber here.
115144
SWIFT_RUNTIME_STDLIB_INTERFACE
116145
extern "C" char ** _swift_stdlib_getUnsafeArgvArgc(int *outArgLen) {

0 commit comments

Comments
 (0)