CPN
Computational Process Networks
ServerSocketHandle.cc
Go to the documentation of this file.
1 //=============================================================================
2 // Computational Process Networks class library
3 // Copyright (C) 1997-2006 Gregory E. Allen and The University of Texas
4 //
5 // This library is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Library General Public License as published
7 // by the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Library General Public License for more details.
14 //
15 // The GNU Public License is available in the file LICENSE, or you
16 // can write to the Free Software Foundation, Inc., 59 Temple Place -
17 // Suite 330, Boston, MA 02111-1307, USA, or you can find it on the
18 // World Wide Web at http://www.fsf.org.
19 //=============================================================================
23 #include "common_priv.h"
26 #include <errno.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 
30 void ServerSocketHandle::Listen(const SocketAddress &addr, int queuelength) {
31  int error = 0;
32  if (!Listen(addr, queuelength, error)) { throw ErrnoException(error); }
33 }
34 
35 void ServerSocketHandle::Listen(const SockAddrList &addrs, int queuelength) {
36  int error = 0;
37  bool success = false;
38  for (SockAddrList::const_iterator itr = addrs.begin();
39  itr != addrs.end(); ++itr) {
40  success = Listen(*itr, queuelength, error);
41  if (success) break;
42  }
43  if (!success) throw ErrnoException(error);
44 }
45 
47  return Accept(&addr);
48 }
49 
51  return Accept(0);
52 }
54  bool loop = true;
55  int nfd = -1;
56  while (loop) {
57  if (addr) {
58  addr->GetLen() = sizeof(sockaddr_storage);
59  nfd = accept(FD(), addr->GetAddr(), &addr->GetLen());
60  } else {
61  nfd = accept(FD(), 0, 0);
62  }
63  if (nfd < 0) {
64  int error = errno;
65  switch (error) {
66  case EAGAIN:
67  //case EWOULDBLOCK: // Duplicate
68  Readable(false);
69  case ECONNABORTED:
70  case EINTR:
71  case ENETDOWN:
72  case EPROTO:
73  case ENOPROTOOPT:
74  case EHOSTDOWN:
75  //case ENONET:
76  case EHOSTUNREACH:
77  case ENETUNREACH:
78  case ENOBUFS:
79  case ENOMEM:
80  case EPERM:
81  case EPIPE:
82  case ETIMEDOUT:
83  nfd = -1;
84  loop = false;
85  break;
86  case EOPNOTSUPP:
87  case EBADF:
88  case EINVAL:
89  case ENFILE:
90  case EMFILE:
91  case ENOTSOCK:
92  case EFAULT:
93  default:
94  throw ErrnoException(error);
95  }
96  } else {
97  loop = false;
98  }
99  }
100  return nfd;
101 }
102 
103 bool ServerSocketHandle::Listen(const SocketAddress &addr, int queuelength, int &error) {
104  SocketAddress address = addr;
105  int nfd = socket(address.Family(), SOCK_STREAM, 0);
106  if (nfd < 0) {
107  error = errno;
108  return false;
109  }
110  if (reuse_addr) {
111  int opt = 1;
112  if (setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
113  throw ErrnoException();
114  }
115  }
116  if (bind(nfd, address.GetAddr(), address.GetLen()) < 0) {
117  error = errno;
118  return false;
119  }
120  if (listen(nfd, queuelength) < 0) {
121  error = errno;
122  return false;
123  }
124  FD(nfd);
125  return true;
126 }
void Listen(const SocketAddress &addr, int queuelength=256)
An abstraction of a socket address with convenience methods.
Definition: SocketAddress.h:42
socklen_t & GetLen()
sa_family_t & Family()
sockaddr * GetAddr()
int FD() const
Definition: FileHandle.h:106
std::vector< SocketAddress > SockAddrList
Definition: SocketAddress.h:35
bool Readable() const
Gives the current readability status of the file.
Definition: FileHandle.h:91