00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #include "libts.h"
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 #ifdef CHECK_PLAUSIBILITY_OF_SOCKADDR
00040 #define CHECK_PLAUSIBLE_SOCKADDR(_n,_f,_l) check_plausible_sockaddr(_n,_f,_n)
00041 inline void
00042 check_valid_sockaddr(sockaddr * sa, char *file, int line)
00043 {
00044   sockaddr_in *si = (sockaddr_in *) sa;
00045   unsigned short port = ntohs(si->sin_port);
00046   unsigned short addr = ntohl(si->sin_addr.s_addr);
00047 
00048   if (port > 20000) {
00049     cerr << "[byteordering] In " << file << ", line " << line << " the IP port ";
00050     cerr << "was found to be " << port << "(in host byte order).\n";
00051     cerr << "[byteordering] This seems inplausible, so check for byte order problems\n";
00052   }
00053 }
00054 #else
00055 #define CHECK_PLAUSIBLE_SOCKADDR(_n,_f,_l)
00056 #endif
00057 
00058 int
00059 safe_setsockopt(int s, int level, int optname, char *optval, int optlevel)
00060 {
00061   int r;
00062   do {
00063     r = setsockopt(s, level, optname, optval, optlevel);
00064   } while (r < 0 && (errno == EAGAIN || errno == EINTR));
00065   return r;
00066 }
00067 
00068 int
00069 safe_getsockopt(int s, int level, int optname, char *optval, int *optlevel)
00070 {
00071   int r;
00072   do {
00073     r = getsockopt(s, level, optname, optval, (socklen_t *) optlevel);
00074   } while (r < 0 && (errno == EAGAIN || errno == EINTR));
00075   return r;
00076 }
00077 
00078 int
00079 safe_fcntl(int fd, int cmd, int arg)
00080 {
00081   int r = 0;
00082   do {
00083     r = fcntl(fd, cmd, arg);
00084   } while (r < 0 && (errno == EAGAIN || errno == EINTR));
00085   return r;
00086 }
00087 
00088 int
00089 safe_set_fl(int fd, int arg)
00090 {
00091   int flags = safe_fcntl(fd, F_GETFL, 0);
00092   if (flags < 0)
00093     return flags;
00094   flags |= arg;
00095   flags = safe_fcntl(fd, F_SETFL, flags);
00096   return flags;
00097 }
00098 
00099 int
00100 safe_clr_fl(int fd, int arg)
00101 {
00102   int flags = safe_fcntl(fd, F_GETFL, 0);
00103   if (flags < 0)
00104     return flags;
00105   flags &= ~arg;
00106   flags = safe_fcntl(fd, F_SETFL, flags);
00107   return flags;
00108 }
00109 
00110 int
00111 safe_nonblocking(int fd)
00112 {
00113   return safe_set_fl(fd, O_NONBLOCK);
00114 }
00115 
00116 int
00117 safe_blocking(int fd)
00118 {
00119   return safe_clr_fl(fd, O_NONBLOCK);
00120 }
00121 
00122 int
00123 write_ready(int fd)
00124 {
00125   struct pollfd p;
00126   p.events = POLLOUT;
00127   p.fd = fd;
00128   int r = poll(&p, 1, 0);
00129   if (r <= 0)
00130     return r;
00131   if (p.revents & (POLLERR | POLLNVAL))
00132     return -1;
00133   if (p.revents & (POLLOUT | POLLHUP))
00134     return 1;
00135   return 0;
00136 }
00137 
00138 int
00139 read_ready(int fd)
00140 {
00141   struct pollfd p;
00142   p.events = POLLIN;
00143   p.fd = fd;
00144   int r = poll(&p, 1, 0);
00145   if (r <= 0)
00146     return r;
00147   if (p.revents & (POLLERR | POLLNVAL))
00148     return -1;
00149   if (p.revents & (POLLIN | POLLHUP))
00150     return 1;
00151   return 0;
00152 }
00153 
00154 int
00155 safe_ioctl(int fd, int request, char *arg)
00156 {
00157   int r = -1;
00158   do {
00159     r = ioctl(fd, request, arg);
00160   } while (r < 0 && (errno == EAGAIN || errno == EINTR));
00161   return r;
00162 }
00163 
00164 int
00165 safe_bind(int s, struct sockaddr const* name, int namelen)
00166 {
00167   int r;
00168   CHECK_PLAUSIBLE_SOCKADDR(name, __FILE__, __LINE__);
00169   do {
00170     r = bind(s, name, namelen);
00171   } while (r < 0 && (errno == EAGAIN || errno == EINTR));
00172   return r;
00173 }
00174 
00175 int
00176 safe_listen(int s, int backlog)
00177 {
00178   int r;
00179   do {
00180     r = listen(s, backlog);
00181   } while (r < 0 && (errno == EAGAIN || errno == EINTR));
00182   return r;
00183 }
00184 
00185 int
00186 safe_getsockname(int s, struct sockaddr *name, int *namelen)
00187 {
00188   int r;
00189   do {
00190     r = getsockname(s, name, (socklen_t *) namelen);
00191   } while (r < 0 && (errno == EAGAIN || errno == EINTR));
00192   return r;
00193 }
00194 
00195 char
00196 fd_read_char(int fd)
00197 {
00198   char c;
00199   int r;
00200   do {
00201     r = read(fd, &c, 1);
00202     if (r > 0)
00203       return c;
00204   } while (r < 0 && (errno == EAGAIN || errno == EINTR));
00205   perror("fd_read_char");
00206   ink_assert(!"fd_read_char");
00207   return c;
00208 }
00209 
00210 int
00211 fd_read_line(int fd, char *s, int len)
00212 {
00213   char c;
00214   int numread = 0, r;
00215   
00216   do {
00217     do
00218       r = read(fd, &c, 1);
00219     while (r < 0 && (errno == EAGAIN || errno == EINTR));
00220 
00221     if (r <= 0 && numread)
00222       break;
00223 
00224     if (r <= 0)
00225       return r;
00226 
00227     if (c == '\n')
00228       break;
00229 
00230     s[numread++] = c;
00231   } while (numread < len - 1);
00232 
00233   s[numread] = 0;
00234   return numread;
00235 }
00236 
00237 
00238 int
00239 close_socket(int s)
00240 {
00241   return close(s);
00242 }
00243 
00244 int
00245 write_socket(int s, const char *buffer, int length)
00246 {
00247   return write(s, (const void *) buffer, length);
00248 }
00249 
00250 int
00251 read_socket(int s, char *buffer, int length)
00252 {
00253   return read(s, (void *) buffer, length);
00254 }