Read a line into the "buf" buffer. */
| 1241 | |
| 1242 | /* Read a line into the "buf" buffer. */ |
| 1243 | int read_line(int fd, char *buf, size_t bufsiz, int flags) |
| 1244 | { |
| 1245 | char ch, *s, *eob; |
| 1246 | |
| 1247 | #ifdef ICONV_OPTION |
| 1248 | if (flags & RL_CONVERT && iconv_buf.size < bufsiz) |
| 1249 | realloc_xbuf(&iconv_buf, ROUND_UP_1024(bufsiz) + 1024); |
| 1250 | #endif |
| 1251 | |
| 1252 | start: |
| 1253 | #ifdef ICONV_OPTION |
| 1254 | s = flags & RL_CONVERT ? iconv_buf.buf : buf; |
| 1255 | #else |
| 1256 | s = buf; |
| 1257 | #endif |
| 1258 | eob = s + bufsiz - 1; |
| 1259 | while (1) { |
| 1260 | /* We avoid read_byte() for files because files can return an EOF. */ |
| 1261 | if (fd == iobuf.in_fd) |
| 1262 | ch = read_byte(fd); |
| 1263 | else if (safe_read(fd, &ch, 1) == 0) |
| 1264 | break; |
| 1265 | if (flags & RL_EOL_NULLS ? ch == '\0' : (ch == '\r' || ch == '\n')) { |
| 1266 | /* Skip empty lines if dumping comments. */ |
| 1267 | if (flags & RL_DUMP_COMMENTS && s == buf) |
| 1268 | continue; |
| 1269 | break; |
| 1270 | } |
| 1271 | if (s < eob) |
| 1272 | *s++ = ch; |
| 1273 | } |
| 1274 | *s = '\0'; |
| 1275 | |
| 1276 | if (flags & RL_DUMP_COMMENTS && (*buf == '#' || *buf == ';')) |
| 1277 | goto start; |
| 1278 | |
| 1279 | #ifdef ICONV_OPTION |
| 1280 | if (flags & RL_CONVERT) { |
| 1281 | xbuf outbuf; |
| 1282 | INIT_XBUF(outbuf, buf, 0, bufsiz); |
| 1283 | iconv_buf.pos = 0; |
| 1284 | iconv_buf.len = s - iconv_buf.buf; |
| 1285 | iconvbufs(ic_recv, &iconv_buf, &outbuf, |
| 1286 | ICB_INCLUDE_BAD | ICB_INCLUDE_INCOMPLETE | ICB_INIT); |
| 1287 | outbuf.buf[outbuf.len] = '\0'; |
| 1288 | return outbuf.len; |
| 1289 | } |
| 1290 | #endif |
| 1291 | |
| 1292 | return s - buf; |
| 1293 | } |
| 1294 | |
| 1295 | /* Reverse safe_arg()'s backslash escaping of a daemon option arg, the way a |
| 1296 | * remote shell un-escapes args for the ssh transport. In place; \X -> X. */ |
no test coverage detected