| 1125 | advance IN_STREAM. */ |
| 1126 | |
| 1127 | static bool |
| 1128 | skip (intmax_t n_skip) |
| 1129 | { |
| 1130 | bool ok = true; |
| 1131 | int in_errno = 0; |
| 1132 | |
| 1133 | if (n_skip == 0) |
| 1134 | return true; |
| 1135 | |
| 1136 | while (in_stream != NULL) /* EOF. */ |
| 1137 | { |
| 1138 | struct stat file_stats; |
| 1139 | |
| 1140 | /* First try seeking. For large offsets, this extra work is |
| 1141 | worthwhile. If the offset is below some threshold it may be |
| 1142 | more efficient to move the pointer by reading. There are two |
| 1143 | issues when trying to seek: |
| 1144 | - the file must be seekable. |
| 1145 | - before seeking to the specified position, make sure |
| 1146 | that the new position is in the current file. |
| 1147 | Try to do that by getting file's size using fstat. |
| 1148 | But that will work only for regular files. */ |
| 1149 | |
| 1150 | if (fstat (fileno (in_stream), &file_stats) == 0) |
| 1151 | { |
| 1152 | /* The st_size field is valid for regular files. |
| 1153 | If the number of bytes left to skip is larger than |
| 1154 | the size of the current file, we can decrement n_skip |
| 1155 | and go on to the next file. Skip this optimization also |
| 1156 | when st_size is no greater than the block size, because |
| 1157 | some kernels report nonsense small file sizes for |
| 1158 | proc-like file systems. */ |
| 1159 | if (S_ISREG (file_stats.st_mode) |
| 1160 | && STP_BLKSIZE (&file_stats) < file_stats.st_size) |
| 1161 | { |
| 1162 | if (file_stats.st_size < n_skip) |
| 1163 | n_skip -= file_stats.st_size; |
| 1164 | else |
| 1165 | { |
| 1166 | if (fseeko (in_stream, n_skip, SEEK_CUR) != 0) |
| 1167 | { |
| 1168 | in_errno = errno; |
| 1169 | ok = false; |
| 1170 | } |
| 1171 | n_skip = 0; |
| 1172 | } |
| 1173 | } |
| 1174 | |
| 1175 | else if (! (S_ISREG (file_stats.st_mode) |
| 1176 | || S_TYPEISSHM (&file_stats) |
| 1177 | || S_TYPEISTMO (&file_stats)) |
| 1178 | && fseeko (in_stream, n_skip, SEEK_CUR) == 0) |
| 1179 | n_skip = 0; |
| 1180 | |
| 1181 | /* If it's neither a seekable file with unusable size, nor a |
| 1182 | regular file so large it can't be in a proc-like file system, |
| 1183 | position the file pointer by reading. */ |
| 1184 |
no test coverage detected