X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=fd.c;h=ea16bdda993aff814fa41684af53506e46242a4f;hp=2e59bc95111d4e94daac0cf070ddf48b0dde4c81;hb=c0abcee0da53a6b399c3d16a62830aaa9ae21349;hpb=de7b5b177b8ad295820bd14c00b049fd8a5ec21f diff --git a/fd.c b/fd.c index 2e59bc95..ea16bdda 100644 --- a/fd.c +++ b/fd.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2010 Andre Noll + * Copyright (C) 2006-2011 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -49,10 +49,6 @@ int write_all(int fd, const char *buf, size_t *len) * \param fd The file descriptor. * \param buf the buffer to write. * \param len the number of bytes of \a buf. - * \param max_bytes_per_write Do not write more than that many bytes at once. - * - * If \a max_bytes_per_write is non-zero, do not send more than that many bytes - * per write(). * * EAGAIN is not considered an error condition. For example CCID3 has a * sending wait queue which fills up and is emptied asynchronously. The EAGAIN @@ -61,8 +57,7 @@ int write_all(int fd, const char *buf, size_t *len) * * \return Negative on errors, number of bytes written else. */ -int write_nonblock(int fd, const char *buf, size_t len, - size_t max_bytes_per_write) +int write_nonblock(int fd, const char *buf, size_t len) { size_t written = 0; int ret = 0; @@ -70,8 +65,6 @@ int write_nonblock(int fd, const char *buf, size_t len, while (written < len) { size_t num = len - written; - if (max_bytes_per_write && max_bytes_per_write < num) - num = max_bytes_per_write; ret = write(fd, buf + written, num); if (ret < 0 && errno == EAGAIN) return written; @@ -104,7 +97,7 @@ int write_nonblock(int fd, const char *buf, size_t len, * In any case, \a num_bytes contains the number of bytes that have been * successfully read from \a fd (zero if the first readv() call failed with * EAGAIN). Note that even if the function returns negative, some data might - * have been read before the error occured. In this case \a num_bytes is + * have been read before the error occurred. In this case \a num_bytes is * positive. * * \sa \ref write_nonblock(), read(2), readv(2). @@ -177,6 +170,52 @@ 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. + * \param rfds Passed to read_nonblock(). + * + * 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. * @@ -407,7 +446,7 @@ int para_chdir(const char *path) * \sa getcwd(3). * */ -int para_opendir(const char *dirname, DIR **dir, int *cwd) +static int para_opendir(const char *dirname, DIR **dir, int *cwd) { int ret; @@ -441,7 +480,7 @@ close_cwd: * * \return Standard. */ -int para_fchdir(int fd) +static int para_fchdir(int fd) { if (fchdir(fd) < 0) return -ERRNO_TO_PARA_ERROR(errno); @@ -524,6 +563,9 @@ out: int para_munmap(void *start, size_t length) { int err; + + if (!start) + return 0; if (munmap(start, length) >= 0) return 1; err = errno;