00001
00002 #ifndef __SOCKETS_POSIX_PAL_HPP__
00003 #define __SOCKETS_POSIX_PAL_HPP__
00004
00005 #include <sys/types.h>
00006 #include <sys/socket.h>
00007 #include <netinet/in.h>
00008 #include <arpa/inet.h>
00009 #include <string.h>
00010 #include <unistd.h>
00011 #include <netdb.h>
00012 #include <fcntl.h>
00013 #include <assert.h>
00014
00015 namespace lfc
00016 {
00017 namespace posixPAL
00018 {
00019
00021 namespace sockets
00022 {
00023
00024 const int MAX_ERROR_CODE = 6;
00025
00026 enum ErrorCodes
00027 {
00028 errOk,
00029 errGeneric,
00030 errInitError,
00031 errConnectionClosed,
00032 errUnbound,
00033 errNotListening,
00034 errBadAddress
00035 };
00036
00037 extern const char *messagesTable[MAX_ERROR_CODE + 1];
00038
00039
00041 const int
00042 pfINET = AF_INET,
00043 pfUNIX = AF_UNIX,
00044 pfIPX = AF_IPX;
00045
00047 const int
00048 stSTREAM = SOCK_STREAM,
00049 stDGRAM = SOCK_DGRAM;
00050
00052 const int
00053 flagPEEK = MSG_PEEK,
00054 flagOOB = MSG_OOB;
00055
00057 typedef int Handle;
00058
00060 const Handle NULL_HANDLE = -1;
00061
00062
00064
00068 inline int init()
00069 {
00070 return errOk;
00071
00072 }
00073
00075
00079 inline int cleanup()
00080 {
00081 return errOk;
00082 }
00083
00085
00092 inline int open(Handle &handle, int pf, int type)
00093 {
00094 Handle temp;
00095 if( ( temp = ::socket(pf, type, 0)) == NULL_HANDLE )
00096 return errGeneric;
00097
00098 handle = temp;
00099 return errOk;
00100 }
00101
00103
00107 inline int close(Handle handle)
00108 {
00109 if( ::shutdown(handle, SHUT_RDWR) == NULL_HANDLE )
00110 return errGeneric;
00111
00112 if( ::close(handle) == NULL_HANDLE )
00113 return errGeneric;
00114
00115 return errOk;
00116 }
00117
00119
00128 inline int connect(Handle handle, const char* to, int pf,
00129 u_short port)
00130 {
00131 sockaddr_in sin;
00132 hostent *hp = ::gethostbyname(to);
00133
00134 if( hp == NULL )
00135 if( ( sin.sin_addr.s_addr = inet_addr(to) ) == INADDR_NONE )
00136 return errBadAddress;
00137 else
00138 ::memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
00139
00140 sin.sin_family = pf;
00141 sin.sin_port = htons(port);
00142
00143 if( ::connect(handle, (sockaddr *)&sin, sizeof sin) == NULL_HANDLE )
00144 return errGeneric;
00145
00146 return errOk;
00147 }
00148
00150
00160 inline int send(Handle handle, const char* buffer, long len, int flags,
00161 long &bytesSent)
00162 {
00163 if( ( bytesSent = ::send(handle, buffer, len, flags)) == NULL_HANDLE )
00164 return errGeneric;
00165
00166 return errOk;
00167 }
00168
00169
00187 inline int sendTo(Handle handle, const char* buffer, long len, int flags,
00188 const char* to, int pf, u_short port,
00189 long &bytesSent)
00190 {
00191 sockaddr_in sin;
00192 hostent *hp = ::gethostbyname(to);
00193
00194 if( hp == NULL )
00195 if( ( sin.sin_addr.s_addr = inet_addr(to) ) == INADDR_NONE )
00196 return errBadAddress;
00197 else
00198 ::memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
00199
00200 sin.sin_family = pf;
00201 sin.sin_port = htons(port);
00202
00203 bytesSent = ::sendto(handle, buffer, len, flags, (sockaddr *)&sin,
00204 sizeof sin);
00205
00206 if( bytesSent == NULL_HANDLE )
00207 return errGeneric;
00208
00209 return errOk;
00210 }
00211
00212
00214
00222 inline int recv(Handle handle, char* buffer, long len, int flags,
00223 long &bytesReceived)
00224 {
00225 switch( bytesReceived = ::recv(handle, buffer, len, flags) )
00226 {
00227 case 0:
00228 return errConnectionClosed;
00229
00230 case NULL_HANDLE:
00231 return errGeneric;
00232
00233 default:
00234 return errOk;
00235 }
00236 }
00237
00239
00251 inline int recvFrom(Handle handle, char* buffer, long len, int flags,
00252 char* from, int pf, u_short port,
00253 long &bytesReceived)
00254 {
00255 sockaddr_in sin;
00256
00257 unsigned int sinSize = sizeof sin;
00258
00259 bytesReceived = ::recvfrom(handle, buffer, len, flags, (sockaddr *)&sin,
00260 &sinSize);
00261
00262 switch( bytesReceived )
00263 {
00264 case 0:
00265 return errConnectionClosed;
00266
00267 case NULL_HANDLE:
00268 return errGeneric;
00269
00270 default:
00271 ::strcpy(from, ::inet_ntoa(sin.sin_addr));
00272 return errOk;
00273 }
00274 }
00275
00277
00284 inline int bind(Handle handle, int pf, u_short port)
00285 {
00286 sockaddr_in sin;
00287
00288 sin.sin_addr.s_addr = INADDR_ANY;
00289 sin.sin_port = htons(port);
00290 sin.sin_family = pf;
00291
00292 if( ::bind(handle, (sockaddr *)&sin, sizeof sin) == NULL_HANDLE )
00293 return errGeneric;
00294
00295 return errOk;
00296 }
00297
00299
00305 inline int listen(Handle handle, int backlog = SOMAXCONN)
00306 {
00307 if( ::listen(handle, backlog) == NULL_HANDLE )
00308 return errGeneric;
00309
00310 return errOk;
00311 }
00312
00314
00320 inline int accept(Handle& newHandle, Handle handle)
00321 {
00322 Handle temp;
00323 if( ( temp = ::accept(handle, NULL, NULL) ) == NULL_HANDLE )
00324 return errGeneric;
00325
00326 newHandle = temp;
00327 return errOk;
00328 }
00329
00331
00336 inline int setBlocking(Handle handle, bool blocking)
00337 {
00338 if( ::fcntl( handle, F_SETFL, blocking ? 0 : O_NONBLOCK ) == NULL_HANDLE )
00339 return errGeneric;
00340
00341 return errOk;
00342 }
00343
00344
00350 inline int getServicePort(const char *service, u_short &port)
00351 {
00352 servent *psent = ::getservbyname(service, NULL);
00353 if(psent == NULL)
00354 return errGeneric;
00355 port = ntohs(psent->s_port);
00356 return errOk;
00357 }
00358
00359
00361
00366 inline int flush(Handle handle)
00367 {
00368 return errOk;
00369 }
00370
00371
00373 inline const char *message(int index)
00374 {
00375 assert(index >= 0 && index <= MAX_ERROR_CODE);
00376 return messagesTable[index];
00377 }
00378
00379
00380 }
00381 }
00382
00383 namespace pal = posixPAL;
00384
00385 }
00386
00387 #endif // __SOCKETS_POSIX_PAL_HPP__
00388