[Pkg-privacy-commits] [onioncat] 181/340: Added cyclic buffered read from fd in preparation for controller rewrite
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 13:04:38 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch debian
in repository onioncat.
commit 141d12f1863773fec3e0903f624fd9665178117f
Author: eagle <eagle at 58e1ccc2-750e-0410-8d0d-f93ca75ab447>
Date: Wed May 13 09:34:55 2009 +0000
Added cyclic buffered read from fd in preparation for controller rewrite
git-svn-id: http://www.cypherpunk.at/svn/onioncat/trunk@501 58e1ccc2-750e-0410-8d0d-f93ca75ab447
---
src/ocatfdbuf.c | 214 ++++++++++++++++++++++++++++++++++++++
src/{ocatcompat.c => ocatfdbuf.h} | 31 ++++--
2 files changed, 238 insertions(+), 7 deletions(-)
diff --git a/src/ocatfdbuf.c b/src/ocatfdbuf.c
new file mode 100644
index 0000000..a5244dd
--- /dev/null
+++ b/src/ocatfdbuf.c
@@ -0,0 +1,214 @@
+/* Copyright 2008-2009 Bernhard R. Fischer.
+ *
+ * This file is part of OnionCat.
+ *
+ * OnionCat is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OnionCat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with OnionCat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "ocatfdbuf.h"
+
+
+/*! Init fdFile_t structure.
+ * The function allocates memory, hence,
+ * it must be freed again with fdf_free().
+ * @param fd File descriptor if open file.
+ * @param delim Delimiting character.
+ * @return Pointer to fdFile_t structure.
+ */
+fdFile_t* fdf_init(int fd, char delim)
+{
+ fdFile_t *fdf;
+ long flags;
+
+ // set fd in non-blocking mode
+ if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
+ return NULL;
+ if ((fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1)
+ return NULL;
+
+ if (!(fdf = malloc(sizeof(fdFile_t))))
+ return NULL;
+
+ fdf->fd = fd;
+ fdf->wp = fdf->rp = fdf->buf;
+ fdf->len = 0;
+ fdf->delim = delim;
+ fdf->eof = 0;
+
+ return fdf;
+}
+
+
+void fdf_free(fdFile_t *fdf)
+{
+ free(fdf);
+}
+
+
+/*! Block and read data into buffer as soon as it is available.
+ * @param fdf Pointer to fdFile_t structure.
+ * @return Number of bytes read or -1 if an error occured. In the
+ * latter case errno is set appropriately. If the number of
+ * bytes is 0, then the buffer is full.
+ */
+int fdf_fill(fdFile_t *fdf)
+{
+ fd_set rset;
+ int maxfd = -1, len;
+
+ // cycle write position
+ if (fdf->wp >= fdf->buf + FDBUF_SIZE)
+ fdf->wp = fdf->buf;
+
+ FD_ZERO(&rset);
+ FD_SET(fdf->fd, &rset);
+
+ if ((maxfd = select(fdf->fd + 1, &rset, NULL, NULL, NULL)) == -1)
+ return -1;
+
+ if (maxfd != 1)
+ // Fatal error. This should never happen.
+ exit(1);
+
+ // test if write position is behind read position
+ if (fdf->wp > fdf->rp)
+ len = FDBUF_SIZE - (fdf->wp - fdf->buf);
+ // test if write position is before read position
+ else if (fdf->wp < fdf->rp)
+ len = fdf->rp - fdf->wp;
+ // if equal, test if buffer is full
+ else if (fdf->len)
+ return 0;
+ // else the buffer is empty, read to the end
+ else
+ len = FDBUF_SIZE - (fdf->wp - fdf->buf);
+
+ // read bytes into buffer
+ if ((len = read(fdf->fd, fdf->wp, len)) == -1)
+ return -1;
+
+ // test and set end-of-file
+ if (!len)
+ fdf->eof++;
+
+ // advance write position
+ fdf->wp += len;
+ // increase number of readable bytes
+ fdf->len += len;
+
+ return len;
+}
+
+
+/*! Copy bytes sequentially out of buffer. fdf_memcpy() does
+ * correctly move the read position pointer and decreases
+ * the byte counter.
+ * @param fdf Pointer to fdFile_t structure.
+ * @param buf Pointer to destination memory.
+ * @param n Number of bytes to copy. fdf_memcpy() does not check
+ * memory boundaries, hence, n must not be larger than
+ * fdf->rp - FDBUF_SIZE and buf must be large enough to
+ * receive all bytes.
+ * @return Number of bytes copied. This should always be n.
+ */
+int fdf_memcpy(fdFile_t *fdf, char *buf, int n)
+{
+ memcpy(buf, fdf->rp, n);
+ fdf->rp += n;
+ fdf->len -= n;
+ // set read position pointer to the beginning if it reached the end
+ if (fdf->rp >= fdf->buf + FDBUF_SIZE)
+ fdf->rp = fdf->buf;
+ return n;
+}
+
+
+/*! This is similar to fdf_memcpy but it copies memory which is
+ * wrapped around and it honors memory boundaries given by n and s.
+ * @param fdf Pointer to fdFile_t structure.
+ * @param buf Pointer to destination memory.
+ * @param n Number of bytes available in buf.
+ * @param s Number of bytes to copy.
+ * @return Number of bytes copied.
+ */
+int fdf_wrpcpy(fdFile_t *fdf, char *buf, int n, int s)
+{
+ int len = fdf->buf + FDBUF_SIZE - fdf->rp;
+
+ // check if bytes to copy do wrap
+ if (s < len)
+ len = s;
+ // copy part starting at the read position
+ if (n < len)
+ return fdf_memcpy(fdf, buf, n);
+ fdf_memcpy(fdf, buf, len);
+ // copy part at the beginning
+ buf += len;
+ if (n < s)
+ return fdf_memcpy(fdf, buf, n - len) + len;
+ return fdf_memcpy(fdf, buf, s - len) + len;
+}
+
+
+/*! Read n of bytes from file identified by fdf into buf.
+ * The bytes are copied to buf including the delimiter character
+ * except buf is too small. In that case it is filled to the
+ * maximum and of course does not include the delimiter.
+ * @param fdf Pointer to fdFile_t structure.
+ * @param buf Pointer to destination memory.
+ * @param n Number of bytes available in buf.
+ * @return Nuber of bytes actually read or -1 on error.
+ */
+int fdf_read(fdFile_t *fdf, char *buf, int n)
+{
+ int len;
+ char *s = NULL;
+
+ for (;;)
+ {
+ // determine if read buffer is wrapped
+ if (fdf->rp + fdf->len <= fdf->buf + FDBUF_SIZE)
+ // no
+ len = fdf->len;
+ else
+ // yes
+ len = (fdf->buf + FDBUF_SIZE) - fdf->rp;
+
+ // search delimiter in unwrapped part behind read position
+ if ((s = memchr(fdf->rp, fdf->delim, len)))
+ return fdf_wrpcpy(fdf, buf, n, s - fdf->rp + 1);
+
+ // test if wrapped part at the beginning of the buffer exists
+ if ((fdf->len - len))
+ // test if delimiter is found in the wrapped part at the beginning of the buffer
+ if ((s = memchr(fdf->buf, fdf->delim, fdf->len - len)))
+ return fdf_wrpcpy(fdf, buf, n, s - fdf->buf + len);
+
+ // test if buffer is full
+ if (fdf->len >= FDBUF_SIZE)
+ return fdf_wrpcpy(fdf, buf, n, FDBUF_SIZE);
+
+ if (fdf->eof)
+ return 0;
+
+ if ((len = fdf_fill(fdf)) == -1)
+ return -1;
+ }
+}
+
diff --git a/src/ocatcompat.c b/src/ocatfdbuf.h
similarity index 51%
copy from src/ocatcompat.c
copy to src/ocatfdbuf.h
index ebdbfde..8b1bdda 100644
--- a/src/ocatcompat.c
+++ b/src/ocatfdbuf.h
@@ -1,4 +1,4 @@
-/* Copyright 2008 Bernhard R. Fischer, Daniel Haslinger.
+/* Copyright 2008-2009 Bernhard R. Fischer.
*
* This file is part of OnionCat.
*
@@ -15,12 +15,29 @@
* along with OnionCat. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
+#ifndef OCATFDBUF_H
+#define OCATFDBUF_H
+
+
+#define FDBUF_SIZE 2048
+
+
+typedef struct fdFile
+{
+ int fd; //!< file descriptor
+ char buf[FDBUF_SIZE]; //!< buffer
+ char *wp; //!< write position
+ char *rp; //!< read position
+ int len; //!< readable bytes starting at read position
+ char delim; //!< delimiting character
+ int eof; //!< flag is set if EOF
+} fdFile_t;
+
+
+fdFile_t* fdf_init(int, char);
+void fdf_free(fdFile_t *);
+int fdf_read(fdFile_t *, char *, int);
+
-#ifndef HAVE_STRLCAT
-#include "strlcat.c"
-#endif
-#ifndef HAVE_STRLCPY
-#include "strlcpy.c"
#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/onioncat.git
More information about the Pkg-privacy-commits
mailing list