diff --git a/main.c b/main.c index 077ada5..d657d07 100644 --- a/main.c +++ b/main.c @@ -56,16 +56,6 @@ void handle_exit_signal(int signum) exit_requested = true; } -static int retrying_write(int fd, const char *buf, size_t len) -{ - int n; - do { - errno = 0; - n = write(fd, buf, len); - } while (errno == EINTR); - return n; -} - static int append_selector_part(const char *part, size_t partlen, char *buf, size_t bufsize) { @@ -162,8 +152,10 @@ int main(int argc, char *argv[]) struct sockaddr_in6 paddr; socklen_t paddr_size = sizeof(paddr); int cfd; - ssize_t n, slen; + ssize_t n, slen, rlen; while (!exit_requested) { + n = slen = rlen = 0; + /* * Accept incoming connection. * @@ -283,7 +275,6 @@ int main(int argc, char *argv[]) * endings is done with a buffered reading approach to * minimize syscalls (as opposed to using fgetc()). */ - unsigned rpos = 0; while (true) { /* Fill fbuf from file. */ n = fread(fbuf, sizeof(*fbuf), FBUF_SIZE, rf); @@ -295,38 +286,24 @@ int main(int argc, char *argv[]) /* Copy from fbuf to rbuf, replacing LF with CRLF. */ for (unsigned fpos = 0; fpos < n; ++fpos) { if (fbuf[fpos] == '\n') { - if (RBUF_SIZE - rpos < 2) { + if (RBUF_SIZE - rlen < 2) { fprintf(stderr, "Response buffer is too small"); goto close_client_socket; } - rbuf[rpos++] = '\r'; - rbuf[rpos++] = '\n'; + rbuf[rlen++] = '\r'; + rbuf[rlen++] = '\n'; } else { - if (RBUF_SIZE - rpos < 1) { + if (RBUF_SIZE - rlen < 1) { fprintf(stderr, "Response buffer is too small"); goto close_client_socket; } - rbuf[rpos++] = fbuf[fpos]; + rbuf[rlen++] = fbuf[fpos]; } } if (feof(rf)) break; } - - /* - * Terminate and send the response. - */ - if (RBUF_SIZE - rpos < RESP_TERM_LEN) { - fprintf(stderr, "Response buffer is too small"); - goto close_client_socket; - } - memcpy(&rbuf[rpos], RESP_TERM, RESP_TERM_LEN); - rpos += RESP_TERM_LEN; - if (retrying_write(cfd, rbuf, rpos) == -1) { - fprintf(stderr, "Failed to write response to client\n"); - goto close_client_socket; - } } else if (S_ISDIR(rstat.st_mode)) { /* * Open the directory. @@ -390,24 +367,16 @@ int main(int argc, char *argv[]) continue; /* - * Format and send response line for current entry. + * Format response line for current entry. */ - n = snprintf(rbuf, RBUF_SIZE, "%1u%s\t%s\t%s\t%u\r\n", type, - ent->d_name, &pbuf[srvroot_len], HOST, PORT); - if (n >= RBUF_SIZE) { - fprintf(stderr, - "Response buffer was too small, skipping entry\n"); - continue; + n = snprintf(&rbuf[rlen], RBUF_SIZE - rlen, + "%1u%s\t%s\t%s\t%u\r\n", type, ent->d_name, + &pbuf[srvroot_len], HOST, PORT); + if (n >= RBUF_SIZE - rlen) { + fprintf(stderr, "Response buffer was too small\n"); + goto close_client_socket; } - if (retrying_write(cfd, rbuf, n) != n) { - fprintf(stderr, "Error sending respose line to client\n"); - continue; - } - } - if (retrying_write(cfd, ".\r\n", 3) != 3) { - fprintf(stderr, - "Error sending response terminator to client\n"); - goto close_client_socket; + rlen += n; } /* @@ -422,6 +391,24 @@ int main(int argc, char *argv[]) goto close_client_socket; } + /* + * Terminate and send the response. + */ + if (RBUF_SIZE - rlen < RESP_TERM_LEN) { + fprintf(stderr, "Response buffer is too small"); + goto close_client_socket; + } + memcpy(&rbuf[rlen], RESP_TERM, RESP_TERM_LEN); + rlen += RESP_TERM_LEN; + do { + errno = 0; + n = write(cfd, rbuf, rlen); + } while (errno == EINTR); + if (n == -1) { + fprintf(stderr, "Failed to write response to client\n"); + goto close_client_socket; + } + close_client_socket: close(cfd); }