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.
- * 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);
ret = 0;
if (n == 0)
goto out;
ret = -E_READ_PATTERN;
ret = 0;
if (n == 0)
goto out;
ret = -E_READ_PATTERN;
- if (strncasecmp(buf, pattern, len) != 0)
+ if (strncasecmp(buf, expectation, len) != 0)
- if (ret < 0) {
- PARA_NOTICE_LOG("%s\n", para_strerror(-ret));
- PARA_NOTICE_LOG("recvd %zu bytes: %s\n", n, buf);
- }
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);
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,
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,
return 0;
}
if (phd->status == HTTP_SENT_GET_REQUEST) {
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;
if (ret < 0) {
PARA_ERROR_LOG("did not receive HTTP OK message\n");
goto out;
case HTTP_STREAMING: /* nothing to do */
break;
case HTTP_CONNECTED: /* need to recv get request */
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) {
if (ret < 0)
phsd->status = HTTP_INVALID_GET_REQUEST;
else if (ret > 0) {