Here is the situation before the realloc:
fd_max_size
|
v
XXXOOOOXXXXX
^
|
fd_off
The X's are data, the O's are empty. What we start with after the realloc:
fd_max_size
|
v
XXXOOOOXXXXXOOOOOOOOOOOO
^
|
fd_off
In the original code we have the movement of data from byte 0
(tip->fd_buf) to tip->fd_off - over-writing data. I think if we use
tip->fd_max_size, we get the desired result (note: tip->fd_max_size is
updated to 2 times the size AFTER the memmove).
*/
if (tip->fd_off + tip->fd_size > tip->fd_max_size) {
unsigned long wrap_size = tip->fd_size - (tip->fd_max_size - tip->fd_off);
- memmove(tip->fd_buf + tip->fd_off, tip->fd_buf, wrap_size);
+ memmove(tip->fd_buf + tip->fd_max_size, tip->fd_buf, wrap_size);
}
tip->fd_max_size <<= 1;