From 8a63543fdfbd3b5d00e4afecfbc397795a49ed04 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 25 Apr 2010 19:54:06 +0200 Subject: [PATCH] Make recv_pattern() use the nonblock API. 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 | 2 +- fd.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ fd.h | 1 + http_recv.c | 6 +++--- http_send.c | 17 +++++++---------- net.c | 38 -------------------------------------- net.h | 1 - 7 files changed, 57 insertions(+), 53 deletions(-) diff --git a/error.h b/error.h index e30e8a28..1c477137 100644 --- 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 2e59bc95..bdba2765 100644 --- 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 787784d3..c21a7d14 100644 --- 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, diff --git a/http_recv.c b/http_recv.c index cc376dd9..636e2241 100644 --- a/http_recv.c +++ b/http_recv.c @@ -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; diff --git a/http_send.c b/http_send.c index 828d99e2..c8879fec 100644 --- a/http_send.c +++ b/http_send.c @@ -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 92ae217d..64693bef 100644 --- 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 93c0c5e8..c43249ea 100644 --- 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 -- 2.39.2