00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include "sbuild-personality.h"
00023
00024 #include <cstring>
00025 #include <cerrno>
00026 #include <utility>
00027
00028 #ifdef __linux__
00029 #include <sys/personality.h>
00030 #endif
00031
00032 #include <boost/format.hpp>
00033
00034 using boost::format;
00035 using namespace sbuild;
00036
00037 namespace
00038 {
00039
00040 typedef std::pair<sbuild::personality::error_code,const char *> emap;
00041
00046 emap init_errors[] =
00047 {
00048
00049 emap(sbuild::personality::BAD, N_("Personality '%1%' is unknown")),
00050
00051 emap(sbuild::personality::SET, N_("Failed to set personality '%1%'"))
00052 };
00053
00054 typedef std::pair<std::string,sbuild::personality::type> pmap;
00055
00060 pmap initial_personalities[] =
00061 {
00062 pmap("undefined", 0xffffffff),
00063 #ifdef __linux__
00064 pmap("linux", PER_LINUX),
00065 pmap("linux_32bit", PER_LINUX_32BIT),
00066 pmap("svr4", PER_SVR4),
00067 pmap("scorvr3", PER_SCOSVR3),
00068 pmap("osr5", PER_OSR5),
00069 pmap("wysev386", PER_WYSEV386),
00070 pmap("iscr4", PER_ISCR4),
00071 pmap("bsd", PER_BSD),
00072 pmap("sunos", PER_SUNOS),
00073 pmap("xenix", PER_XENIX),
00074 pmap("linux32", PER_LINUX32),
00075 pmap("irix32", PER_IRIX32),
00076 pmap("irixn32", PER_IRIXN32),
00077 pmap("irix64", PER_IRIX64),
00078 pmap("riscos", PER_RISCOS),
00079 pmap("solaris", PER_SOLARIS),
00080 pmap("uw7", PER_UW7),
00081 pmap("hpux", PER_HPUX),
00082 pmap("osf4", PER_OSF4),
00083 #endif
00084 };
00085
00086 }
00087
00088 template<>
00089 error<sbuild::personality::error_code>::map_type
00090 error<sbuild::personality::error_code>::error_strings
00091 (init_errors,
00092 init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
00093
00094 std::map<std::string,sbuild::personality::type>
00095 sbuild::personality::personalities(initial_personalities,
00096 initial_personalities + (sizeof(initial_personalities) / sizeof(initial_personalities[0])));
00097
00098 sbuild::personality::personality ():
00099 persona(
00100 #ifdef __linux__
00101 ::personality(0xffffffff)
00102 #else
00103 0xffffffff
00104 #endif
00105 )
00106 {
00107 }
00108
00109 sbuild::personality::personality (type persona):
00110 persona(persona)
00111 {
00112 }
00113
00114 sbuild::personality::personality (std::string const& persona):
00115 persona(find_personality(persona))
00116 {
00117 }
00118
00119 sbuild::personality::~personality ()
00120 {
00121 }
00122
00123 sbuild::personality::type
00124 sbuild::personality::find_personality (std::string const& persona)
00125 {
00126 std::map<std::string,type>::const_iterator pos =
00127 personalities.find(persona);
00128
00129 if (pos != personalities.end())
00130 return pos->second;
00131
00132 return 0xffffffff;
00133 }
00134
00135 std::string const&
00136 sbuild::personality::find_personality (type persona)
00137 {
00138 static const std::string unknown("unknown");
00139
00140 for (std::map<std::string,type>::const_iterator pos = personalities.begin();
00141 pos != personalities.end();
00142 ++pos)
00143 if (pos->second == persona)
00144 return pos->first;
00145
00146 return unknown;
00147 }
00148
00149 std::string const&
00150 sbuild::personality::get_name () const
00151 {
00152 return find_personality(this->persona);
00153 }
00154
00155 sbuild::personality::type
00156 sbuild::personality::get () const
00157 {
00158 return this->persona;
00159 }
00160
00161 void
00162 sbuild::personality::set () const
00163 {
00164 #ifdef __linux__
00165
00166 if (this->persona != 0xffffffff &&
00167 ::personality (this->persona) < 0)
00168 {
00169 throw error(get_name(), SET, strerror(errno));
00170 }
00171 #endif
00172 }
00173
00174 std::string
00175 sbuild::personality::get_personalities ()
00176 {
00177
00178 format fmt(_("Valid personalities: %1%\n"));
00179 std::string ps;
00180
00181 for (std::map<std::string,type>::const_iterator pos = personalities.begin();
00182 pos != personalities.end();
00183 ++pos)
00184 {
00185 ps += pos->first;
00186 std::map<std::string,type>::const_iterator stpos = pos;
00187 if (++stpos != personalities.end())
00188 ps += ", ";
00189 }
00190
00191 fmt % ps;
00192
00193 return fmt.str();
00194 }