/usr/include/ui-utilcpp/Misc.hpp is in libui-utilcpp-dev 1.8.3-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | /**
* @file
*/
#ifndef UI_UTIL_MISC_HPP
#define UI_UTIL_MISC_HPP
// STDC++
#include <string>
#include <vector>
#include <map>
#include <list>
#include <memory>
// C++ libraries
#include <ui-utilcpp/Exception.hpp>
#include <ui-utilcpp/Sys.hpp>
#include <ui-utilcpp/Text.hpp>
namespace UI {
namespace Util {
/** @brief Run "delete" on all vector elements, and clear the vector. *>.
*
* I.e. empty whole vector && call destructor for each ElType * - element.
*/
template <typename ElType>
void delAnySeqContainer(std::vector<ElType *> & l) throw()
{
for (typename std::vector<ElType *>::iterator i(l.begin()); i != l.end(); ++i)
{
delete *i;
}
l.clear();
}
/** @brief Run "std::free" on all vector elements, and clear the vector. *>.
*
* I.e. empty whole vector && call destructor for each ElType * - element.
*/
template <typename ElType>
void freeAnySeqContainer(std::vector<ElType *> & l) throw()
{
for (typename std::vector<ElType *>::iterator i(l.begin()); i != l.end(); ++i)
{
std::free((void *) *i);
}
l.clear();
}
/** @brief Utility to delete any map<string, anytype>.
*
* I.e. empty whole map && call destuctor for each ElType * - element.
*/
template <typename ElType>
void delStringMap(std::map<std::string, ElType *> & l) throw()
{
for (typename std::map<std::string, ElType *>::iterator i(l.begin()); i != l.end(); ++i)
{
delete i->second;
}
l.clear();
}
/** @brief Base adapter class to hold a pointer that can't be freed
* using standard "delete".
*
* Derived classes should overwrite the destructor accordingly (and
* add other tool methods at will).
*/
template <typename P>
class auto_base
{
public:
/** @brief Construct from any pointer (may be 0). */
auto_base(P * const p=0)
:p_(p)
{}
/** @brief Set controlled pointer (must not be 0). */
void set(P * const p)
{
assert(p);
p_ = p;
}
/** @brief Get underlying pointer. */
P * get() const
{
return p_;
}
/** @brief Smart dereferencing. */
P * operator->() const
{
return p_;
}
protected:
/** @brief Controlled pointer. */
P * p_;
};
/** @brief Control freeing of C vector pointers via delete[]. */
template<typename P>
class auto_cvec: public auto_base<P>
{
public:
/** @brief Control this C vector pointer created via new P[n]. */
auto_cvec(P * const p)
:auto_base<P>(p)
{}
/** @brief Free memory held by C vector via delete[]. */
~auto_cvec()
{
delete[] auto_base<P>::p_;
}
/** @brief Access an C vector element. */
P & operator[](int i)
{
return auto_base<P>::p_[i];
}
};
/** @brief Control freeing of memory via std::free. */
template <typename P>
class auto_free: public auto_base<P>
{
public:
/** @brief Control this memory allocated via std::*alloc. */
auto_free(P * const p)
:auto_base<P>(p)
{}
/** @brief Free memory via std::free. */
~auto_free()
{
std::free(auto_base<P>::p_);
}
};
/** @brief Reverse "find" for lists.
*
* @note Why doesn't "find(list.rbegin(), list.rend(), key)" work?
*
* @param l The list to search.
* @param key The key to find.
* @return Iterator to found key, or l.end() if not found.
*/
template <typename K>
typename std::list<K>::iterator reverse_lfind(std::list<K> & l, K const & key)
{
typename std::list<K>::iterator i(l.end());
do
{
--i;
if ((*i) == key)
{
return i;
}
}
while (i != l.begin());
return l.end();
}
/** @brief Get canonical absolute path name
*
* This effectively works like realpath(3), wrapped up for C++, w/ exception error handling.
*
* @see realpath(3)
* @bug realpath(3) is "broken by design". We need to create a char buffer of size MAX_PATH
* each time we call this function.
*/
std::string realpath(std::string const & path);
/** @brief Mutex Lock class; an object of this class will guard a scope.
*
* The Mutex class must provide enterMutex(), tryEnterMutex() and leaveMutex() methods.
*/
template <typename Mutex>
class MutexLock
{
public:
/** @brief Error codes for exceptions. */
enum ErrorCode
{
Locked_ = 1
};
/** @brief This classes exceptions. */
typedef CodeException<ErrorCode> Exception;
/** @brief Constructor; locks the mutex.
*
* @param mutex Any Mutex providing enterMutex(), tryEnterMutex() and leaveMutex().
* @param wait Whether to wait until the lock can be set, or to return with exception LOCKED.
*/
MutexLock(Mutex & mutex, bool wait=true) throw(Exception)
:mutex_(&mutex)
{
if (wait)
{
mutex_->enterMutex();
}
else
{
if (!mutex_->tryEnterMutex())
{
UI_THROW_CODE(Locked_, "Mutex is locked");
}
}
}
/** @brief Destructor; unlocks the mutex. */
~MutexLock()
{
mutex_->leaveMutex();
}
private:
Mutex * const mutex_;
};
/** @brief Get canonical absolute path name (mutex-protected)
*
* You should create one instance of this for one multi-threaded environment, and then
* call the object's get() method. Purpose is to be faster than realpath() by not having
* to create a buffer of MAX_PATH each time we call. Tests however suprisingly show
* it's even somewhat slower.
*
* @param path Path to canonize.
*
* @attention Do not use more than one object in a multi-threaded environment.
*
* @see UI::Util::realpath().
*
*/
template <typename M>
class RealPath
{
public:
/** @brief Get canonical path, mutex-protected. */
std::string get(std::string const & path)
{
MutexLock<M> lock(mutex_);
Sys::realpath(path.c_str(), buffer_);
return std::string(buffer_);
};
private:
M mutex_;
char buffer_[PATH_MAX];
};
/** @brief Helper class to get a scope executed with some other effective uid. */
class EUIDSwap
{
public:
/** @brief Error codes for exceptions. */
enum ErrorCode
{
SetEuidErr_ = 1
};
/** @brief This classes exceptions. */
typedef CodeException<ErrorCode> Exception;
EUIDSwap(uid_t uid=Sys::getuid());
~EUIDSwap();
/** @brief Get the original effective user id. */
uid_t getOrigUID() const;
private:
uid_t const origEUID_;
};
}}
#endif
|