ian@0: // ian@0: // Boost.Process ian@0: // ~~~~~~~~~~~~~ ian@0: // ian@0: // Copyright (c) 2006, 2007 Julio M. Merino Vidal ian@0: // Copyright (c) 2008 Ilya Sokolov, Boris Schaeling ian@0: // Copyright (c) 2009 Boris Schaeling ian@0: // Copyright (c) 2010 Felipe Tanus, Boris Schaeling ian@0: // ian@0: // Distributed under the Boost Software License, Version 1.0. (See accompanying ian@0: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) ian@0: // ian@0: ian@0: /** ian@0: * \file boost/process/self.hpp ian@0: * ian@0: * Includes the declaration of the self class. ian@0: */ ian@0: ian@0: #ifndef BOOST_PROCESS_SELF_HPP ian@0: #define BOOST_PROCESS_SELF_HPP ian@0: ian@0: #include ian@0: ian@0: #if defined(BOOST_POSIX_API) ian@0: # include ian@0: # include ian@0: # include ian@0: # include ian@0: # if defined(__APPLE__) ian@0: # include ian@0: # endif ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: # include ian@0: #else ian@0: # error "Unsupported platform." ian@0: #endif ian@0: ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: #include ian@0: ian@0: #if defined(BOOST_POSIX_API) ian@0: extern "C" ian@0: { ian@0: extern char **environ; ian@0: } ian@0: #endif ian@0: ian@0: namespace boost { ian@0: namespace process { ian@0: ian@0: /** ian@0: * The self class provides access to the process itself. ian@0: */ ian@0: class self : public process, public boost::noncopyable ian@0: { ian@0: public: ian@0: /** ian@0: * Returns the self instance representing the caller's process. ian@0: */ ian@0: static self &get_instance() ian@0: { ian@0: static self *instance = 0; ian@0: if (!instance) ian@0: instance = new self; ian@0: return *instance; ian@0: } ian@0: ian@0: /** ian@0: * Returns the current environment. ian@0: * ian@0: * Returns the current process environment variables. Modifying the ian@0: * returned object has no effect on the current environment. ian@0: */ ian@0: static environment get_environment() ian@0: { ian@0: environment e; ian@0: ian@0: #if defined(BOOST_POSIX_API) ian@0: # if defined(__APPLE__) ian@0: char **env = *_NSGetEnviron(); ian@0: # else ian@0: char **env = environ; ian@0: # endif ian@0: ian@0: while (*env) ian@0: { ian@0: std::string s = *env; ian@0: std::string::size_type pos = s.find('='); ian@0: e.insert(environment::value_type(s.substr(0, pos), ian@0: s.substr(pos + 1))); ian@0: ++env; ian@0: } ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: # ifdef GetEnvironmentStrings ian@0: # undef GetEnvironmentStrings ian@0: # endif ian@0: ian@0: char *ms_environ = GetEnvironmentStrings(); ian@0: if (!ms_environ) ian@0: BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR( ian@0: "GetEnvironmentStrings() failed"); ian@0: try ian@0: { ian@0: char *env = ms_environ; ian@0: while (*env) ian@0: { ian@0: std::string s = env; ian@0: std::string::size_type pos = s.find('='); ian@0: e.insert(environment::value_type(s.substr(0, pos), ian@0: s.substr(pos + 1))); ian@0: env += s.size() + 1; ian@0: } ian@0: } ian@0: catch (...) ian@0: { ian@0: FreeEnvironmentStringsA(ms_environ); ian@0: throw; ian@0: } ian@0: FreeEnvironmentStringsA(ms_environ); ian@0: #endif ian@0: ian@0: return e; ian@0: } ian@0: ian@0: /** ian@0: * Returns the current work directory. ian@0: */ ian@0: static std::string get_work_dir() ian@0: { ian@0: #if defined(BOOST_POSIX_API) ian@0: #if defined(PATH_MAX) ian@0: char buffer[PATH_MAX]; ian@0: char *cwd = buffer; ian@0: long size = PATH_MAX; ian@0: #elif defined(_PC_PATH_MAX) ian@0: errno = 0; ian@0: long size = pathconf("/", _PC_PATH_MAX); ian@0: if (size == -1 && errno) ian@0: BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("pathconf(2) failed"); ian@0: else if (size == -1) ian@0: size = BOOST_PROCESS_POSIX_PATH_MAX; ian@0: BOOST_ASSERT(size > 0); ian@0: boost::scoped_array buffer(new char[size]); ian@0: char *cwd = buffer.get(); ian@0: #else ian@0: char buffer[BOOST_PROCESS_POSIX_PATH_MAX]; ian@0: char *cwd = buffer; ian@0: long size = BOOST_PROCESS_POSIX_PATH_MAX; ian@0: #endif ian@0: if (!getcwd(cwd, size)) ian@0: BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("getcwd(2) failed"); ian@0: BOOST_ASSERT(cwd[0] != '\0'); ian@0: return cwd; ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: BOOST_ASSERT(MAX_PATH > 0); ian@0: char cwd[MAX_PATH]; ian@0: if (!GetCurrentDirectoryA(sizeof(cwd), cwd)) ian@0: BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR( ian@0: "GetCurrentDirectory() failed"); ian@0: BOOST_ASSERT(cwd[0] != '\0'); ian@0: return cwd; ian@0: #endif ian@0: } ian@0: ian@0: private: ian@0: /** ian@0: * Constructs a new self object. ian@0: * ian@0: * Creates a new self object that represents the current process. ian@0: */ ian@0: self() : ian@0: #if defined(BOOST_POSIX_API) ian@0: process(getpid()) ian@0: #elif defined(BOOST_WINDOWS_API) ian@0: process(GetCurrentProcessId()) ian@0: #endif ian@0: { ian@0: } ian@0: }; ian@0: ian@0: } ian@0: } ian@0: ian@0: #endif