©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

ux/uxsocket.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00003     May be copied only for purposes and under conditions described
00004     on the Web page www.basepath.com/aup/copyright.htm.
00005 
00006     The Example Files are provided "as is," without any warranty;
00007     without even the implied warranty of merchantability or fitness
00008     for a particular purpose. The author and his publisher are not
00009     responsible for any damages, direct or incidental, resulting
00010     from the use or non-use of these Example Files.
00011 
00012     The Example Files may contain defects, and some contain deliberate
00013     coding mistakes that were included for educational reasons.
00014     You are responsible for determining if and how the Example Files
00015     are to be used.
00016 
00017 */
00018 #include "ux.hpp"
00019 
00020 #include <arpa/inet.h>
00021 
00022 using namespace Ux;
00023 
00024 /**
00025     Calls inet_pton. Throws errors from inet_pton, or EINVAL if inet_pton returns 0.
00026 */
00027 void SockIPv4::set(const char *str)
00028 {
00029     switch (::inet_pton(AF_INET, str, &ipv4)) {
00030     case 0:
00031         throw Error(EINVAL);
00032     case -1:
00033         throw Error(errno);
00034     }
00035 }
00036 
00037 /**
00038     Calls inet_ntop.
00039 */
00040 const char *SockIPv4::get_string(char *buf, socklen_t bufsize) const
00041 {
00042     if (::inet_ntop(AF_INET, &ipv4, buf, bufsize) == NULL)
00043         throw Error(errno);
00044     return buf;
00045 }
00046 
00047 /**
00048     Sets object to zeros.
00049 */
00050 void SockIPv6::set(uint8_t *ip = NULL)
00051 {
00052     if (ip == NULL)
00053         memset(ipv6, 0, sizeof(ipv6));
00054     else
00055         memcpy(ipv6, ip, sizeof(ipv6));
00056 }
00057 
00058 /**
00059     Calls inet_pton. Throws errors from inet_pton, or EINVAL if inet_pton returns 0.
00060 */
00061 void SockIPv6::set(const char *str)
00062 {
00063     switch (::inet_pton(AF_INET6, str, ipv6)) {
00064     case 0:
00065         throw Error(EINVAL);
00066     case -1:
00067         throw Error(errno);
00068     }
00069 }
00070 
00071 /**
00072     Calls inet_ntop.
00073 */
00074 const char *SockIPv6::get_string(char *buf, socklen_t bufsize) const
00075 {
00076     if (::inet_ntop(AF_INET6, ipv6, buf, bufsize) == NULL)
00077         throw Error(errno);
00078     return buf;
00079 }
00080 
00081 /**
00082     Sets up socet address directly from a path. Can throw ENAMETOOLONG.
00083 */
00084 void SockAddrUn::set(const char *path)
00085 {
00086     struct sockaddr_un *p = (struct sockaddr_un *)&sa_storage;
00087 
00088     p->sun_family = AF_UNIX;
00089     if (strlen(path) >= sizeof(p->sun_path))
00090         throw Error(ENAMETOOLONG);
00091     strcpy(p->sun_path, path);
00092     set_len(sizeof(struct sockaddr_un));
00093 }
00094 
00095 /**
00096     Sets up socet address directly from a struct in_addr.
00097 */
00098 void SockAddrIn::set(in_port_t port, struct in_addr& sa)
00099 {
00100     struct sockaddr_in *p = (struct sockaddr_in *)&sa_storage;
00101 
00102     p->sin_family = AF_INET;
00103     p->sin_port = port;
00104     p->sin_addr = sa;
00105     set_len(sizeof(struct sockaddr_in));
00106 }
00107 
00108 /**
00109     Sets up socet address directly from an IPv4 as a 32-bit number.
00110 */
00111 void SockAddrIn::set(in_port_t port, in_addr_t ipv4)
00112 {
00113     struct in_addr sa;
00114 
00115     sa.s_addr = ipv4;
00116     set(port, sa);
00117 }
00118 
00119 /**
00120     Sets up socet address directly from dotted string.
00121 */
00122 void SockAddrIn::set(in_port_t port, const char *dotted)
00123 {
00124     set(port, SockIPv4(dotted).get_ipv4());
00125 }
00126 
00127 /**
00128     Calls getaddrinfo.
00129 */
00130 /* static */ void SockAddr::getaddrinfo(const char *nodename, const char *servname,
00131   const struct addrinfo *hint, struct addrinfo **infop)
00132 {
00133     int r;
00134 
00135     if ((r = ::getaddrinfo(nodename, servname, hint, infop)) != 0)
00136         throw Error(r, EC_EAI);
00137 }
00138 
00139 /**
00140     Calls getaddrinfo, but doesn't require setting up a separate hint structure.
00141 */
00142 /* static */ void SockAddr::getaddrinfo(const char *nodename, const char *servname, int family, int type,
00143   int flags, struct addrinfo **infop)
00144 {
00145     struct addrinfo hint;
00146 
00147     memset(&hint, 0, sizeof(hint));
00148     hint.ai_family = family;
00149     hint.ai_socktype = type;
00150     hint.ai_flags = flags;
00151     getaddrinfo(nodename, servname, &hint, infop);
00152 }
00153 
00154 /**
00155     Calls getaddrinfo and then sets up the socket address from a nodename and servname (port).
00156 */
00157 void SockAddr::set_server(const char *nodename, const char *servname)
00158 {
00159     struct addrinfo *infop;
00160 
00161     getaddrinfo(nodename, servname, AF_INET, SOCK_STREAM, AI_PASSIVE, &infop);
00162     memcpy(&sa_storage, infop->ai_addr, infop->ai_addrlen);
00163     set_len(infop->ai_addrlen);
00164     set_protocol(infop->ai_protocol);
00165 }
00166 
00167 /**
00168     Calls getnameinfo.
00169 */
00170 /* static */ void SockAddr::getnameinfo(const struct sockaddr *sa, socklen_t sa_len, char *nodename,
00171       socklen_t nodelen, char *servname, socklen_t servlen, unsigned flags)
00172 {
00173     int r;
00174 
00175     if ((r = ::getnameinfo(sa, sa_len, nodename, nodelen, servname, servlen, flags)) != 0)
00176         throw Error(r, EC_EAI);
00177 }
00178 
00179 /**
00180     Calls socket.
00181 */
00182 void Socket::socket(int domain, int type, int protocol)
00183 {
00184     if ((fd = ::socket(domain, type, protocol)) == -1)
00185         throw Error(errno);
00186 }
00187 
00188 /**
00189     Calls bind.
00190 */
00191 void Socket::bind(const SockAddr& sa)
00192 {
00193     if (::bind(fd, sa.get_addr(), sa.get_len()) == -1)
00194         throw Error(errno);
00195 }
00196 
00197 /**
00198     Calls listen.
00199 */
00200 void Socket::listen(int backlog)
00201 {
00202     if (::listen(fd, backlog) == -1)
00203         throw Error(errno);
00204 }
00205 
00206 /**
00207     Calls accept.
00208 */
00209 Socket Socket::accept(SockAddr *sa)
00210 {
00211     int r;
00212 
00213     if (sa == NULL)
00214         r = ::accept(fd, NULL, NULL);
00215     else
00216         r = ::accept(fd, sa->get_addr(), sa->get_len_ptr());
00217     if (r == -1)
00218         throw Error(errno);
00219     return Socket(r);
00220 }
00221 
00222 /**
00223     Calls connect.
00224 */
00225 void Socket::connect(const SockAddr& sa)
00226 {
00227     if (::connect(fd, sa.get_addr(), sa.get_len()) == -1)
00228         throw Error(errno);
00229 }
00230 
00231 /**
00232     Calls setsockopt.
00233 */
00234 void Socket::setsockopt(int level, int option, const void *value, socklen_t value_len)
00235 {
00236     if (::setsockopt(fd, level, option, value, value_len) == -1)
00237         throw Error(errno);
00238 }
00239 
00240 /**
00241     Calls getsockopt.
00242 */
00243 void Socket::getsockopt(int level, int option, void *value, socklen_t& value_len)
00244 {
00245     if (::getsockopt(fd, level, option, value, &value_len) == -1)
00246         throw Error(errno);
00247 }
00248 
00249 /**
00250     Calls sendto.
00251 */
00252 ssize_t Socket::sendto(const void *message, size_t length, int flags, const struct sockaddr *sa,
00253       socklen_t sa_len)
00254 {
00255     ssize_t n;
00256 
00257     if ((n = ::sendto(fd, message, length, flags, sa, sa_len)) == -1)
00258         throw Error(errno);
00259     return n;
00260 }
00261 
00262 /**
00263     Calls recvfrom.
00264 */
00265 ssize_t Socket::recvfrom(void *buffer, size_t length, int flags, struct sockaddr *sa,
00266       socklen_t *sa_len)
00267 {
00268     ssize_t n;
00269 
00270     if ((n = ::recvfrom(fd, buffer, length, flags, sa, sa_len)) == -1)
00271         throw Error(errno);
00272     return n;
00273 }
00274 
00275 /**
00276     Calls sendmsg.
00277 */
00278 ssize_t Socket::sendmsg(const struct msghdr *message, int flags)
00279 {
00280     ssize_t n;
00281 
00282     if ((n = ::sendmsg(fd, message, flags)) == -1)
00283         throw Error(errno);
00284     return n;
00285 }
00286 
00287 /**
00288     Calls recvmsg.
00289 */
00290 ssize_t Socket::recvmsg(struct msghdr *message, int flags)
00291 {
00292     ssize_t n;
00293 
00294     if ((n = ::recvmsg(fd, message, flags)) == -1)
00295         throw Error(errno);
00296     return n;
00297 }
00298 
00299 /**
00300     Calls send.
00301 */
00302 ssize_t Socket::send(const void *data, size_t length, int flags)
00303 {
00304     ssize_t n;
00305 
00306     if ((n = ::send(fd, data, length, flags)) == -1)
00307         throw Error(errno);
00308     return n;
00309 }
00310 
00311 /**
00312     Calls recv.
00313 */
00314 ssize_t Socket::recv(void *buffer, size_t length, int flags)
00315 {
00316     ssize_t n;
00317 
00318     if ((n = ::recv(fd, buffer, length, flags)) == -1)
00319         throw Error(errno);
00320     return n;
00321 }
00322 /**
00323     Calls getpeername.
00324 */
00325 void Socket::getpeername(SockAddr& sa)
00326 {
00327     if (::getpeername(fd, sa.get_addr(), sa.get_len_ptr()) == -1)
00328         throw Error(errno);
00329 }
00330 
00331 /**
00332     Calls getsockname.
00333 */
00334 void Socket::getsockname(SockAddr& sa)
00335 {
00336     if (::getsockname(fd, sa.get_addr(), sa.get_len_ptr()) == -1)
00337         throw Error(errno);
00338 }
00339 
00340 /**
00341     Calls socketpair. Arguments rearranged so array comes first, which allows default arguments.
00342 */
00343 /* static */ void Socket::socketpair(Socket sv[2], int domain, int type, int protocol)
00344 {
00345     int fds[2];
00346 
00347     if (::socketpair(domain, type, protocol, fds) == -1)
00348         throw Error(errno);
00349     sv[0].set(fds[0]);
00350     sv[1].set(fds[1]);
00351 }
00352 
00353 /**
00354     Calls shutdown.
00355 */
00356 void Socket::shutdown(int how)
00357 {
00358     if (::shutdown(fd, how) == -1)
00359         throw Error(errno);
00360 }
00361 
00362 /**
00363     Calls sockatmark; return converted to bool.
00364 */
00365 bool Socket::sockatmark(void)
00366 {
00367 #if _XOPEN_VERSION >= 600
00368     int r;
00369 
00370     if ((r = ::sockatmark(fd)) == -1)
00371         throw Error(errno);
00372     return r == 1;
00373 #else
00374     throw Error(ENOSYS);
00375 #endif
00376 }

Generated on Fri Apr 23 10:57:06 2004 for AUP2 Example Source by doxygen 1.3.1