| 939 | if a line is so long as to completely overlap the partition. */ |
| 940 | |
| 941 | static void |
| 942 | lines_chunk_split (intmax_t k, intmax_t n, char *buf, idx_t bufsize, |
| 943 | ssize_t initial_read, off_t file_size) |
| 944 | { |
| 945 | affirm (n && k <= n); |
| 946 | |
| 947 | intmax_t rem_bytes = file_size % n; |
| 948 | off_t chunk_size = file_size / n; |
| 949 | intmax_t chunk_no = 1; |
| 950 | off_t chunk_end = chunk_size + (0 < rem_bytes); |
| 951 | off_t n_written = 0; |
| 952 | bool new_file_flag = true; |
| 953 | bool chunk_truncated = false; |
| 954 | |
| 955 | if (k > 1 && 0 < file_size) |
| 956 | { |
| 957 | /* Start reading 1 byte before kth chunk of file. */ |
| 958 | off_t start = (k - 1) * chunk_size + MIN (k - 1, rem_bytes) - 1; |
| 959 | if (start < initial_read) |
| 960 | { |
| 961 | memmove (buf, buf + start, initial_read - start); |
| 962 | initial_read -= start; |
| 963 | } |
| 964 | else |
| 965 | { |
| 966 | if (initial_read < start |
| 967 | && lseek (STDIN_FILENO, start - initial_read, SEEK_CUR) < 0) |
| 968 | error (EXIT_FAILURE, errno, "%s", quotef (infile)); |
| 969 | initial_read = -1; |
| 970 | } |
| 971 | n_written = start; |
| 972 | chunk_no = k - 1; |
| 973 | chunk_end = start + 1; |
| 974 | } |
| 975 | |
| 976 | while (n_written < file_size) |
| 977 | { |
| 978 | char *bp = buf, *eob; |
| 979 | ssize_t n_read; |
| 980 | if (0 <= initial_read) |
| 981 | { |
| 982 | n_read = initial_read; |
| 983 | initial_read = -1; |
| 984 | } |
| 985 | else |
| 986 | { |
| 987 | n_read = read (STDIN_FILENO, buf, |
| 988 | MIN (bufsize, file_size - n_written)); |
| 989 | if (n_read < 0) |
| 990 | error (EXIT_FAILURE, errno, "%s", quotef (infile)); |
| 991 | } |
| 992 | if (n_read == 0) |
| 993 | break; /* eof. */ |
| 994 | chunk_truncated = false; |
| 995 | eob = buf + n_read; |
| 996 | |
| 997 | while (bp != eob) |
| 998 | { |
no test coverage detected