}
/**
- * Simple wrapper for readv().
+ * Read a buffer and check its content for a pattern.
*
- * \param fd The file descriptor to read from.
- * \param iov Scatter/gather array used in readv().
- * \param iovcnt Number of elements in \a iov.
+ * \param fd The file descriptor to receive from.
+ * \param pattern The expected pattern.
+ * \param bufsize The size of the internal buffer.
+ * \param rfds Passed to read_nonblock().
*
- * \return A negative error code on errors, the return value of the underlying
- * call to readv() otherwise.
+ * 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.
*
- * \sa readv(2).
+ * \return Positive if \a pattern was received, negative on errors, zero if no data
+ * was available to read.
+ *
+ * \sa \ref read_nonblock(), \sa strncasecmp(3).
*/
-int para_readv(int fd, struct iovec *iov, int iovcnt)
+int read_pattern(int fd, const char *pattern, size_t bufsize, fd_set *rfds)
{
- int ret = readv(fd, iov, iovcnt);
+ size_t n, len;
+ char *buf = para_malloc(bufsize + 1);
+ int ret = read_nonblock(fd, buf, bufsize, rfds, &n);
+ buf[n] = '\0';
if (ret < 0)
- return -ERRNO_TO_PARA_ERROR(errno);
+ goto out;
+ 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)
+ 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;
}