new in release 1.8.0
This commit is contained in:
		
							
								
								
									
										199
									
								
								mrw/errno.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								mrw/errno.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
| } | ||||
							
								
								
									
										149
									
								
								mrw/errno.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								mrw/errno.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||
		Reference in New Issue
	
	Block a user