I have a c++ program running under Linux Debian 9. I'm doing a simple read() from a file descriptor:
int bytes_read = read(fd, buffer, buffer_size);
Imagine that I want to read some more data from the socket, but I want to skip a known number of bytes before getting to some content I'm interested in:
int unwanted_bytes_read = read(fd, unwanted_buffer, bytes_to_skip);
int useful_bytes = read(fd, buffer, buffer_size);
In Linux, is there a system-wide 'built-in' location that I can dump the unwanted bytes into, rather than having to maintain a buffer for unwanted data (like unwanted_buffer
in the above example)?
I suppose what I'm looking for would be (sort of) the opposite of MSG_PEEK
in the socket world, i.e. the kernel would purge bytes_to_skip
from its receive buffer before the next useful call to recv.
If I were reading from a file then lseek
would be enough. But this is not possible if you are reading from a socket and are using scatter/gather I/O, and you want to drop one of the fields.
I'm thinking about something like this:
// send side
int a = 1;
int b = 2;
int c = 3;
struct iovec iov[3];
ssize_t nwritten;
iov[0].iov_base = &a;
iov[0].iov_len = sizeof(int);
iov[1].iov_base = &b;
iov[1].iov_len = sizeof(int);
iov[2].iov_base = &c;
iov[2].iov_len = sizeof(int);
nwritten = writev(fd, iov, 3);
// receive side
int a = -1;
int c = -1;
struct iovec iov[3]; // you know that you'll be receiving three fields and what their sizes are, but you don't care about the second.
ssize_t nread;
iov[0].iov_base = &a;
iov[0].iov_len = sizeof(int);
iov[1].iov_base = ??? <---- what to put here?
iov[1].iov_len = sizeof(int);
iov[2].iov_base = &c;
iov[2].iov_len = sizeof(int);
nread = readv(fd, iov, 3);
I know that I could just create another b
variable on the receive side, but if I don't want to, how can I read the sizeof(int)
bytes that it occupies in the file but just dump the data and proceed to c
? I could just create a generic buffer to dump b
into, all I was asking is if there is such a location by default.
[EDIT]
Following a suggestion from @inetknght, I tried memory mapping /dev/null and doing my gather into the mapped address:
int nullfd = open("/dev/null", O_WRONLY);
void* blackhole = mmap(NULL, iov[1].iov_len, PROT_WRITE, MAP_SHARED, nullfd, 0);
iov[1].iov_base = blackhole;
nread = readv(fd, iov, 3);
However, blackhole
comes out as 0xffff
and I get an errno 13 'Permission Denied'. I tried running my code as su and this doesn't work either. Perhaps I'm setting up my mmap
incorrectly?