Make recv_pattern() use the nonblock API.
authorAndre Noll <maan@systemlinux.org>
Sun, 25 Apr 2010 17:54:06 +0000 (19:54 +0200)
committerAndre Noll <maan@systemlinux.org>
Sun, 25 Apr 2010 17:54:06 +0000 (19:54 +0200)
Move it to fd.c and rename it to read_pattern(). Both users, http_recv.c and http_send.c,
are adjusted accordingly.

error.h
fd.c
fd.h
http_recv.c
http_send.c
net.c
net.h

diff --git a/error.h b/error.h
index e30e8a2..1c47713 100644 (file)
--- a/error.h
+++ b/error.h
@@ -228,7 +228,6 @@ extern const char **para_errlist[];
        PARA_ERROR(SENDMSG, "sendmsg() failed"), \
        PARA_ERROR(RECVMSG, "recvmsg() failed"), \
        PARA_ERROR(SCM_CREDENTIALS, "did not receive SCM credentials"), \
-       PARA_ERROR(RECV_PATTERN, "did not receive expected pattern"), \
 
 
 #define UDP_RECV_ERRORS \
@@ -375,6 +374,7 @@ extern const char **para_errlist[];
 #define FD_ERRORS \
        PARA_ERROR(FGETS, "fgets error"), \
        PARA_ERROR(EOF, "end of file"), \
+       PARA_ERROR(READ_PATTERN, "did not read expected pattern"), \
 
 
 #define WRITE_ERRORS \
diff --git a/fd.c b/fd.c
index 2e59bc9..bdba276 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -177,6 +177,51 @@ int read_nonblock(int fd, void *buf, size_t sz, fd_set *rfds, size_t *num_bytes)
        return readv_nonblock(fd, &iov, 1, rfds, num_bytes);
 }
 
+/**
+ * Read a buffer and check its content for a pattern.
+ *
+ * \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.
+ *
+ * \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 read_pattern(int fd, const char *pattern, size_t bufsize, fd_set *rfds)
+{
+       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)
+               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;
+}
+
 /**
  * Check whether a file exists.
  *
diff --git a/fd.h b/fd.h
index 787784d..c21a7d1 100644 (file)
--- a/fd.h
+++ b/fd.h
@@ -29,6 +29,7 @@ void valid_fd_012(void);
 int readv_nonblock(int fd, struct iovec *iov, int iovcnt, fd_set *rfds,
                size_t *num_bytes);
 int read_nonblock(int fd, void *buf, size_t sz, fd_set *rfds, size_t *num_bytes);
+int read_pattern(int fd, const char *pattern, size_t bufsize, fd_set *rfds);
 int write_nonblock(int fd, const char *buf, size_t len,
                size_t max_bytes_per_write);
 int for_each_file_in_dir(const char *dirname,
index cc376dd..636e224 100644 (file)
@@ -116,12 +116,12 @@ static void http_recv_post_select(struct sched *s, struct task *t)
                phd->status = HTTP_SENT_GET_REQUEST;
                return;
        }
-       if (!FD_ISSET(phd->fd, &s->rfds))
-               return;
        if (phd->status == HTTP_SENT_GET_REQUEST) {
-               ret = recv_pattern(phd->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG));
+               ret = read_pattern(phd->fd, HTTP_OK_MSG, strlen(HTTP_OK_MSG), &s->rfds);
                if (ret < 0)
                        goto err;
+               if (ret == 0)
+                       return;
                PARA_INFO_LOG("received ok msg, streaming\n");
                phd->status = HTTP_STREAMING;
                return;
index 828d99e..c8879fe 100644 (file)
@@ -96,23 +96,20 @@ static void http_post_select(fd_set *rfds, __a_unused fd_set *wfds)
 {
        struct sender_client *sc, *tmp;
        struct private_http_sender_data *phsd;
+       int ret;
 
-       if (hss->listen_fd < 0)
-               return;
        list_for_each_entry_safe(sc, tmp, &hss->client_list, node) {
                phsd = sc->private_data;
                switch (phsd->status) {
                case HTTP_STREAMING: /* nothing to do */
                        break;
                case HTTP_CONNECTED: /* need to recv get request */
-                       if (FD_ISSET(sc->fd, rfds)) {
-                               if (recv_pattern(sc->fd, HTTP_GET_MSG, MAXLINE)
-                                               < 0) {
-                                       phsd->status = HTTP_INVALID_GET_REQUEST;
-                               } else {
-                                       phsd->status = HTTP_GOT_GET_REQUEST;
-                                       PARA_INFO_LOG("received get request\n");
-                               }
+                       ret = read_pattern(sc->fd, HTTP_GET_MSG, MAXLINE, rfds);
+                       if (ret < 0)
+                               phsd->status = HTTP_INVALID_GET_REQUEST;
+                       else if (ret > 0) {
+                               phsd->status = HTTP_GOT_GET_REQUEST;
+                               PARA_INFO_LOG("received get request\n");
                        }
                        break;
                case HTTP_GOT_GET_REQUEST: /* need to send ok msg */
diff --git a/net.c b/net.c
index 92ae217..64693be 100644 (file)
--- a/net.c
+++ b/net.c
@@ -1017,41 +1017,3 @@ int recv_cred_buffer(int fd, char *buf, size_t size)
        return result;
 }
 #endif /* HAVE_UCRED */
-
-/**
- * Receive a buffer and check for a pattern.
- *
- * \param fd The file descriptor to receive from.
- * \param pattern The expected pattern.
- * \param bufsize The size of the internal buffer.
- *
- * \return Positive if \a pattern was received, negative otherwise.
- *
- * This function tries to receive at most \a bufsize bytes from file descriptor
- * \a fd. If at least \p strlen(\a pattern) bytes were received, the beginning
- * of the received buffer is compared with \a pattern, ignoring case.
- *
- * \sa recv_buffer(), \sa strncasecmp(3).
- */
-int recv_pattern(int fd, const char *pattern, size_t bufsize)
-{
-       size_t len = strlen(pattern);
-       char *buf = para_malloc(bufsize + 1);
-       int ret = -E_RECV_PATTERN, n = recv_buffer(fd, buf, bufsize + 1);
-
-       if (n < len)
-               goto out;
-       if (strncasecmp(buf, pattern, len))
-               goto out;
-       ret = 1;
-out:
-       if (ret < 0) {
-               PARA_NOTICE_LOG("did not receive pattern '%s'\n", pattern);
-               if (n > 0)
-                       PARA_NOTICE_LOG("recvd %d bytes: %s\n", n, buf);
-               else if (n < 0)
-                       PARA_NOTICE_LOG("%s\n", para_strerror(-n));
-       }
-       free(buf);
-       return ret;
-}
diff --git a/net.h b/net.h
index 93c0c5e..c43249e 100644 (file)
--- a/net.h
+++ b/net.h
@@ -145,7 +145,6 @@ int create_local_socket(const char *name, struct sockaddr_un *unix_addr,
 int create_remote_socket(const char *name);
 int recv_cred_buffer(int, char *, size_t);
 ssize_t send_cred_buffer(int, char*);
-int recv_pattern(int fd, const char *pattern, size_t bufsize);
 
 /**
  * Functions and definitions to support \p IPPROTO_DCCP