diff fuzz-wrapfd.c @ 1740:dfbe947bdf0d fuzz

Make wrapfd share a common buffer for all FDs
author Matt Johnston <matt@ucc.asn.au>
date Thu, 15 Oct 2020 22:46:24 +0800
parents 60fceff95858
children 6cf465af5d9f
line wrap: on
line diff
--- a/fuzz-wrapfd.c	Thu Oct 15 19:55:15 2020 +0800
+++ b/fuzz-wrapfd.c	Thu Oct 15 22:46:24 2020 +0800
@@ -7,6 +7,8 @@
 #include "fuzz.h"
 
 #define IOWRAP_MAXFD (FD_SETSIZE-1)
+// hopefully above any real fd...
+static const int WRAPFD_STARTFD = 400;
 static const int MAX_RANDOM_IN = 50000;
 static const double CHANCE_CLOSE = 1.0 / 600;
 static const double CHANCE_INTR = 1.0 / 900;
@@ -17,25 +19,21 @@
 
 struct fdwrap {
 	enum wrapfd_mode mode;
-	buffer *buf;
 	int closein;
 	int closeout;
 };
 
 static struct fdwrap wrap_fds[IOWRAP_MAXFD+1];
-/* for quick selection of in-use descriptors */
-static int wrap_used[IOWRAP_MAXFD+1];
-static unsigned int nused;
 static unsigned short rand_state[3];
+static buffer *input_buf;
 
-void wrapfd_setup(void) {
+void wrapfd_setup(buffer *buf) {
 	TRACE(("wrapfd_setup"))
-	nused = 0;
 	memset(wrap_fds, 0x0, sizeof(wrap_fds));
-	memset(wrap_used, 0x0, sizeof(wrap_used));
 
 	memset(rand_state, 0x0, sizeof(rand_state));
 	wrapfd_setseed(50);
+	input_buf = buf;
 }
 
 void wrapfd_setseed(uint32_t seed) {
@@ -43,39 +41,29 @@
 	nrand48(rand_state);
 }
 
-void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) {
-	TRACE(("wrapfd_add %d buf %p mode %d", fd, buf, mode))
-	assert(fd >= 0);
-	assert(fd <= IOWRAP_MAXFD);
-	assert(wrap_fds[fd].mode == UNUSED);
-	assert(buf || mode == RANDOMIN);
-
-	wrap_fds[fd].mode = mode;
-	wrap_fds[fd].buf = buf;
-	wrap_fds[fd].closein = 0;
-	wrap_fds[fd].closeout = 0;
-	wrap_used[nused] = fd;
-
-	nused++;
+int wrapfd_new() {
+	int fd;
+	// Find a spare file descriptor to use
+	for (fd = WRAPFD_STARTFD; fd < IOWRAP_MAXFD; fd++) {
+		if (wrap_fds[fd].mode == UNUSED) {
+			// check real file descriptors haven't got as far as WRAPFD_STARTFD
+			assert(close(fd) == -1 && errno == EBADF);
+			wrap_fds[fd].mode = COMMONBUF;
+			wrap_fds[fd].closein = 0;
+			wrap_fds[fd].closeout = 0;
+			return fd;
+		}
+	}
+	errno = EMFILE;
+	return -1;
 }
 
 void wrapfd_remove(int fd) {
-	unsigned int i, j;
 	TRACE(("wrapfd_remove %d", fd))
 	assert(fd >= 0);
 	assert(fd <= IOWRAP_MAXFD);
 	assert(wrap_fds[fd].mode != UNUSED);
 	wrap_fds[fd].mode = UNUSED;
-
-
-	/* remove from used list */
-	for (i = 0, j = 0; i < nused; i++) {
-		if (wrap_used[i] != fd) {
-			wrap_used[j] = wrap_used[i];
-			j++;
-		}
-	}
-	nused--;
 }
 
 int wrapfd_close(int fd) {
@@ -115,15 +103,14 @@
 		return -1;
 	}
 
-	buf = wrap_fds[fd].buf;
-	if (buf) {
-		maxread = MIN(buf->len - buf->pos, count);
+	if (input_buf) {
+		maxread = MIN(input_buf->len - input_buf->pos, count);
 		/* returns 0 if buf is EOF, as intended */
 		if (maxread > 0) {
 			maxread = nrand48(rand_state) % maxread + 1;
 		}
-		memcpy(out, buf_getptr(buf, maxread), maxread);
-		buf_incrpos(buf, maxread);
+		memcpy(out, buf_getptr(input_buf, maxread), maxread);
+		buf_incrpos(input_buf, maxread);
 		return maxread;
 	}