1919
2020#include < atomic>
2121#include < cerrno>
22+ #include < climits>
2223#include < cstdarg>
2324
2425#include " Executor.h"
26+ #include " Linker.h"
2527#include " Logger.h"
2628#include " Resolver.h"
2729#include " Session.h"
2830
31+ #if defined HAVE_NSGETENVIRON
32+ #include < crt_externs.h>
33+ #else
34+ #include < unistd.h>
35+
36+ #endif
37+
2938namespace {
3039
3140 size_t va_length (va_list& args)
@@ -41,6 +50,24 @@ namespace {
4150 for (size_t idx = 0 ; idx < argc; ++idx)
4251 argv[idx] = va_arg (args, char *);
4352 }
53+
54+ /* *
55+ * Abstraction to get the current environment.
56+ *
57+ * When the dynamic linker loads the library the `environ` variable
58+ * might not be available. (This is the case for OSX.) This method
59+ * makes it uniform to access the current environment on all platform.
60+ *
61+ * @return the current environment.
62+ */
63+ const char ** environment () noexcept
64+ {
65+ #ifdef HAVE_NSGETENVIRON
66+ return const_cast <const char **>(*_NSGetEnviron ());
67+ #else
68+ return const_cast <const char **>(environ);
69+ #endif
70+ }
4471}
4572
4673/* *
@@ -50,13 +77,13 @@ namespace {
5077 */
5178namespace {
5279 // This is the only non stack memory that this library is using.
53- constexpr size_t BUFFER_SIZE = 15 * 1024 ;
80+ constexpr size_t BUFFER_SIZE = PATH_MAX * 2 ;
5481 char BUFFER[BUFFER_SIZE];
5582 // This is used for being multi thread safe (loading time only).
5683 std::atomic<bool > LOADED (false );
5784 // These are related to the functionality of this library.
5885 el::Session SESSION = el::session::init();
59- el::Resolver RESOLVER ;
86+ el::Linker LINKER ;
6087
6188 constexpr el::log::Logger LOGGER (" lib.cc" );
6289}
@@ -73,7 +100,7 @@ extern "C" void on_load()
73100 if (LOADED.exchange (true ))
74101 return ;
75102
76- el::session::from (SESSION, RESOLVER. environment ());
103+ el::session::from (SESSION, environment ());
77104 el::session::persist (SESSION, BUFFER, BUFFER + BUFFER_SIZE);
78105
79106 el::log::Level level = SESSION.verbose ? el::log::VERBOSE : el::log::SILENT;
@@ -101,7 +128,8 @@ extern "C" int execve(const char* path, char* const argv[], char* const envp[])
101128{
102129 LOGGER.debug (" execve path: " , path);
103130
104- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execve (path, argv, envp);
131+ el::Resolver resolver;
132+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execve (path, argv, envp);
105133 errno = result.error_code ;
106134 return result.return_value ;
107135}
@@ -110,8 +138,9 @@ extern "C" int execv(const char* path, char* const argv[])
110138{
111139 LOGGER.debug (" execv path: " , path);
112140
113- auto envp = const_cast <char * const *>(RESOLVER.environment ());
114- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execve (path, argv, envp);
141+ auto envp = const_cast <char * const *>(environment ());
142+ el::Resolver resolver;
143+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execve (path, argv, envp);
115144 errno = result.error_code ;
116145 return result.return_value ;
117146}
@@ -120,7 +149,8 @@ extern "C" int execvpe(const char* file, char* const argv[], char* const envp[])
120149{
121150 LOGGER.debug (" execvpe file: " , file);
122151
123- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execvpe (file, argv, envp);
152+ el::Resolver resolver;
153+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execvpe (file, argv, envp);
124154 errno = result.error_code ;
125155 return result.return_value ;
126156}
@@ -129,8 +159,9 @@ extern "C" int execvp(const char* file, char* const argv[])
129159{
130160 LOGGER.debug (" execvp file: " , file);
131161
132- auto envp = const_cast <char * const *>(RESOLVER.environment ());
133- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execvpe (file, argv, envp);
162+ auto envp = const_cast <char * const *>(environment ());
163+ el::Resolver resolver;
164+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execvpe (file, argv, envp);
134165 errno = result.error_code ;
135166 return result.return_value ;
136167}
@@ -139,8 +170,9 @@ extern "C" int execvP(const char* file, const char* search_path, char* const arg
139170{
140171 LOGGER.debug (" execvP file: " , file);
141172
142- auto envp = const_cast <char * const *>(RESOLVER.environment ());
143- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execvP (file, search_path, argv, envp);
173+ auto envp = const_cast <char * const *>(environment ());
174+ el::Resolver resolver;
175+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execvP (file, search_path, argv, envp);
144176 errno = result.error_code ;
145177 return result.return_value ;
146178}
@@ -149,7 +181,8 @@ extern "C" int exect(const char* path, char* const argv[], char* const envp[])
149181{
150182 LOGGER.debug (" exect path: " , path);
151183
152- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execve (path, argv, envp);
184+ el::Resolver resolver;
185+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execve (path, argv, envp);
153186 errno = result.error_code ;
154187 return result.return_value ;
155188}
@@ -173,8 +206,9 @@ extern "C" int execl(const char* path, const char* arg, ...)
173206 va_copy_n (ap, &argv[1 ], argc + 1 );
174207 va_end (ap);
175208
176- auto envp = const_cast <char * const *>(RESOLVER.environment ());
177- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execve (path, argv, envp);
209+ auto envp = const_cast <char * const *>(environment ());
210+ el::Resolver resolver;
211+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execve (path, argv, envp);
178212 errno = result.error_code ;
179213 return result.return_value ;
180214}
@@ -195,8 +229,9 @@ extern "C" int execlp(const char* file, const char* arg, ...)
195229 va_copy_n (ap, &argv[1 ], argc + 1 );
196230 va_end (ap);
197231
198- auto envp = const_cast <char * const *>(RESOLVER.environment ());
199- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execvpe (file, argv, envp);
232+ auto envp = const_cast <char * const *>(environment ());
233+ el::Resolver resolver;
234+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execvpe (file, argv, envp);
200235 errno = result.error_code ;
201236 return result.return_value ;
202237}
@@ -219,7 +254,8 @@ extern "C" int execle(const char* path, const char* arg, ...)
219254 char ** envp = va_arg (ap, char **);
220255 va_end (ap);
221256
222- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).execve (path, argv, envp);
257+ el::Resolver resolver;
258+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).execve (path, argv, envp);
223259 errno = result.error_code ;
224260 return result.return_value ;
225261}
@@ -233,7 +269,8 @@ extern "C" int posix_spawn(pid_t* pid, const char* path,
233269{
234270 LOGGER.debug (" posix_spawn path:" , path);
235271
236- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).posix_spawn (pid, path, file_actions, attrp, argv, envp);
272+ el::Resolver resolver;
273+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).posix_spawn (pid, path, file_actions, attrp, argv, envp);
237274 errno = result.error_code ;
238275 return result.return_value ;
239276}
@@ -245,7 +282,8 @@ extern "C" int posix_spawnp(pid_t* pid, const char* file,
245282{
246283 LOGGER.debug (" posix_spawnp file:" , file);
247284
248- const el::Executor::Result result = el::Executor (RESOLVER, SESSION).posix_spawnp (pid, file, file_actions, attrp, argv, envp);
285+ el::Resolver resolver;
286+ const el::Executor::Result result = el::Executor (LINKER, SESSION, resolver).posix_spawnp (pid, file, file_actions, attrp, argv, envp);
249287 errno = result.error_code ;
250288 return result.return_value ;
251289}
0 commit comments