(file) Return to Socket.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 mike  1.2 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3 kumpf 1.4 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4 mike  1.2 // The Open Group, Tivoli Systems
  5           //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7 kumpf 1.4 // of this software and associated documentation files (the "Software"), to
  8           // deal in the Software without restriction, including without limitation the
  9           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10 mike  1.2 // sell copies of the Software, and to permit persons to whom the Software is
 11           // furnished to do so, subject to the following conditions:
 12           // 
 13 kumpf 1.4 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14 mike  1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16 kumpf 1.4 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19 mike  1.2 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21           //
 22           //==============================================================================
 23           //
 24           // Author: Mike Brasher (mbrasher@bmc.com)
 25           //
 26           // Modified By:
 27           //
 28           //%/////////////////////////////////////////////////////////////////////////////
 29           
 30           #include "Socket.h"
 31           
 32           #ifdef PEGASUS_OS_TYPE_WINDOWS
 33 tony  1.9 #include <windows.h>
 34           # ifndef _WINSOCKAPI_
 35           #   include <winsock2.h>
 36           # endif
 37 mike  1.2 #else
 38           # include <cctype>
 39 chuck 1.5 #ifndef PEGASUS_OS_OS400
 40           #   include <unistd.h>
 41           #else
 42 chuck 1.6 #   include <Pegasus/Common/OS400ConvertChar.h>
 43 chuck 1.5 #   include <unistd.cleinc>
 44           #endif
 45 marek 1.7 #   include <string.h>  // added by rk for memcpy
 46 mike  1.2 # include <cstdlib>
 47           # include <errno.h>
 48           # include <fcntl.h>
 49           # include <netdb.h>
 50           # include <netinet/in.h>
 51           # include <arpa/inet.h>
 52           # include <sys/socket.h>
 53 mday  1.9.4.1 # include <errno.h>
 54 mike  1.2     #endif
 55               
 56 mday  1.9.4.1 #include <Pegasus/Common/Sharable.h>
 57 mike  1.2     PEGASUS_NAMESPACE_BEGIN
 58               
 59               static Uint32 _socketInterfaceRefCount = 0;
 60               
 61               Sint32 Socket::read(Sint32 socket, void* ptr, Uint32 size)
 62               {
 63               #ifdef PEGASUS_OS_TYPE_WINDOWS
 64                   return ::recv(socket, (char*)ptr, size, 0);
 65               #elif defined(PEGASUS_OS_ZOS)
 66                   int i=::read(socket, (char*)ptr, size);
 67 marek 1.8     #ifdef PEGASUS_HAVE_EBCDIC
 68 mike  1.2         __atoe_l((char *)ptr,size);
 69 marek 1.8     #endif
 70 mike  1.2         return i;
 71 chuck 1.6     #elif defined(PEGASUS_OS_OS400)
 72                   int i=::read(socket, (char*)ptr, size);
 73                   AtoE((char *)ptr, size);
 74                   return i;
 75 mike  1.2     #else
 76 mday  1.9.4.2 
 77               #if defined (__GNUC__)
 78                   int ccode = TEMP_FAILURE_RETRY(::read(socket, (char*)ptr, size));
 79                   return ccode;
 80               #else 
 81 mike  1.2         return ::read(socket, (char*)ptr, size);
 82               #endif
 83 mday  1.9.4.2 #endif
 84 mike  1.2     }
 85               
 86               Sint32 Socket::write(Sint32 socket, const void* ptr, Uint32 size)
 87               {
 88               #ifdef PEGASUS_OS_TYPE_WINDOWS
 89                   return ::send(socket, (const char*)ptr, size, 0);
 90               #elif defined(PEGASUS_OS_ZOS)
 91                   char * ptr2 = (char *)malloc(size);
 92                   int i;
 93                   memcpy(ptr2,ptr,size);
 94 marek 1.8     #ifdef PEGASUS_HAVE_EBCDIC
 95 mike  1.2         __etoa_l(ptr2,size);
 96 marek 1.8     #endif
 97 chuck 1.6         i = ::write(socket, ptr2, size);
 98                   free(ptr2);
 99                   return i;
100               #elif defined(PEGASUS_OS_OS400)
101                   char * ptr2 = (char *)malloc(size);
102                   int i;
103                   memcpy(ptr2,ptr,size);
104                   EtoA(ptr2,size);
105 mike  1.2         i = ::write(socket, ptr2, size);
106                   free(ptr2);
107                   return i;
108               #else
109 mday  1.9.4.2 #if (__GNUC__)
110                   int ccode = TEMP_FAILURE_RETRY(::write(socket, (char*)ptr, size));
111                   return ccode;
112               #else
113 mike  1.2         return ::write(socket, (char*)ptr, size);
114               #endif
115 mday  1.9.4.2 #endif
116 mike  1.2     }
117               
118               void Socket::close(Sint32 socket)
119               {
120               #ifdef PEGASUS_OS_TYPE_WINDOWS
121                   closesocket(socket);
122               #else
123 mday  1.9.4.2 #if (__GNUC__)
124                   TEMP_FAILURE_RETRY(::close(socket));
125               #else
126 mike  1.2         ::close(socket);
127               #endif
128 mday  1.9.4.2 #endif
129 mike  1.2     }
130               
131 mday  1.9.4.4 int Socket::close2(Sint32 socket)
132               {
133               #ifdef PEGASUS_OS_TYPE_WINDOWS
134                   return closesocket(socket);
135               #else
136               #if (__GNUC__)
137                   int ccode = TEMP_FAILURE_RETRY(::close(socket));
138                   return ccode;
139               #else
140                   return ::close(socket);
141               #endif
142               #endif
143               }
144               
145               
146 mike  1.2     void Socket::enableBlocking(Sint32 socket)
147               {
148               #ifdef PEGASUS_OS_TYPE_WINDOWS
149                   unsigned long flag = 0;
150                   ioctlsocket(socket, FIONBIO, &flag);
151               #else
152                   int flags = fcntl(socket, F_GETFL, 0);
153                   flags &= ~O_NONBLOCK;
154                   fcntl(socket, F_SETFL, flags);
155               #endif
156               }
157               
158 mday  1.9.4.4 int Socket::enableBlocking2(Sint32 socket)
159               {
160               #ifdef PEGASUS_OS_TYPE_WINDOWS
161                   unsigned long flag = 0;
162                   return ioctlsocket(socket, FIONBIO, &flag);
163               #else
164                   int flags = fcntl(socket, F_GETFL, 0);
165                   flags &= ~O_NONBLOCK;
166                   return fcntl(socket, F_SETFL, flags);
167               #endif
168               }
169               
170 mike  1.2     void Socket::disableBlocking(Sint32 socket)
171               {
172               #ifdef PEGASUS_OS_TYPE_WINDOWS
173                   unsigned long flag = 1;
174                   ioctlsocket(socket, FIONBIO, &flag);
175               #else
176                   int flags = fcntl(socket, F_GETFL, 0);
177                   flags |= O_NONBLOCK;
178                   fcntl(socket, F_SETFL, flags);
179               #endif
180               }
181               
182 mday  1.9.4.4 int Socket::disableBlocking2(Sint32 socket)
183               {
184               #ifdef PEGASUS_OS_TYPE_WINDOWS
185                   unsigned long flag = 1;
186                   return ioctlsocket(socket, FIONBIO, &flag);
187               #else
188                   int flags = fcntl(socket, F_GETFL, 0);
189                   flags |= O_NONBLOCK;
190                   return fcntl(socket, F_SETFL, flags);
191               #endif
192               }
193               
194 mike  1.2     void Socket::initializeInterface()
195               {
196               #ifdef PEGASUS_OS_TYPE_WINDOWS
197                   if (_socketInterfaceRefCount == 0)
198                   {
199               	WSADATA tmp;
200               
201               	if (WSAStartup(0x202, &tmp) == SOCKET_ERROR)
202               	    WSACleanup();
203                   }
204               
205                   _socketInterfaceRefCount++;
206               #endif
207               }
208               
209               void Socket::uninitializeInterface()
210               {
211               #ifdef PEGASUS_OS_TYPE_WINDOWS
212                   _socketInterfaceRefCount--;
213               
214                   if (_socketInterfaceRefCount == 0)
215 mike  1.2     	WSACleanup();
216               #endif
217               }
218 mday  1.9.4.1 
219               
220               class abstract_socket : public Sharable
221               {
222                  public:
223                     abstract_socket(void) { }
224                     virtual ~abstract_socket(void){ }
225                     
226                     virtual operator Sint32() const = 0;
227                     virtual int socket(int sock_type, int sock_style, int sock_protocol, void *ssl_context = 0) = 0;
228                     
229                     virtual Sint32 read(void* ptr, Uint32 size) = 0;
230                     virtual Sint32 write(const void* ptr, Uint32 size) = 0;
231                     virtual int close(void) = 0;
232 mday  1.9.4.4       virtual int enableBlocking(void) = 0;
233                     virtual int disableBlocking(void) = 0;
234 mday  1.9.4.1 
235                     virtual int getsockname (struct sockaddr *addr, size_t *length_ptr) = 0;
236                     virtual int bind (struct sockaddr *addr, size_t length) = 0;
237                    
238                     // change size_t to size_t for ZOS and windows
239                     virtual abstract_socket* accept(struct sockaddr *addr, size_t *length_ptr) = 0;
240 mday  1.9.4.4       virtual int connect (struct sockaddr *addr, size_t length) = 0;
241 mday  1.9.4.1       virtual int shutdown(int how) = 0;
242                     virtual int listen(int q) = 0;
243                     virtual int getpeername (struct sockaddr *addr, size_t *length_ptr) = 0;
244                     virtual int send (void *buffer, size_t size, int flags) = 0;
245                     virtual int recv (void *buffer, size_t size, int flags) = 0;
246                     virtual int sendto(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t length) = 0;
247                     virtual int recvfrom(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t *length_ptr) = 0;
248                     virtual int setsockopt (int level, int optname, void *optval, size_t optlen) = 0;
249                     virtual int getsockopt (int level, int optname, void *optval, size_t *optlen_ptr) = 0;
250               
251                     virtual Boolean incompleteReadOccurred(Sint32 retCode) = 0;
252                     virtual Boolean is_secure(void) = 0;
253                     virtual void set_close_on_exec(void) = 0;
254                     virtual const char* get_err_string(void) = 0;
255                     
256                  private:
257               
258                     abstract_socket(const abstract_socket& );
259                     abstract_socket& operator=(const abstract_socket& );
260               };
261               
262 mday  1.9.4.1 
263               /** 
264 mday  1.9.4.3  * internet socket class
265                * designed to be overriden by ssl_socket_rep and file_socket_rep
266                * 
267 mday  1.9.4.1  */
268               class bsd_socket_rep : public abstract_socket
269               {
270                  public:
271               
272                     /** 
273                      * map to pegasus_socket::sock_err 
274                      */
275               
276                     bsd_socket_rep(void);
277                     virtual ~bsd_socket_rep(void);
278 mday  1.9.4.4       // used to allow the accept method to work
279                     bsd_socket_rep(int sock);
280               
281 mday  1.9.4.1       operator Sint32() const;
282                     int socket(int sock_type, int sock_style, int sock_protocol, void *ssl_context = 0);
283                     
284                     virtual Sint32 read(void* ptr, Uint32 size);
285                     virtual Sint32 write(const void* ptr, Uint32 size);
286                     virtual int close(void);
287 mday  1.9.4.4       int enableBlocking(void);
288                     int disableBlocking(void);
289 mday  1.9.4.1 
290 mday  1.9.4.4       virtual int getsockname (struct sockaddr *addr, size_t *length_ptr);
291                     virtual int bind (struct sockaddr *addr, size_t length);
292 mday  1.9.4.1      
293                     // change size_t to size_t for ZOS and windows
294                     virtual abstract_socket* accept(struct sockaddr *addr, size_t *length_ptr);
295 mday  1.9.4.4       virtual int connect (struct sockaddr *addr, size_t length);
296                     virtual int shutdown(int how);
297                     virtual int listen(int queue_len );
298 mday  1.9.4.1       int getpeername (struct sockaddr *addr, size_t *length_ptr);
299                     virtual int send (void *buffer, size_t size, int flags);
300                     virtual int recv (void *buffer, size_t size, int flags);
301 mday  1.9.4.4       virtual int sendto(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t length);
302                     virtual int recvfrom(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t *length_ptr);
303 mday  1.9.4.1       int setsockopt (int level, int optname, void *optval, size_t optlen);
304                     int getsockopt (int level, int optname, void *optval, size_t *optlen_ptr);
305               
306 mday  1.9.4.4       virtual Boolean incompleteReadOccurred(Sint32 retCode);
307 mday  1.9.4.1       virtual Boolean is_secure(void);
308                     void set_close_on_exec(void);
309 mday  1.9.4.4       virtual const char* get_err_string(void);
310               
311 mday  1.9.4.1    private:
312               
313 mday  1.9.4.4 
314                     bsd_socket_rep& operator=(const bsd_socket_rep& );
315 mday  1.9.4.1       // use to perform one-time initializion and destruction
316                     struct _library_init
317                     {
318               	    _library_init(void)
319               	    {
320               	    }
321               	    ~_library_init(void)
322               	    {
323               	    }
324                     };
325               
326                     static struct _library_init _lib_init;
327                     
328                     int _socket;
329                     void *_ssl_context;
330                     int _errno;
331 mday  1.9.4.4       char _strerr[256];
332 mday  1.9.4.1 };
333               
334               #if defined(__GNUC__) && GCC_VERSION >= 30200
335               // TEMP_FAILURE_RETRY (expression)
336               #else
337               
338               #endif
339               
340               
341               /** 
342                * default constructor for an (uninitialized) bsd socket 
343                */
344               bsd_socket_rep::bsd_socket_rep(void)
345                  :_errno(0)
346               {
347               }
348               
349 mday  1.9.4.4 bsd_socket_rep::bsd_socket_rep(int sock)
350                  : _socket(sock)
351               {
352               }
353               
354 mday  1.9.4.1 
355               /** 
356                * default destructor for bsd_socket_rep
357                *
358                */
359               bsd_socket_rep::~bsd_socket_rep(void)
360               {
361                  
362               }
363               
364               int bsd_socket_rep::shutdown(int how)
365               {
366 mday  1.9.4.4    int ccode = ::shutdown(_socket, how);
367                  if(ccode == -1)
368                     _errno = errno;
369                  return ccode;
370 mday  1.9.4.1 }
371               
372               bsd_socket_rep::operator Sint32() const
373               {
374                  return (Sint32)_socket;
375               }
376               
377               int bsd_socket_rep::socket(int sock_type, int sock_style, int sock_protocol, void *ssl_context)
378               {
379                  _socket = ::socket(sock_type, sock_style, sock_protocol);
380                  if(-1 == _socket )
381                  {
382                     _errno = errno;
383                  }
384                  return _socket;
385               }
386               
387               
388 mday  1.9.4.2 Sint32 bsd_socket_rep::read(void* ptr, Uint32 size)
389 mday  1.9.4.1 {
390 mday  1.9.4.4    int ccode = Socket::read(_socket, ptr, size);
391                  if(ccode == -1)
392                     _errno = errno;
393                  return ccode;
394 mday  1.9.4.3 }
395               
396               
397               Sint32 bsd_socket_rep::write(const void* ptr, Uint32 size)
398               {
399 mday  1.9.4.4    int ccode = Socket::write(_socket, ptr, size);
400                  if(ccode == -1)
401                     errno = _errno;
402                  return ccode;
403 mday  1.9.4.3 }
404               
405               
406               int bsd_socket_rep::close(void)
407               {
408 mday  1.9.4.4    int ccode;
409 mday  1.9.4.3    
410 mday  1.9.4.4    shutdown(2);
411                  ccode = Socket::close2(_socket);
412                  if(ccode == -1)
413                     _errno = errno;
414                  return ccode;
415               }
416               
417               
418               
419               int  bsd_socket_rep::enableBlocking(void)
420               {
421                  return Socket::enableBlocking2(_socket);
422               }
423               
424               int bsd_socket_rep::disableBlocking(void)
425               {
426                  return Socket::disableBlocking2(_socket);
427               }
428               
429               int bsd_socket_rep::getsockname (struct sockaddr *addr, size_t *length_ptr)
430               {
431 mday  1.9.4.4    int ccode = ::getsockname(_socket, addr, length_ptr);
432                  if(ccode == -1)
433                     _errno = errno;
434                  return ccode;
435               }
436               
437               /** 
438                * default implementation allows reuseof address
439                * sockaddr structure needs to be fully initialized or call will fail
440                */
441               int bsd_socket_rep::bind (struct sockaddr *addr, size_t length)
442               {
443                  int opt = 1;
444                  int ccode = setsockopt(SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
445                  if(ccode < 0)
446                  {
447                     _errno = errno;
448                     return ccode;
449                  }
450                  return ::bind(_socket, addr, length);
451               }
452 mday  1.9.4.4 
453               abstract_socket* bsd_socket_rep::accept(struct sockaddr *addr, size_t *length_ptr)
454               {
455                  int new_sock = ::accept(_socket, addr, length_ptr);
456                  if(new_sock == -1)
457                  {
458                     _errno = errno;
459                     return 0;
460                  }
461               
462                  bsd_socket_rep *rep = new bsd_socket_rep(new_sock);
463                  // set the close-on-exec flag 
464                  rep->set_close_on_exec();
465                  return rep;
466               }
467               
468               int bsd_socket_rep::connect (struct sockaddr *addr, size_t length)
469               {
470                  int ccode = ::connect(_socket, addr, length);
471                  if(ccode == -1)
472                     _errno = errno;
473 mday  1.9.4.4    return ccode;
474               }
475               
476               
477               int bsd_socket_rep::listen(int queue_len)
478               {
479                  int ccode = ::listen(_socket, queue_len);
480                  if(ccode == -1)
481                     _errno = errno;
482                  return ccode;
483               }
484               
485               
486               int bsd_socket_rep::getpeername (struct sockaddr *addr, size_t *length_ptr)
487               {
488                  int ccode = ::getpeername(_socket, addr, length_ptr);
489                  if(ccode == -1 )
490                     _errno = errno;
491                  return ccode;
492               }
493               
494 mday  1.9.4.4 int bsd_socket_rep::send (void *buffer, size_t size, int flags)
495               {
496                  int ccode = ::send(_socket, buffer, size, flags);
497                  if(ccode == -1)
498                     _errno = errno;
499                  return ccode;
500               }
501               
502               
503               int bsd_socket_rep::recv (void *buffer, size_t size, int flags)
504               {
505                  int ccode = ::recv(_socket, buffer, size, flags);
506                  if(ccode == -1)
507                     _errno = errno;
508                  return ccode;
509               }
510               
511               int bsd_socket_rep::sendto(void *buffer, size_t size, int flags, struct sockaddr *addr, size_t length)
512               {
513                  int ccode = ::sendto(_socket, buffer, size, flags, addr, length);
514                     if(ccode == -1)
515 mday  1.9.4.4       _errno = errno;
516                  return ccode;
517               }
518               
519               
520               int bsd_socket_rep::recvfrom(void *buffer, 
521               			     size_t size, 
522               			     int flags, 
523               			     struct sockaddr *addr, 
524               			     size_t *length_ptr)
525               {
526                  int ccode = ::recvfrom(_socket, buffer, size, flags, addr, length_ptr);
527                  if(ccode == -1)
528                     _errno = errno;
529                  return ccode;
530               }
531               
532               int bsd_socket_rep::setsockopt (int level, int optname, void *optval, size_t optlen)
533               {
534                  int ccode = ::setsockopt(_socket, level, optname, optval, optlen);
535                  if(ccode == -1)
536 mday  1.9.4.4       _errno = errno;
537                  return ccode;
538               }
539               
540               
541               int bsd_socket_rep::getsockopt (int level, int optname, void *optval, size_t *optlen_ptr)
542               {
543                  int ccode = ::getsockopt(_socket, level, optname, optval, optlen_ptr);
544                  if(ccode == -1)
545                     _errno = errno;
546                  return ccode;
547               }
548               
549               
550               Boolean bsd_socket_rep::incompleteReadOccurred(Sint32 retCode)
551               {
552                  return false;
553               }
554               
555               Boolean bsd_socket_rep::is_secure(void)
556               {
557 mday  1.9.4.4    return false;
558               }
559               
560               void bsd_socket_rep::set_close_on_exec(void)
561               {
562                  int sock_flags;
563                  if( (sock_flags = fcntl(_socket, F_GETFD, 0)) >= 0)
564                  {
565                     sock_flags |= FD_CLOEXEC;
566                     fcntl(_socket, F_SETFD, sock_flags);
567                  }
568               }
569               
570               
571               const char* bsd_socket_rep::get_err_string(void)
572               {
573                  strncpy(_strerr, strerror(_errno), 255);
574                  return _strerr;
575 mday  1.9.4.1 }
576               
577               
578 mike  1.2     
579               PEGASUS_NAMESPACE_END
580 mday  1.9.4.4 

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2