| 2083 | /* The main loop. */ |
| 2084 | |
| 2085 | static int |
| 2086 | dd_copy (void) |
| 2087 | { |
| 2088 | char *bufstart; /* Input buffer. */ |
| 2089 | ssize_t nread; /* Bytes read in the current block. */ |
| 2090 | |
| 2091 | /* If nonzero, then the previously read block was partial and |
| 2092 | PARTREAD was its size. */ |
| 2093 | idx_t partread = 0; |
| 2094 | |
| 2095 | int exit_status = EXIT_SUCCESS; |
| 2096 | idx_t n_bytes_read; |
| 2097 | |
| 2098 | if (skip_records != 0 || skip_bytes != 0) |
| 2099 | { |
| 2100 | intmax_t us_bytes; |
| 2101 | bool us_bytes_overflow = |
| 2102 | (ckd_mul (&us_bytes, skip_records, input_blocksize) |
| 2103 | || ckd_add (&us_bytes, skip_bytes, us_bytes)); |
| 2104 | off_t input_offset0 = input_offset; |
| 2105 | intmax_t us_blocks = skip (STDIN_FILENO, input_file, |
| 2106 | skip_records, input_blocksize, &skip_bytes); |
| 2107 | |
| 2108 | /* POSIX doesn't say what to do when dd detects it has been |
| 2109 | asked to skip past EOF, so I assume it's non-fatal. |
| 2110 | There are 3 reasons why there might be unskipped blocks/bytes: |
| 2111 | 1. file is too small |
| 2112 | 2. pipe has not enough data |
| 2113 | 3. partial reads */ |
| 2114 | if ((us_blocks |
| 2115 | || (0 <= input_offset |
| 2116 | && (us_bytes_overflow |
| 2117 | || us_bytes != input_offset - input_offset0))) |
| 2118 | && status_level != STATUS_NONE) |
| 2119 | { |
| 2120 | diagnose (0, _("%s: cannot skip to specified offset"), |
| 2121 | quotef (input_file)); |
| 2122 | } |
| 2123 | } |
| 2124 | |
| 2125 | if (seek_records != 0 || seek_bytes != 0) |
| 2126 | { |
| 2127 | idx_t bytes = seek_bytes; |
| 2128 | intmax_t write_records = skip (STDOUT_FILENO, output_file, |
| 2129 | seek_records, output_blocksize, &bytes); |
| 2130 | |
| 2131 | if (write_records != 0 || bytes != 0) |
| 2132 | { |
| 2133 | memset (obuf, 0, write_records ? output_blocksize : bytes); |
| 2134 | |
| 2135 | do |
| 2136 | { |
| 2137 | idx_t size = write_records ? output_blocksize : bytes; |
| 2138 | if (iwrite (STDOUT_FILENO, obuf, size) != size) |
| 2139 | { |
| 2140 | diagnose (errno, _("writing to %s"), quoteaf (output_file)); |
| 2141 | quit (EXIT_FAILURE); |
| 2142 | } |
no test coverage detected