From 7316f2fdd978d0deb574d876d16654bb499cbc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Tue, 8 Feb 2005 12:30:22 +0000 Subject: [PATCH] new in release 1.8.0 --- mrw/errno.cpp | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++ mrw/errno.hpp | 149 +++++++++++++++++++++++++++++++++++++ 2 files changed, 348 insertions(+) create mode 100644 mrw/errno.cpp create mode 100644 mrw/errno.hpp diff --git a/mrw/errno.cpp b/mrw/errno.cpp new file mode 100644 index 0000000..c206ad7 --- /dev/null +++ b/mrw/errno.cpp @@ -0,0 +1,199 @@ +/** @file + + $Id$ + + $Date$ + $Author$ + @copy © Marc Wäckerlin + @license LGPL, see file COPYING + + $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 +#include +#include + +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; +} diff --git a/mrw/errno.hpp b/mrw/errno.hpp new file mode 100644 index 0000000..624f9b9 --- /dev/null +++ b/mrw/errno.hpp @@ -0,0 +1,149 @@ +/** @file + + $Id$ + + $Date$ + $Author$ + + @copy © Marc Wäckerlin + @license LGPL, see file COPYING + + $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 +#include +#include + +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 */ + class Errno { + + //............................................................... typedefs + public: + + typedef std::map 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 */ + + 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