$search
00001 00009 /***************************************************************************** 00010 ** Cross platform 00011 *****************************************************************************/ 00012 00013 #include <ecl/config/ecl.hpp> 00014 #ifndef ECL_IS_MAC 00015 #ifdef ECL_IS_POSIX 00016 00017 /***************************************************************************** 00018 ** Includes 00019 *****************************************************************************/ 00020 00021 #include <sstream> 00022 #include <errno.h> 00023 #include <netdb.h> // gethostbyname 00024 #include <ecl/exceptions/standard_exception.hpp> 00025 #include "../../../include/ecl/devices/detail/socket_exception_handler_pos.hpp" 00026 00027 /***************************************************************************** 00028 ** Namespaces 00029 *****************************************************************************/ 00030 00031 namespace ecl { 00032 namespace devices { 00033 00034 StandardException socket_exception(const char* loc) { 00035 switch( errno ) { 00036 case ( EACCES ) : return StandardException(LOC,OpenError,"Unable to open socket. Permission to create is denied."); 00037 case ( EAFNOSUPPORT): return StandardException(LOC,NotSupportedError,"Unable to open socket. Your implementation does not support the specified address family (in this case AF_INET or otherwise known as ipv4)."); 00038 case ( EINVAL ) : return StandardException(LOC,InvalidArgError,"Unable to open socket. Unknown or invalid protocol, family."); 00039 case ( EMFILE ) : return StandardException(LOC,OutOfRangeError,"Unable to open socket. Process file table overflow."); 00040 case ( ENFILE ) : return StandardException(LOC,OutOfResourcesError,"Unable to open socket. The system limit on the number of open files has been reached."); 00041 case ( ENOBUFS ) : return StandardException(LOC,MemoryError,"Unable to open socket. Insufficient memory available."); 00042 case ( ENOMEM ) : return StandardException(LOC,MemoryError,"Unable to open socket. Insufficient memory available."); 00043 case ( EPROTONOSUPPORT ) : return StandardException(LOC,NotSupportedError,"Unable to open socket. The protocol type (socket streams) is not supported within this address family (ipv4)."); 00044 default : { 00045 std::ostringstream ostream; 00046 ostream << "Unknown errno [" << errno << "]"; 00047 return StandardException(loc, UnknownError, ostream.str()); 00048 } 00049 } 00050 } 00051 00052 StandardException bind_exception(const char* loc) { 00053 switch( errno ) { 00054 case ( EACCES ) : return StandardException(LOC,PermissionsError,"Unable to bind the socket. The address is protected (maybe need to be superuser?)."); 00055 case ( EADDRINUSE ) : return StandardException(LOC,BusyError,"Unable to bind the socket. Address already in use (might be timing out, try again in a moment)."); 00056 case ( EBADF ) : return StandardException(LOC,InvalidObjectError,"Unable to bind the socket. Not a valid socket descriptor."); 00057 case ( EINVAL ) : return StandardException(LOC,BusyError,"Unable to bind the socket. The socket is already bound to an address."); 00058 case ( ENOTSOCK ) : return StandardException(LOC,InvalidObjectError,"Unable to bind the socket. The descriptor is a file descriptor, not a socket descriptor."); 00059 case ( EADDRNOTAVAIL ) : return StandardException(LOC,InvalidObjectError,"Unable to bind the socket. Interface does not exist or is not local."); 00060 case ( EFAULT ) : return StandardException(LOC,OutOfRangeError,"Unable to bind the socket. Socket specification is outside the user address space."); 00061 case ( ELOOP ) : return StandardException(LOC,SystemFailureError,"Unable to bind the socket. Too many symbolic links involved."); 00062 case ( ENAMETOOLONG ) : return StandardException(LOC,InvalidArgError,"Unable to bind the socket. Address is too long."); 00063 case ( ENOENT ) : return StandardException(LOC,InvalidObjectError,"Unable to bind the socket. The file does not exist."); 00064 case ( ENOMEM ) : return StandardException(LOC,MemoryError,"Unable to bind the socket. Insufficient kernel memory."); 00065 case ( ENOTDIR ) : return StandardException(LOC,InvalidArgError,"Unable to bind the socket. A component of the path prefix is not a directory."); 00066 case ( EROFS ) : return StandardException(LOC,PermissionsError,"Unable to bind the socket. Socket inode resides on a read only file system."); 00067 default : { 00068 std::ostringstream ostream; 00069 ostream << "Unknown error [" << errno << "]"; 00070 return StandardException(loc, UnknownError, ostream.str()); 00071 } 00072 } 00073 } 00074 00075 StandardException accept_exception(const char* loc) { 00076 switch( errno ) { 00077 case ( EWOULDBLOCK ) : return StandardException(LOC,BlockingError,"Unable to accept client connection. The socket is non-blocking and no connections are available."); 00078 case ( EBADF ) : return StandardException(LOC,InvalidObjectError,"Unable to accept client connection. Not a valid socket descriptor."); 00079 case ( ECONNABORTED ): return StandardException(LOC,InterruptedError,"Unable to accept client connection. A connection has been aborted."); 00080 case ( EINTR ) : return StandardException(LOC,InterruptedError,"Unable to accept client connection. A system signal has interrupted."); 00081 case ( EINVAL ) : return StandardException(LOC,UsageError,"Unable to accept client connection. Socket is not listening for connections or address length is invalid."); 00082 case ( EMFILE ) : return StandardException(LOC,OutOfResourcesError,"Unable to accept client connection. The system or per-process limit on files has been reached."); 00083 case ( ENFILE ) : return StandardException(LOC,OutOfResourcesError,"Unable to accept client connection. The system or per-process limit on files has been reached."); 00084 case ( ENOTSOCK ) : return StandardException(LOC,InvalidObjectError,"Unable to accept client connection. The descriptor is a file descriptor, not a socket descriptor.."); 00085 case ( EOPNOTSUPP ) : return StandardException(LOC,InvalidObjectError,"Unable to accept client connection. The client socket is not of type SOCK_STREAM."); 00086 case ( EFAULT ) : return StandardException(LOC,PermissionsError,"Unable to accept client connection. The address argument is not writable by the user."); 00087 case ( ENOBUFS ) : return StandardException(LOC,MemoryError,"Unable to accept client connection. Not enough free memory (buffer or system)."); 00088 case ( ENOMEM ) : return StandardException(LOC,MemoryError,"Unable to accept client connection. Not enough free memory (buffer or system)."); 00089 case ( EPROTO ) : return StandardException(LOC,InvalidArgError,"Unable to accept client connection. Protocol error."); 00090 case ( EPERM ) : return StandardException(LOC,PermissionsError,"Unable to accept client connection. Permissions do not allow this connection."); 00091 default : { 00092 std::ostringstream ostream; 00093 ostream << "Unknown error [" << errno << "]"; 00094 return StandardException(loc, UnknownError, ostream.str()); 00095 } 00096 } 00097 } 00098 00099 StandardException receive_exception(const char* loc) { 00100 00101 switch( errno ) { 00102 case ( EAGAIN || EWOULDBLOCK ) : return StandardException(LOC,InterruptedError,"Unable to read the socket. Probably a timeout occured."); 00103 case ( EBADF ) : return StandardException(LOC,InvalidObjectError,"Unable to read the socket. Bad file descriptor."); 00104 case ( ECONNREFUSED) : return StandardException(LOC,ConnectionError,"Unable to read the socket. Remote host refused the connection (probably not running)."); 00105 case ( EFAULT ) : return StandardException(LOC,SystemFailureError,"Unable to read the socket. Receive buffer has an address problem."); 00106 case ( EINTR ) : return StandardException(LOC,InterruptedError,"Unable to read the socket. Signal interruption."); 00107 case ( EINVAL ) : return StandardException(LOC,InvalidArgError,"Unable to read the socket. Invalid argument was used."); 00108 case ( ENOMEM ) : return StandardException(LOC,MemoryError,"Unable to read the socket. Could not allocate memory for the operation."); 00109 case ( ENOTCONN ) : return StandardException(LOC,ConnectionError,"Unable to read the socket. Has not been connected."); 00110 case ( ENOTSOCK ) : return StandardException(LOC,InvalidObjectError,"Unable to read the socket. The file descriptor does not refer to a socket."); 00111 default : { 00112 std::ostringstream ostream; 00113 ostream << "Unknown error [" << errno << "]"; 00114 return StandardException(loc, UnknownError, ostream.str()); 00115 } 00116 } 00117 } 00118 00119 StandardException send_exception(const char* loc) { 00120 00121 switch( errno ) { 00122 case ( EAGAIN || EWOULDBLOCK ) : return StandardException(LOC,BlockingError,"Unable to write to the socket. Socket is configured as non-blocking and this would block."); 00123 case ( EWOULDBLOCK ) : return StandardException(LOC,BlockingError,"Unable to write to the socket. Socket is configured as non-blocking and this would block."); 00124 case ( EACCES ) : return StandardException(LOC,PermissionsError,"Unable to write to the socket. Permission to write is denied."); 00125 case ( EBADF ) : return StandardException(LOC,InvalidObjectError,"Unable to write to the socket. Bad file descriptor."); 00126 case ( ECONNRESET ) : return StandardException(LOC,InterruptedError,"Unable to write to the socket. Connection reset by peer."); 00127 case ( EFAULT ) : return StandardException(LOC,SystemFailureError,"Unable to write to the socket. Buffer has an address problem."); 00128 case ( EINTR ) : return StandardException(LOC,InterruptedError,"Unable to write to the socket. Signal interruption."); 00129 case ( EINVAL ) : return StandardException(LOC,InvalidArgError,"Unable to write to the socket. Invalid argument was used."); 00130 case ( EISCONN ) : return StandardException(LOC,ConnectionError,"Unable to write to the socket. Connection mismatch???"); 00131 case ( EMSGSIZE ) : return StandardException(LOC,WriteError,"Unable to write to the socket. Socket type required to send atomically, but the size of this message is too large to handle in this way."); 00132 case ( ENOBUFS ) : return StandardException(LOC,OutOfResourcesError,"Unable to write to the socket. Output queue is full (could be caused by transient congestion, but this doesn't usually happen in linux which typically just drops packets)."); 00133 case ( ENOMEM ) : return StandardException(LOC,MemoryError,"Unable to write to the socket. Could not allocate memory for the operation."); 00134 case ( ENOTCONN ) : return StandardException(LOC,ConnectionError,"Unable to write to the socket. Has not been connected."); 00135 case ( ENOTSOCK ) : return StandardException(LOC,InvalidObjectError,"Unable to write to the socket. The file descriptor does not refer to a socket."); 00136 case ( EOPNOTSUPP ) : return StandardException(LOC,NotSupportedError,"Unable to write to the socket. Some api here not supported."); 00137 case ( EPIPE ) : return StandardException(LOC,InterruptedError,"Unable to write to the socket. Local end has been shutdown. Probably bad and will receive a SIGPIPE signal too."); 00138 default : { 00139 std::ostringstream ostream; 00140 ostream << "Unknown error [" << errno << "]"; 00141 return StandardException(loc, UnknownError, ostream.str()); 00142 } 00143 } 00144 } 00145 00146 StandardException ioctl_exception(const char* loc) { 00147 00148 switch( errno ) { 00149 case ( EBADF ) : return StandardException(LOC,InvalidObjectError, "Socket control error. The file descriptor was not valid."); 00150 case ( EFAULT ) : return StandardException(LOC,OutOfRangeError, "Socket control error. Tried to reference inaccessible memory."); 00151 case ( EINVAL ) : return StandardException(LOC,InvalidArgError, "Socket control error. Ioctl input arguments were not valid."); 00152 case ( ENOTTY ) : return StandardException(LOC,InvalidObjectError, "Socket control error. The file descriptor is not valid or this operation may not be performed on it."); 00153 default : { 00154 std::ostringstream ostream; 00155 ostream << "Unknown error [" << errno << "]"; 00156 return StandardException(loc, UnknownError, ostream.str()); 00157 } 00158 } 00159 } 00160 00161 StandardException gethostbyname_exception(const char* loc, const std::string& hostname) { 00162 switch( h_errno ) { 00163 case ( HOST_NOT_FOUND ) : { 00164 std::string header; 00165 header += "Unable to correctly determine the server hostname: "; 00166 header += hostname; 00167 return StandardException(LOC,OpenError,header); 00168 } 00169 case ( TRY_AGAIN ) : return StandardException(LOC, OpenError,"A temporary error occurred on an authoritative name server. Try again later."); 00170 case ( NO_ADDRESS ) : return StandardException(LOC,InvalidArgError,"Requested server hostname is valid, but does not have an IP address."); 00171 case ( NO_RECOVERY ) : return StandardException(LOC,UnknownError); 00172 default : { 00173 std::ostringstream ostream; 00174 ostream << "Unknown error [" << h_errno << "]"; 00175 return StandardException(loc, UnknownError, ostream.str()); 00176 } 00177 } 00178 } 00179 00180 StandardException connection_exception(const char* loc) { 00181 switch( errno ) { 00182 case ( ( EACCES ) || ( EPERM ) ): return StandardException(LOC,PermissionsError,"Write permission on the socket denied or firewalled."); 00183 case ( EADDRINUSE ) : return StandardException(LOC,BusyError,"Address already in use."); 00184 case ( EAFNOSUPPORT ): return StandardException(LOC,NotSupportedError,"Incorrect address family used (no support for AF maybe?"); 00185 case ( EAGAIN ) : return StandardException(LOC,OutOfResourcesError,"No free local ports remaining."); 00186 case ( EALREADY ) : return StandardException(LOC,BlockingError,"Socket is non-blocking and a previous connection attempt has not yet completed (wtf?)."); 00187 case ( EBADF ) : return StandardException(LOC,InvalidObjectError,"Not a valid socket descriptor."); 00188 case ( ECONNREFUSED ): return StandardException(LOC,ConnectionRefusedError,"Connection refused (no-one listening)."); 00189 case ( EFAULT ) : return StandardException(LOC,OutOfRangeError,"Socket specification is outside the user address space."); 00190 case ( EINPROGRESS ) : return StandardException(LOC,BlockingError,"Socket is non-blocking and the connection cannot be completed immediately (try select or poll for writing)."); 00191 case ( EINTR ) : return StandardException(LOC,InterruptedError,"Connection interrupted by a system signal."); 00192 case ( EISCONN ) : return StandardException(LOC,ConnectionError,"This socket is already connected."); 00193 case ( ENETUNREACH ) : 00194 case ( EHOSTUNREACH ): return StandardException(LOC,NotFoundError,"The host is unreachable."); 00195 case ( ENOTSOCK ) : return StandardException(LOC,InvalidObjectError,"This is not a socket file descriptor."); 00196 case ( ETIMEDOUT ) : return StandardException(LOC,TimeOutError,"Timed out."); 00197 default : { 00198 std::ostringstream ostream; 00199 ostream << "Unknown error [" << errno << "]"; 00200 return StandardException(loc, UnknownError, ostream.str()); 00201 } 00202 } 00203 00204 } 00205 00206 00207 } // namespace devices 00208 } // namespace ecl 00209 00210 #endif /* ECL_IS_POSIX */ 00211 #endif /* !ECL_IS_MAC */ 00212