00001
00009
00010
00011
00012
00013 #include <ecl/config/ecl.hpp>
00014 #ifndef ECL_IS_MAC
00015 #ifdef ECL_IS_POSIX
00016
00017
00018
00019
00020
00021 #include <sstream>
00022 #include <errno.h>
00023 #include <netdb.h>
00024 #include <ecl/exceptions/standard_exception.hpp>
00025 #include "../../../include/ecl/devices/detail/socket_exception_handler_pos.hpp"
00026
00027
00028
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 }
00208 }
00209
00210 #endif
00211 #endif
00212