peerplays-fc/include/boost/process/self.hpp
2012-12-19 12:23:12 -05:00

188 lines
4.7 KiB
C++

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