diff options
| author | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2021-03-05 18:14:11 -0300 | 
|---|---|---|
| committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2021-03-05 18:17:27 -0300 | 
| commit | d9d7af1a52d77ed0074ebb72f87678308296e74e (patch) | |
| tree | e5663c17ea0780bbf043527e31a374de1f163a65 /lib/ringbuf.c | |
| parent | 130daf24ae1acf5db602e55c13b9ffca139a1dbf (diff) | |
lib: add ringbuf socket read function
Implement new ringbuf function to do the proper socket reads without
the need of intermediary buffers.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'lib/ringbuf.c')
| -rw-r--r-- | lib/ringbuf.c | 35 | 
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/ringbuf.c b/lib/ringbuf.c index 1c3c3e9753..26c4e744b4 100644 --- a/lib/ringbuf.c +++ b/lib/ringbuf.c @@ -131,3 +131,38 @@ void ringbuf_wipe(struct ringbuf *buf)  	memset(buf->data, 0x00, buf->size);  	ringbuf_reset(buf);  } + +ssize_t ringbuf_read(struct ringbuf *buf, int sock) +{ +	size_t to_read = ringbuf_space(buf); +	size_t bytes_to_end = buf->size - buf->end; +	ssize_t bytes_read; +	struct iovec iov[2] = {}; + +	/* Calculate amount of read blocks. */ +	if (to_read > bytes_to_end) { +		iov[0].iov_base = buf->data + buf->end; +		iov[0].iov_len = bytes_to_end; +		iov[1].iov_base = buf->data; +		iov[1].iov_len = to_read - bytes_to_end; +	} else { +		iov[0].iov_base = buf->data + buf->end; +		iov[0].iov_len = to_read; +	} + +	/* Do the system call. */ +	bytes_read = readv(sock, iov, 2); +	if (bytes_read <= 0) +		return bytes_read; + +	/* Calculate the new end. */ +	if ((size_t)bytes_read > bytes_to_end) +		buf->end = bytes_read - bytes_to_end; +	else +		buf->end += bytes_read; + +	/* Set emptiness state. */ +	buf->empty = (buf->start == buf->end) && (buf->empty && !bytes_read); + +	return bytes_read; +}  | 
