diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2017-12-12 15:57:51 -0500 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2017-12-12 15:57:51 -0500 |
commit | 838ff9c67d4ade0e0e0ee7132eb933a7c861d384 (patch) | |
tree | 8013402e9bb89e342ef2d7545df1b0aacc40b547 | |
parent | cd3ea086ec3db709c6682d85f8a97b96646cbb4f (diff) | |
download | rockbox-838ff9c67d4ade0e0e0ee7132eb933a7c861d384.tar.gz rockbox-838ff9c67d4ade0e0e0ee7132eb933a7c861d384.zip |
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
-rw-r--r-- | apps/misc.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/apps/misc.c b/apps/misc.c index 047098556f..477efc6313 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -1029,32 +1029,54 @@ int format_sound_value(char *buf, size_t size, int snd, int val) | |||
1029 | */ | 1029 | */ |
1030 | int read_line(int fd, char* buffer, int buffer_size) | 1030 | int read_line(int fd, char* buffer, int buffer_size) |
1031 | { | 1031 | { |
1032 | if (!buffer || buffer_size-- <= 0) | ||
1033 | { | ||
1034 | errno = EINVAL; | ||
1035 | return -1; | ||
1036 | } | ||
1037 | |||
1038 | unsigned char rdbuf[32]; | ||
1039 | off_t rdbufend = 0; | ||
1040 | int rdbufidx = 0; | ||
1032 | int count = 0; | 1041 | int count = 0; |
1033 | int num_read = 0; | 1042 | int num_read = 0; |
1034 | 1043 | ||
1035 | errno = 0; | ||
1036 | |||
1037 | while (count < buffer_size) | 1044 | while (count < buffer_size) |
1038 | { | 1045 | { |
1039 | unsigned char c; | 1046 | if (rdbufidx >= rdbufend) |
1047 | { | ||
1048 | rdbufidx = 0; | ||
1049 | rdbufend = read(fd, rdbuf, sizeof (rdbuf)); | ||
1040 | 1050 | ||
1041 | if (1 != read(fd, &c, 1)) | 1051 | if (rdbufend <= 0) |
1042 | break; | 1052 | break; |
1043 | 1053 | ||
1044 | num_read++; | 1054 | num_read += rdbufend; |
1055 | } | ||
1056 | |||
1057 | int c = rdbuf[rdbufidx++]; | ||
1045 | 1058 | ||
1046 | if ( c == '\n' ) | 1059 | if (c == '\n') |
1047 | break; | 1060 | break; |
1048 | 1061 | ||
1049 | if ( c == '\r' ) | 1062 | if (c == '\r') |
1050 | continue; | 1063 | continue; |
1051 | 1064 | ||
1052 | buffer[count++] = c; | 1065 | buffer[count++] = c; |
1053 | } | 1066 | } |
1054 | 1067 | ||
1055 | buffer[MIN(count, buffer_size - 1)] = 0; | 1068 | rdbufidx -= rdbufend; |
1069 | |||
1070 | if (rdbufidx < 0) | ||
1071 | { | ||
1072 | /* "put back" what wasn't read from the buffer */ | ||
1073 | num_read += rdbufidx; | ||
1074 | rdbufend = lseek(fd, rdbufidx, SEEK_CUR); | ||
1075 | } | ||
1076 | |||
1077 | buffer[count] = '\0'; | ||
1056 | 1078 | ||
1057 | return errno ? -1 : num_read; | 1079 | return rdbufend >= 0 ? num_read : -1; |
1058 | } | 1080 | } |
1059 | 1081 | ||
1060 | 1082 | ||