summaryrefslogtreecommitdiff
path: root/apps/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/misc.c')
-rw-r--r--apps/misc.c42
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 */
1030int read_line(int fd, char* buffer, int buffer_size) 1030int 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