readline - read a '\n' terminated line from socket fd into buffer bufptr of size len. The line in the buffer is terminated with '\0'. It returns -1 in case of error or if the capacity of the buffer is exceeded. It returns 0 if EOF is encountered before reading '\n'. */
| 195 | It returns 0 if EOF is encountered before reading '\n'. |
| 196 | */ |
| 197 | int readline(int fd, char *bufptr, size_t len) { |
| 198 | /* Note that this function is very tricky. It uses the |
| 199 | static variables bp, cnt, and b to establish a local buffer. |
| 200 | The recv call requests large chunks of data (the size of the buffer). |
| 201 | Then if the recv call reads more than one line, the overflow |
| 202 | remains in the buffer and it is made available to the next call |
| 203 | to readline. |
| 204 | Notice also that this routine reads up to '\n' and overwrites |
| 205 | it with '\0'. Thus if the line is really terminated with |
| 206 | "\r\n", the '\r' will remain unchanged. |
| 207 | */ |
| 208 | char *bufx = bufptr; |
| 209 | static char *bp; |
| 210 | static int cnt = 0; |
| 211 | static char b[4096]; |
| 212 | char c; |
| 213 | |
| 214 | while (--len > 0) { |
| 215 | if (--cnt <= 0) { |
| 216 | cnt = recv(fd, b, sizeof(b), 0); |
| 217 | if (cnt < 0) { |
| 218 | if ( errno == EINTR) { |
| 219 | len++; /* the while will decrement */ |
| 220 | continue; |
| 221 | } |
| 222 | return -1; |
| 223 | } |
| 224 | if (cnt == 0) |
| 225 | return 0; |
| 226 | bp = b; |
| 227 | } |
| 228 | c = *bp++; |
| 229 | *bufptr++ = c; |
| 230 | if (c == '\n') { |
| 231 | *bufptr = '\0'; |
| 232 | return bufptr - bufx; |
| 233 | } |
| 234 | } |
| 235 | return -1; |
| 236 | } |
| 237 | |
| 238 | int readData(int socket, uint8_t *buf, int buflen) { |
| 239 | int sendSize = buflen; |