Add a 32 byte read buffer to read_line.

Do as with fdprintf and avoid filesystem calls for every single
byte. If it overreads, just put the excess back with lseek, which
does no I/O itself.

Change-Id: Ifd5d21b5dca7183346e44d365d3f7d45e8cc6438
This commit is contained in:
Michael Sevakis 2017-12-12 15:57:51 -05:00
parent cd3ea086ec
commit 838ff9c67d

View file

@ -1029,32 +1029,54 @@ int format_sound_value(char *buf, size_t size, int snd, int val)
*/
int read_line(int fd, char* buffer, int buffer_size)
{
if (!buffer || buffer_size-- <= 0)
{
errno = EINVAL;
return -1;
}
unsigned char rdbuf[32];
off_t rdbufend = 0;
int rdbufidx = 0;
int count = 0;
int num_read = 0;
errno = 0;
while (count < buffer_size)
{
unsigned char c;
if (rdbufidx >= rdbufend)
{
rdbufidx = 0;
rdbufend = read(fd, rdbuf, sizeof (rdbuf));
if (1 != read(fd, &c, 1))
if (rdbufend <= 0)
break;
num_read += rdbufend;
}
int c = rdbuf[rdbufidx++];
if (c == '\n')
break;
num_read++;
if ( c == '\n' )
break;
if ( c == '\r' )
if (c == '\r')
continue;
buffer[count++] = c;
}
buffer[MIN(count, buffer_size - 1)] = 0;
rdbufidx -= rdbufend;
return errno ? -1 : num_read;
if (rdbufidx < 0)
{
/* "put back" what wasn't read from the buffer */
num_read += rdbufidx;
rdbufend = lseek(fd, rdbufidx, SEEK_CUR);
}
buffer[count] = '\0';
return rdbufend >= 0 ? num_read : -1;
}