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:
parent
cd3ea086ec
commit
838ff9c67d
1 changed files with 34 additions and 12 deletions
46
apps/misc.c
46
apps/misc.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue