| 1025 | Return false on failure, with errno set. */ |
| 1026 | |
| 1027 | static bool |
| 1028 | invalidate_cache (int fd, off_t len) |
| 1029 | { |
| 1030 | int adv_ret = -1; |
| 1031 | off_t offset; |
| 1032 | bool nocache_eof = (fd == STDIN_FILENO ? i_nocache_eof : o_nocache_eof); |
| 1033 | |
| 1034 | /* Minimize syscalls. */ |
| 1035 | off_t clen = cache_round (fd, len); |
| 1036 | if (len && !clen) |
| 1037 | return true; /* Don't advise this time. */ |
| 1038 | else if (! len && ! clen && ! nocache_eof) |
| 1039 | return true; |
| 1040 | off_t pending = len ? cache_round (fd, 0) : 0; |
| 1041 | |
| 1042 | if (fd == STDIN_FILENO) |
| 1043 | { |
| 1044 | if (input_seekable) |
| 1045 | offset = input_offset; |
| 1046 | else |
| 1047 | { |
| 1048 | offset = -1; |
| 1049 | errno = ESPIPE; |
| 1050 | } |
| 1051 | } |
| 1052 | else |
| 1053 | { |
| 1054 | static off_t output_offset = -2; |
| 1055 | |
| 1056 | if (output_offset != -1) |
| 1057 | { |
| 1058 | if (output_offset < 0) |
| 1059 | output_offset = lseek (fd, 0, SEEK_CUR); |
| 1060 | else if (len) |
| 1061 | output_offset += clen + pending; |
| 1062 | } |
| 1063 | |
| 1064 | offset = output_offset; |
| 1065 | } |
| 1066 | |
| 1067 | if (0 <= offset) |
| 1068 | { |
| 1069 | if (! len && clen && nocache_eof) |
| 1070 | { |
| 1071 | pending = clen; |
| 1072 | clen = 0; |
| 1073 | } |
| 1074 | |
| 1075 | /* Note we're being careful here to only invalidate what |
| 1076 | we've read, so as not to dump any read ahead cache. |
| 1077 | Note also the kernel is conservative and only invalidates |
| 1078 | full pages in the specified range. */ |
| 1079 | #if HAVE_POSIX_FADVISE |
| 1080 | offset = offset - clen - pending; |
| 1081 | /* ensure full page specified when invalidating to eof. */ |
| 1082 | if (clen == 0) |
| 1083 | offset -= offset % page_size; |
| 1084 | adv_ret = posix_fadvise (fd, offset, clen, POSIX_FADV_DONTNEED); |
no test coverage detected