comparison 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
comparison
equal deleted inserted replaced
1739:13d834efc376 1740:dfbe947bdf0d
5 #include "dbutil.h" 5 #include "dbutil.h"
6 6
7 #include "fuzz.h" 7 #include "fuzz.h"
8 8
9 #define IOWRAP_MAXFD (FD_SETSIZE-1) 9 #define IOWRAP_MAXFD (FD_SETSIZE-1)
10 // hopefully above any real fd...
11 static const int WRAPFD_STARTFD = 400;
10 static const int MAX_RANDOM_IN = 50000; 12 static const int MAX_RANDOM_IN = 50000;
11 static const double CHANCE_CLOSE = 1.0 / 600; 13 static const double CHANCE_CLOSE = 1.0 / 600;
12 static const double CHANCE_INTR = 1.0 / 900; 14 static const double CHANCE_INTR = 1.0 / 900;
13 static const double CHANCE_READ1 = 0.96; 15 static const double CHANCE_READ1 = 0.96;
14 static const double CHANCE_READ2 = 0.5; 16 static const double CHANCE_READ2 = 0.5;
15 static const double CHANCE_WRITE1 = 0.96; 17 static const double CHANCE_WRITE1 = 0.96;
16 static const double CHANCE_WRITE2 = 0.5; 18 static const double CHANCE_WRITE2 = 0.5;
17 19
18 struct fdwrap { 20 struct fdwrap {
19 enum wrapfd_mode mode; 21 enum wrapfd_mode mode;
20 buffer *buf;
21 int closein; 22 int closein;
22 int closeout; 23 int closeout;
23 }; 24 };
24 25
25 static struct fdwrap wrap_fds[IOWRAP_MAXFD+1]; 26 static struct fdwrap wrap_fds[IOWRAP_MAXFD+1];
26 /* for quick selection of in-use descriptors */
27 static int wrap_used[IOWRAP_MAXFD+1];
28 static unsigned int nused;
29 static unsigned short rand_state[3]; 27 static unsigned short rand_state[3];
30 28 static buffer *input_buf;
31 void wrapfd_setup(void) { 29
30 void wrapfd_setup(buffer *buf) {
32 TRACE(("wrapfd_setup")) 31 TRACE(("wrapfd_setup"))
33 nused = 0;
34 memset(wrap_fds, 0x0, sizeof(wrap_fds)); 32 memset(wrap_fds, 0x0, sizeof(wrap_fds));
35 memset(wrap_used, 0x0, sizeof(wrap_used));
36 33
37 memset(rand_state, 0x0, sizeof(rand_state)); 34 memset(rand_state, 0x0, sizeof(rand_state));
38 wrapfd_setseed(50); 35 wrapfd_setseed(50);
36 input_buf = buf;
39 } 37 }
40 38
41 void wrapfd_setseed(uint32_t seed) { 39 void wrapfd_setseed(uint32_t seed) {
42 memcpy(rand_state, &seed, sizeof(seed)); 40 memcpy(rand_state, &seed, sizeof(seed));
43 nrand48(rand_state); 41 nrand48(rand_state);
44 } 42 }
45 43
46 void wrapfd_add(int fd, buffer *buf, enum wrapfd_mode mode) { 44 int wrapfd_new() {
47 TRACE(("wrapfd_add %d buf %p mode %d", fd, buf, mode)) 45 int fd;
48 assert(fd >= 0); 46 // Find a spare file descriptor to use
49 assert(fd <= IOWRAP_MAXFD); 47 for (fd = WRAPFD_STARTFD; fd < IOWRAP_MAXFD; fd++) {
50 assert(wrap_fds[fd].mode == UNUSED); 48 if (wrap_fds[fd].mode == UNUSED) {
51 assert(buf || mode == RANDOMIN); 49 // check real file descriptors haven't got as far as WRAPFD_STARTFD
52 50 assert(close(fd) == -1 && errno == EBADF);
53 wrap_fds[fd].mode = mode; 51 wrap_fds[fd].mode = COMMONBUF;
54 wrap_fds[fd].buf = buf; 52 wrap_fds[fd].closein = 0;
55 wrap_fds[fd].closein = 0; 53 wrap_fds[fd].closeout = 0;
56 wrap_fds[fd].closeout = 0; 54 return fd;
57 wrap_used[nused] = fd; 55 }
58 56 }
59 nused++; 57 errno = EMFILE;
58 return -1;
60 } 59 }
61 60
62 void wrapfd_remove(int fd) { 61 void wrapfd_remove(int fd) {
63 unsigned int i, j;
64 TRACE(("wrapfd_remove %d", fd)) 62 TRACE(("wrapfd_remove %d", fd))
65 assert(fd >= 0); 63 assert(fd >= 0);
66 assert(fd <= IOWRAP_MAXFD); 64 assert(fd <= IOWRAP_MAXFD);
67 assert(wrap_fds[fd].mode != UNUSED); 65 assert(wrap_fds[fd].mode != UNUSED);
68 wrap_fds[fd].mode = UNUSED; 66 wrap_fds[fd].mode = UNUSED;
69
70
71 /* remove from used list */
72 for (i = 0, j = 0; i < nused; i++) {
73 if (wrap_used[i] != fd) {
74 wrap_used[j] = wrap_used[i];
75 j++;
76 }
77 }
78 nused--;
79 } 67 }
80 68
81 int wrapfd_close(int fd) { 69 int wrapfd_close(int fd) {
82 if (fd >= 0 && fd <= IOWRAP_MAXFD && wrap_fds[fd].mode != UNUSED) { 70 if (fd >= 0 && fd <= IOWRAP_MAXFD && wrap_fds[fd].mode != UNUSED) {
83 wrapfd_remove(fd); 71 wrapfd_remove(fd);
113 if (erand48(rand_state) < CHANCE_INTR) { 101 if (erand48(rand_state) < CHANCE_INTR) {
114 errno = EINTR; 102 errno = EINTR;
115 return -1; 103 return -1;
116 } 104 }
117 105
118 buf = wrap_fds[fd].buf; 106 if (input_buf) {
119 if (buf) { 107 maxread = MIN(input_buf->len - input_buf->pos, count);
120 maxread = MIN(buf->len - buf->pos, count);
121 /* returns 0 if buf is EOF, as intended */ 108 /* returns 0 if buf is EOF, as intended */
122 if (maxread > 0) { 109 if (maxread > 0) {
123 maxread = nrand48(rand_state) % maxread + 1; 110 maxread = nrand48(rand_state) % maxread + 1;
124 } 111 }
125 memcpy(out, buf_getptr(buf, maxread), maxread); 112 memcpy(out, buf_getptr(input_buf, maxread), maxread);
126 buf_incrpos(buf, maxread); 113 buf_incrpos(input_buf, maxread);
127 return maxread; 114 return maxread;
128 } 115 }
129 116
130 maxread = MIN(MAX_RANDOM_IN, count); 117 maxread = MIN(MAX_RANDOM_IN, count);
131 maxread = nrand48(rand_state) % maxread + 1; 118 maxread = nrand48(rand_state) % maxread + 1;