Created
May 17, 2016 18:43
-
-
Save neoneye/3d11bf5a0a8c3a919b55ae8a119ea06d to your computer and use it in GitHub Desktop.
posix_spawn with an "environment" class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright © 2015 Simon Strandgaard. All rights reserved. | |
// MIT license | |
#include "environment.hpp" | |
#include <unistd.h> | |
#include <iostream> | |
#include <boost/algorithm/string/predicate.hpp> | |
extern char **environ; | |
void Environment::populateWithGlobalEnvironment() { | |
for (char **env = ::environ; *env; ++env) { | |
environment.push_back(*env); | |
} | |
} | |
void Environment::prependRaw(const std::string &env) { | |
environment.insert(environment.begin(), env); | |
} | |
void Environment::appendRaw(const std::string &env) { | |
environment.push_back(env); | |
} | |
void Environment::print() { | |
for (auto &env: environment) { | |
std::cout << "environment-item: " << env << std::endl; | |
} | |
} | |
boost::optional<std::string> Environment::get(const std::string &key) { | |
std::string prefix(key + "="); | |
for (auto &env: environment) { | |
if (!boost::starts_with(env, prefix)) { continue; } | |
return env.substr(prefix.size()); | |
} | |
return boost::none; | |
} | |
void Environment::set(const std::string &key, const std::string &value) { | |
std::string prefix(key + "="); | |
std::string combined(key + "=" + value); | |
int i = -1; | |
for (auto &env: environment) { | |
++i; | |
if (!boost::starts_with(env, prefix)) { continue; } | |
environment[i] = combined; | |
return; | |
} | |
environment.push_back(combined); | |
} | |
bool Environment::remove(const std::string &key) { | |
std::string prefix(key + "="); | |
int i = -1; | |
for (auto &env: environment) { | |
++i; | |
if (!boost::starts_with(env, prefix)) { continue; } | |
environment.erase(environment.begin() + i); | |
return true; | |
} | |
return false; | |
} | |
CStringArrayPtr Environment::c_str_array() { | |
size_t n = environment.size(); | |
size_t n1 = n + 1; | |
CStringArrayPtr result( | |
new const char*[n1], | |
std::default_delete<const char*[]>() | |
); | |
const char** array = result.get(); | |
for (size_t i=0; i<n; ++i) { | |
array[i] = environment[i].c_str(); | |
} | |
array[n] = 0; | |
return result; | |
} | |
void Environment::prepend(const std::string &key, const std::string &value, const std::string &separator) { | |
boost::optional<std::string> s = get(key); | |
std::string joinedValue(value); | |
if (s) { | |
joinedValue += separator + s.value(); | |
} | |
set(key, joinedValue); | |
} | |
void Environment::append(const std::string &key, const std::string &value, const std::string &separator) { | |
boost::optional<std::string> s = get(key); | |
std::string joinedValue; | |
if (s) { | |
joinedValue = s.value() + separator; | |
} | |
joinedValue += value; | |
set(key, joinedValue); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright © 2015 Simon Strandgaard. All rights reserved. | |
// MIT license | |
#ifndef environment_hpp | |
#define environment_hpp | |
#include <vector> | |
#include <string> | |
#include <memory> | |
#include <boost/optional.hpp> | |
typedef std::shared_ptr<const char*> CStringArrayPtr; | |
class Environment { | |
private: | |
std::vector<std::string> environment; | |
public: | |
void populateWithGlobalEnvironment(); | |
void prependRaw(const std::string &env); | |
void appendRaw(const std::string &env); | |
void print(); | |
boost::optional<std::string> get(const std::string &key); | |
void set(const std::string &key, const std::string &value); | |
bool remove(const std::string &key); | |
CStringArrayPtr c_str_array(); | |
void prepend(const std::string &key, const std::string &value, const std::string &separator); | |
void append(const std::string &key, const std::string &value, const std::string &separator); | |
}; | |
#endif /* environment_hpp */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright © 2015 Simon Strandgaard. All rights reserved. | |
// MIT license | |
const char *argv[] = { | |
NULL, | |
NULL | |
}; | |
argv[0] = path_to_executable.c_str(); | |
Environment e; | |
e.populateWithGlobalEnvironment(); | |
Configuration::getInstance().updateEnvironmentWithStuff1(e); | |
Configuration::getInstance().updateEnvironmentWithStuff2(e); | |
e.set("MYAPP_USER_ID", user_id); | |
e.set("MYAPP_TIMESTAMP", timestamp); | |
CStringArrayPtr ptr = e.c_str_array(); | |
char * const* environ2 = const_cast<char * const*>(ptr.get()); | |
int exitStatus = -1; | |
pid_t pid; | |
int status = ::posix_spawn(&pid, argv[0], NULL, NULL, (char * const*)argv, environ2); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment