Provide a helper function for reading a single \n terminated string from a socket.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
diff --git a/util.c b/util.c
index ae2063d..b69cf23 100644
--- a/util.c
+++ b/util.c
@@ -863,6 +863,41 @@ static bool sock_send(int sock, char *s, ssize_t len)
#define RECVSIZE 8192
+static void clear_sock(SOCKETTYPE sock)
+{
+ char *s = alloca(RECVSIZE);
+
+ recv(sock, s, RECVSIZE, MSG_DONTWAIT);
+}
+
+/* Peeks at a socket to find the first end of line and then reads just that
+ * from the socket and returns that as a malloced char */
+static char *recv_line(SOCKETTYPE sock)
+{
+ char *sret = NULL, *s;
+ ssize_t len;
+
+ s = alloca(RECVSIZE);
+ if (SOCKETFAIL(recv(sock, s, RECVSIZE, MSG_PEEK))) {
+ applog(LOG_DEBUG, "Failed to recv sock in recv_line");
+ goto out;
+ }
+ sret = strtok(s, "\n");
+ if (!sret) {
+ applog(LOG_DEBUG, "Failed to parse a \\n terminated string in recv_line");
+ goto out;
+ }
+ len = strlen(sret);
+ /* We know how much data is in the buffer so this read should not fail */
+ read(sock, s, len);
+ sret = strdup(s);
+
+out:
+ if (!sret)
+ clear_sock(sock);
+ return sret;
+}
+
bool initiate_stratum(struct pool *pool)
{
json_t *val, *res_val, *err_val, *notify_val;
@@ -870,7 +905,6 @@ bool initiate_stratum(struct pool *pool)
struct timeval timeout;
json_error_t err;
bool ret = false;
- ssize_t len;
fd_set rd;
s = alloca(RECVSIZE);
@@ -898,22 +932,12 @@ bool initiate_stratum(struct pool *pool)
goto out;
}
- if (SOCKETFAIL(recv(pool->sock, s, RECVSIZE, MSG_PEEK | MSG_DONTWAIT))) {
- applog(LOG_DEBUG, "Failed to recv sock in initiate_stratum");
+ sret = recv_line(pool->sock);
+ if (!sret)
goto out;
- }
-
- sret = strtok(s, "\n");
- if (!sret) {
- applog(LOG_DEBUG, "Failed to parse a \\n terminated string in initiate_stratum");
- goto out;
- }
-
- /* We know how much data is in the buffer so this read should not fail */
- len = strlen(sret);
- read(pool->sock, s, len);
- val = JSON_LOADS(s, &err);
+ val = JSON_LOADS(sret, &err);
+ free(sret);
if (!val) {
applog(LOG_DEBUG, "JSON decode failed(%d): %s", err.line, err.text);
goto out;