Mercurial > hg > fxanalyse
diff xsocket.c @ 262:ebbe0f198322
Fix DDS client connection retry
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Tue, 16 Jun 2015 17:16:11 +0200 |
parents | a03df7dc98f8 |
children | 8d9a4c5eb7a4 |
line wrap: on
line diff
--- a/xsocket.c Tue Jun 16 15:09:23 2015 +0200 +++ b/xsocket.c Tue Jun 16 17:16:11 2015 +0200 @@ -20,6 +20,17 @@ #include "xsocket.h" +#define XRETRY(code) \ + ({ \ + int __r, __n = 0; \ + while (__n++ < 2) { \ + __r = (code); \ + if (__r != -EAGAIN) \ + break; \ + } \ + __r; \ + }) + struct xsocket * xsocket(const char *hostname, const int port) { @@ -72,86 +83,97 @@ int xsend(struct xsocket *s, const char *data, size_t len) { - int r, retry = 2; + int r; - while (--retry) { - - r = xconnect(s); - if (r < 0) - return r; + r = xconnect(s); + if (r < 0) + return r; - r = send(s->fd, data, len, 0); - if (r < 0) { - close(s->fd); - s->fd = -1; - continue; - } + r = send(s->fd, data, len, 0); + if (r < 0) + return -errno; - break; - } - - return (r < 0) ? -errno : 0; + return r; } int xrecv(struct xsocket *s, char *buffer, size_t len) { - return recv(s->fd, buffer, len, 0); + int r; + + r = recv(s->fd, buffer, len, 0); + if (r < 0) + return -errno; + if (r == 0) { + close(s->fd); + s->fd = -1; + return -EAGAIN; + } + + return r; } -int msend(struct xsocket *s, const char *data, size_t len) +static inline int __exchange(struct xsocket *s, const char *out, size_t outlen, char *in, size_t inlen) { - char *buffer = malloc(len + 2); - memcpy(buffer, data, len); - - buffer[len++] = '\r'; - buffer[len++] = '\n'; + int r; - return xsend(s, buffer, len); + r = xsend(s, out, outlen); + if (r < 0) + return r; + + r = xrecv(s, in, inlen); + if (r < 0) + return r; + + return r; } -int mrecv(struct xsocket *s, char *buffer, size_t len) +int xask(struct xsocket *s, const char *cmd, size_t len, char *buffer, size_t bufferlen) { - int n; + int r; + char *data; + + data = malloc(len + 2); + memcpy(data, cmd, len); + data[len++] = '\r'; + data[len++] = '\n'; - n = xrecv(s, buffer, len); - if (n < 0) - return n; + r = XRETRY(__exchange(s, data, len, buffer, bufferlen)); + if (r < 0) + return r; - if ((buffer[--n] != '\n') || (buffer[--n] != '\r')) + if ((buffer[--r] != '\n') || (buffer[--r] != '\r')) return -EINVAL; - - buffer[n] = '\0'; - - return n; + buffer[r] = '\0'; + + return 0; } -int command(struct xsocket *s, char *frmt, ...) +int xcommand(struct xsocket *s, const char *frmt, ...) { - int r, n; + int r, len; char buffer[1024]; va_list v; - + va_start(v, frmt); - n = vsnprintf(buffer, sizeof(buffer) - 2, frmt, v); + len = vsnprintf(buffer, sizeof(buffer) - 2, frmt, v); va_end(v); + buffer[len++] = '\r'; + buffer[len++] = '\n'; - buffer[n++] = '\r'; - buffer[n++] = '\n'; - - r = xsend(s, buffer, n); + r = XRETRY(__exchange(s, buffer, len, buffer, sizeof(buffer))); if (r < 0) return r; - r = mrecv(s, buffer, sizeof(buffer)); - if (r < 0) - return r; + if ((buffer[--r] != '\n') || (buffer[--r] != '\r')) + return -EINVAL; + buffer[r] = '\0'; if (strcmp(buffer, "OK") != 0) return -EINVAL; - + return 0; }