parent
24ac20563a
commit
7316f2fdd9
2 changed files with 348 additions and 0 deletions
@ -0,0 +1,199 @@ |
||||
/** @file
|
||||
|
||||
$Id$ |
||||
|
||||
$Date$ |
||||
$Author$ |
||||
@copy © Marc Wäckerlin |
||||
@license LGPL, see file <a href="license.html">COPYING</a> |
||||
|
||||
$Log$ |
||||
Revision 1.1 2005/02/08 12:30:22 marc |
||||
new in release 1.8.0 |
||||
|
||||
|
||||
1 2 3 4 5 6 7 8 |
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890 |
||||
*/ |
||||
|
||||
#include <mrw/errno.hpp> |
||||
#include <mrw/string.hpp> |
||||
#include <errno.h> |
||||
|
||||
static const mrw::Errno::ErrnoMapper::value_type AUX_MAP[] = { |
||||
std::make_pair(E2BIG, |
||||
"E2BIG: Arg list too long"), |
||||
std::make_pair(EACCES, |
||||
"EACCES: Permission denied"), |
||||
std::make_pair(EADDRINUSE, |
||||
"EADDRINUSE: Address in use"), |
||||
std::make_pair(EADDRNOTAVAIL, |
||||
"EADDRNOTAVAIL: Address not available"), |
||||
std::make_pair(EAFNOSUPPORT, |
||||
"EAFNOSUPPORT: Address family not supported"), |
||||
std::make_pair(EWOULDBLOCK, |
||||
"EWOULDBLOCK: Operation would block"), |
||||
std::make_pair(EAGAIN, |
||||
"EAGAIN: Resource temporarily unavailable"), |
||||
std::make_pair(EALREADY, |
||||
"EALREADY: Connection already in progress"), |
||||
std::make_pair(EBADF, |
||||
"EBADF: Bad file descriptor"), |
||||
std::make_pair(EBADMSG, |
||||
"EBADMSG: Bad message"), |
||||
std::make_pair(EBUSY, |
||||
"EBUSY: Resource busy"), |
||||
std::make_pair(ECANCELED, |
||||
"ECANCELED: Operation canceled"), |
||||
std::make_pair(ECHILD, |
||||
"ECHILD: No child processes"), |
||||
std::make_pair(ECONNABORTED, |
||||
"ECONNABORTED: Connection aborted"), |
||||
std::make_pair(ECONNREFUSED, |
||||
"ECONNREFUSED: Connection refused"), |
||||
std::make_pair(ECONNRESET, |
||||
"ECONNRESET: Connection reset"), |
||||
std::make_pair(EDEADLK, |
||||
"EDEADLK: Resource deadlock avoided"), |
||||
std::make_pair(EDESTADDRREQ, |
||||
"EDESTADDRREQ: Destination address required"), |
||||
std::make_pair(EDOM, |
||||
"EDOM: Domain error"), |
||||
std::make_pair(EDQUOT, |
||||
"EDQUOT: Reserved"), |
||||
std::make_pair(EEXIST, |
||||
"EEXIST: File exists"), |
||||
std::make_pair(EFAULT, |
||||
"EFAULT: Bad address"), |
||||
std::make_pair(EFBIG, |
||||
"EFBIG: File too large"), |
||||
std::make_pair(EHOSTUNREACH, |
||||
"EHOSTUNREACH: Host is unreachable"), |
||||
std::make_pair(EIDRM, |
||||
"EIDRM: Identifier removed"), |
||||
std::make_pair(EILSEQ, |
||||
"EILSEQ: Illegal byte sequence"), |
||||
std::make_pair(EINPROGRESS, |
||||
"EINPROGRESS: Operation in progress"), |
||||
std::make_pair(EINTR, |
||||
"EINTR: Interrupted function call"), |
||||
std::make_pair(EINVAL, |
||||
"EINVAL: Invalid argument"), |
||||
std::make_pair(EIO, |
||||
"EIO Input:/output error"), |
||||
std::make_pair(EISCONN, |
||||
"EISCONN: Socket is connected"), |
||||
std::make_pair(EISDIR, |
||||
"EISDIR: Is a directory"), |
||||
std::make_pair(ELOOP, |
||||
"ELOOP: Too many levels of symbolic links"), |
||||
std::make_pair(EMFILE, |
||||
"EMFILE: Too many open files"), |
||||
std::make_pair(EMLINK, |
||||
"EMLINK: Too many links"), |
||||
std::make_pair(EMSGSIZE, |
||||
"EMSGSIZE: Inappropriate message buffer length"), |
||||
std::make_pair(EMULTIHOP, |
||||
"EMULTIHOP: Reserved"), |
||||
std::make_pair(ENAMETOOLONG, |
||||
"ENAMETOOLONG: Filename too long"), |
||||
std::make_pair(ENETDOWN, |
||||
"ENETDOWN: Network is down"), |
||||
std::make_pair(ENETRESET, |
||||
"ENETRESET: Connection aborted by network"), |
||||
std::make_pair(ENETUNREACH, |
||||
"ENETUNREACH: Network unreachable"), |
||||
std::make_pair(ENFILE, |
||||
"ENFILE: Too many open files in system"), |
||||
std::make_pair(ENOBUFS, |
||||
"ENOBUFS: No buffer space available"), |
||||
std::make_pair(ENODATA, |
||||
"ENODATA: No message is available on the STREAM" |
||||
" head read queue"), |
||||
std::make_pair(ENODEV, |
||||
"ENODEV: No such device"), |
||||
std::make_pair(ENOENT, |
||||
"ENOENT: No such file or directory"), |
||||
std::make_pair(ENOEXEC, |
||||
"ENOEXEC: Exec format error"), |
||||
std::make_pair(ENOLCK, |
||||
"ENOLCK: No locks available"), |
||||
std::make_pair(ENOLINK, |
||||
"ENOLINK: Reserved"), |
||||
std::make_pair(ENOMEM, |
||||
"ENOMEM: Not enough space"), |
||||
std::make_pair(ENOMSG, |
||||
"ENOMSG: No message of the desired type"), |
||||
std::make_pair(ENOPROTOOPT, |
||||
"ENOPROTOOPT: Protocol not available"), |
||||
std::make_pair(ENOSPC, |
||||
"ENOSPC: No space left on device"), |
||||
std::make_pair(ENOSR, |
||||
"ENOSR: No STREAM resources"), |
||||
std::make_pair(ENOSTR, |
||||
"ENOSTR: Not a STREAM"), |
||||
std::make_pair(ENOSYS, |
||||
"ENOSYS: Function not implemented"), |
||||
std::make_pair(ENOTCONN, |
||||
"ENOTCONN: The socket is not connected"), |
||||
std::make_pair(ENOTDIR, |
||||
"ENOTDIR: Not a directory"), |
||||
std::make_pair(ENOTEMPTY, |
||||
"ENOTEMPTY: Directory not empty"), |
||||
std::make_pair(ENOTSOCK, |
||||
"ENOTSOCK: Not a socket"), |
||||
std::make_pair(ENOTSUP, |
||||
"ENOTSUP: Not supported"), |
||||
std::make_pair(ENOTTY, |
||||
"ENOTTY: Inappropriate I/O control operation"), |
||||
std::make_pair(ENXIO, |
||||
"ENXIO: No such device or address"), |
||||
std::make_pair(EOPNOTSUPP, |
||||
"EOPNOTSUPP: Operation not supported on socket"), |
||||
std::make_pair(EOVERFLOW, |
||||
"EOVERFLOW: Value too large to be stored in data type"), |
||||
std::make_pair(EPERM, |
||||
"EPERM: Operation not permitted"), |
||||
std::make_pair(EPIPE, |
||||
"EPIPE: Broken pipe"), |
||||
std::make_pair(EPROTO, |
||||
"EPROTO: Protocol error"), |
||||
std::make_pair(EPROTONOSUPPORT, |
||||
"EPROTONOSUPPORT: Protocol not supported"), |
||||
std::make_pair(EPROTOTYPE, |
||||
"EPROTOTYPE: Protocol wrong type for socket"), |
||||
std::make_pair(ERANGE, |
||||
"ERANGE: Result too large"), |
||||
std::make_pair(EROFS, |
||||
"EROFS Read:-only file system"), |
||||
std::make_pair(ESPIPE, |
||||
"ESPIPE: Invalid seek"), |
||||
std::make_pair(ESRCH, |
||||
"ESRCH: No such process"), |
||||
std::make_pair(ESTALE, |
||||
"ESTALE: Reserved"), |
||||
std::make_pair(ETIME, |
||||
"ETIME: STREAM ioctl() timeout"),
|
||||
std::make_pair(ETIMEDOUT, |
||||
"ETIMEDOUT: Operation timed out"), |
||||
std::make_pair(ETXTBSY, |
||||
"ETXTBSY: Test file busy"), |
||||
std::make_pair(EXDEV, |
||||
"EXDEV: Improper link") |
||||
}; |
||||
|
||||
mrw::Errno::Errno() throw(): _errno(errno) {} |
||||
|
||||
const mrw::Errno::ErrnoMapper |
||||
mrw::Errno::MAPPER(AUX_MAP, |
||||
AUX_MAP+sizeof(AUX_MAP)/sizeof(ErrnoMapper::value_type)); |
||||
|
||||
mrw::Errno::operator std::string() const throw(std::bad_exception) { |
||||
ErrnoMapper::const_iterator it(MAPPER.find(_errno)); |
||||
return it!=MAPPER.end() ? it->second : std::string("errno=")+_errno; |
||||
} |
||||
|
||||
std::string mrw::Errno::string() const throw(std::bad_exception) { |
||||
ErrnoMapper::const_iterator it(MAPPER.find(_errno)); |
||||
return it!=MAPPER.end() ? it->second : std::string("errno=")+_errno; |
||||
} |
@ -0,0 +1,149 @@ |
||||
/** @file
|
||||
|
||||
$Id$ |
||||
|
||||
$Date$ |
||||
$Author$ |
||||
|
||||
@copy © Marc Wäckerlin |
||||
@license LGPL, see file <a href="license.html">COPYING</a> |
||||
|
||||
$Log$ |
||||
Revision 1.1 2005/02/08 12:30:22 marc |
||||
new in release 1.8.0 |
||||
|
||||
|
||||
1 2 3 4 5 6 7 8 |
||||
5678901234567890123456789012345678901234567890123456789012345678901234567890 |
||||
*/ |
||||
|
||||
#ifndef __MRW_ERRNO_HPP__ |
||||
#define __MRW_ERRNO_HPP__ |
||||
|
||||
#include <mrw/exception.hpp> |
||||
#include <string> |
||||
#include <map> |
||||
|
||||
namespace mrw { |
||||
|
||||
/** @addtogroup exceptions
|
||||
|
||||
In addition to the reimplementation of the standard exceptions, |
||||
There is also a class mrw::Errno to handle UNIX C library errno |
||||
and an exception class mrw::unix_error to that uses mrw::Errno |
||||
to convert @c errno into a meaningful string and that offers |
||||
facilities to handle failed UNIX C library calls. */ |
||||
//@{
|
||||
|
||||
/** @brief Stores a UNIX errno error number and converts it to string.
|
||||
|
||||
@pre #include <mrw/errno.hpp> */ |
||||
class Errno { |
||||
|
||||
//............................................................... typedefs
|
||||
public: |
||||
|
||||
typedef std::map<int, std::string> ErrnoMapper; |
||||
|
||||
//................................................................ methods
|
||||
public: |
||||
|
||||
/// stores the actual @c errno
|
||||
Errno() throw(); |
||||
|
||||
/// returns a string that describes the error
|
||||
operator std::string() const throw(std::bad_exception); |
||||
|
||||
/// returns a string that describes the error
|
||||
std::string string() const throw(std::bad_exception); |
||||
|
||||
/// returns the @c errno stored in the constructor
|
||||
operator int() const throw() { |
||||
return _errno; |
||||
} |
||||
|
||||
/// returns the @c errno stored in the constructor
|
||||
int numerical() const throw() { |
||||
return _errno; |
||||
} |
||||
|
||||
//.............................................................. variables
|
||||
private: |
||||
|
||||
static const ErrnoMapper MAPPER; |
||||
|
||||
int _errno; |
||||
|
||||
}; |
||||
|
||||
/** @brief to be thrown when a unix system call fails, evaluates @c errno
|
||||
|
||||
@pre #include <mrw/errno.hpp> */ |
||||
|
||||
class unix_error: public mrw::runtime_error { |
||||
|
||||
//................................................................ methods
|
||||
public: |
||||
|
||||
/** @brief convert return value of a UNIX system call that sets @c errno
|
||||
to an exception |
||||
|
||||
Thought to be used like this: |
||||
@code |
||||
mrw::unix_error::check(sockfd=::socket(domain, type, 0), "socket"); |
||||
@endcode |
||||
or even simpler with a macro (sets text automatically): |
||||
@code |
||||
MRW_CHECK_UNIX(sockfd=::socket(domain, type, 0)); |
||||
@endcode |
||||
this is the same (but simpler to write) than: |
||||
@code |
||||
if ((sockfd=::socket(domain, type, 0)<0) |
||||
throw mrw::unix_error("socket"); |
||||
@endcode |
||||
|
||||
@param res the result of a UNIX C library operation |
||||
@param arg additional error information |
||||
@throw mrw::unix_error if res<0 */ |
||||
|
||||
static void check(int res, const std::string& arg) |
||||
throw(std::exception) { |
||||
if (res<0) throw mrw::unix_error(arg); |
||||
} |
||||
|
||||
/** @brief convert return value of a UNIX system call that sets @c errno
|
||||
to an exception |
||||
|
||||
Thought to be used like this: |
||||
@code |
||||
MRW_CHECK_UNIX(sockfd=::socket(domain, type, 0)); |
||||
@endcode |
||||
this is the same (but simpler to write) than: |
||||
@code |
||||
if ((sockfd=::socket(domain, type, 0)<0) |
||||
throw mrw::unix_error("sockfd=::socket(domain, type, 0)"); |
||||
@endcode |
||||
|
||||
@param CMD a UNIX operation to be executed and checked |
||||
@throw mrw::unix_error if return value of CMD < 0 */ |
||||
# define MRW_CHECK_UNIX(CMD) mrw::unix_error::check((CMD), # CMD) |
||||
|
||||
/** @brief construct an exception that stores the @c errno given an
|
||||
additional error text |
||||
|
||||
The error text returned by what() is: |
||||
|
||||
"unix error: " + Errno().string() + "; " + arg |
||||
|
||||
@param arg additional error text */ |
||||
|
||||
unix_error(const std::string& arg) throw(std::bad_exception): |
||||
mrw::runtime_error(std::string("unix error: ")+Errno().string() |
||||
+"; "+arg) { |
||||
} |
||||
}; |
||||
|
||||
//@}
|
||||
|
||||
} |
||||
#endif |
Loading…
Reference in new issue