]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
fd: Improve read_pattern(), rename it to read_and_compare().
authorAndre Noll <maan@tuebingen.mpg.de>
Sun, 25 Sep 2022 20:01:25 +0000 (22:01 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 7 May 2023 18:45:22 +0000 (20:45 +0200)
The old name was a poor choice because the pattern argument actually
is neither a regular expression nor a filename pattern.

More importantly, the function receives a buffer size and tries
to read this many bytes but then compares only the first part of
the received buffer to the expected string. This is a rather weird
calling convention.

The only two callers are the http sender and receiver which both
call the function during the initial handshake where no other data is
available. Thus we can change the function to read only the minimal
amount of data (length of the expected string), and drop the bufsize
parameter.

Remove the unnecessary log message in the error case and streamline
the documentation while at it.

fd.c
fd.h
http_recv.c
http_send.c

diff --git a/fd.c b/fd.c
index 236494515697ba18d01ad3e5049839d7780be6ad..d858ae623ba6203719e70930625df97867166e67 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -260,46 +260,40 @@ int read_nonblock(int fd, void *buf, size_t sz, size_t *num_bytes)
 }
 
 /**
- * Read a buffer and check its content for a pattern.
+ * Read a buffer and compare its contents to a string, ignoring case.
  *
- * \param fd The file descriptor to receive from.
- * \param pattern The expected pattern.
- * \param bufsize The size of the internal buffer.
- *
- * This function tries to read at most \a bufsize bytes from the non-blocking
- * file descriptor \a fd. If at least \p strlen(\a pattern) bytes have been
- * received, the beginning of the received buffer is compared with \a pattern,
- * ignoring case.
+ * \param fd The file descriptor to read from.
+ * \param expectation The expected string to compare to.
  *
- * \return Positive if \a pattern was received, negative on errors, zero if no data
- * was available to read.
+ * The given file descriptor is expected to be in non-blocking mode. The string
+ * comparison is performed using strncasecmp(3).
  *
- * \sa \ref read_nonblock(), \sa strncasecmp(3).
+ * \return Zero if no data was available, positive if a buffer was read whose
+ * contents compare as equal to the expected string, negative otherwise.
+ * Possible errors: (a) not enough data was read, (b) the buffer contents
+ * compared as non-equal, (c) a read error occurred. In the first two cases,
+ * -E_READ_PATTERN is returned. In the read error case the (negative) return
+ * value of the underlying call to \ref read_nonblock() is returned.
  */
-int read_pattern(int fd, const char *pattern, size_t bufsize)
+int read_and_compare(int fd, const char *expectation)
 {
-       size_t n, len;
-       char *buf = alloc(bufsize + 1);
-       int ret = read_nonblock(fd, buf, bufsize, &n);
+       size_t n, len = strlen(expectation);
+       char *buf = alloc(len + 1);
+       int ret = read_nonblock(fd, buf, len, &n);
 
-       buf[n] = '\0';
        if (ret < 0)
                goto out;
+       buf[n] = '\0';
        ret = 0;
        if (n == 0)
                goto out;
        ret = -E_READ_PATTERN;
-       len = strlen(pattern);
        if (n < len)
                goto out;
-       if (strncasecmp(buf, pattern, len) != 0)
+       if (strncasecmp(buf, expectation, len) != 0)
                goto out;
        ret = 1;
 out:
-       if (ret < 0) {
-               PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
-               PARA_NOTICE_LOG("recvd %zu bytes: %s\n", n, buf);
-       }
        free(buf);
        return ret;
 }
diff --git a/fd.h b/fd.h
index 9f11dc85c8206bd19b6d85cbeac7f104b339d11b..da480f0bc134e20f1f6d656d12eb635dbf31be85 100644 (file)
--- a/fd.h
+++ b/fd.h
@@ -19,7 +19,7 @@ int write_ok(int fd);
 void valid_fd_012(void);
 int readv_nonblock(int fd, struct iovec *iov, int iovcnt, size_t *num_bytes);
 int read_nonblock(int fd, void *buf, size_t sz, size_t *num_bytes);
-int read_pattern(int fd, const char *pattern, size_t bufsize);
+int read_and_compare(int fd, const char *expectation);
 int xwrite(int fd, const char *buf, size_t len);
 int xwritev(int fd, struct iovec *iov, int iovcnt);
 int for_each_file_in_dir(const char *dirname,
index 32c9e7b9af6b24ca0fc93f3d7d65fce15c32e03a..8d2add19091f4894814c1aeeaeeefee5d5c8c19e 100644 (file)
@@ -105,7 +105,7 @@ static int http_recv_post_monitor(struct sched *s, void *context)
                return 0;
        }
        if (phd->status == HTTP_SENT_GET_REQUEST) {
-               ret = read_pattern(rn->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG));
+               ret = read_and_compare(rn->fd, HTTP_OK_MSG);
                if (ret < 0) {
                        PARA_ERROR_LOG("did not receive HTTP OK message\n");
                        goto out;
index 90e3ee57d1b6d40152ef6fc4026331766e2524c5..429b4662a70497d522fd68a0e3467941e7edc959 100644 (file)
@@ -170,7 +170,7 @@ static void http_post_monitor(__a_unused struct sched *s)
                case HTTP_STREAMING: /* nothing to do */
                        break;
                case HTTP_CONNECTED: /* need to recv get request */
-                       ret = read_pattern(sc->fd, HTTP_GET_MSG, MAXLINE);
+                       ret = read_and_compare(sc->fd, HTTP_GET_MSG);
                        if (ret < 0)
                                phsd->status = HTTP_INVALID_GET_REQUEST;
                        else if (ret > 0) {