1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "file_image.h" 25 26 #include <unistd.h> 27 28 #include <errno.h> 29 #include <fcntl.h> 30 31 #if defined(LINUX) 32 # ifndef __USE_BSD 33 # define __USE_BSD /* madvise, MADV_WILLNEED */ 34 # endif 35 #endif /* Linux */ 36 37 #include <sys/mman.h> 38 #include <sys/stat.h> 39 40 #include <string.h> 41 42 /* 43 * file_image_open 44 */ 45 int file_image_open (file_image * image, const char * filename) 46 { 47 int result = 0; 48 int fd; 49 struct stat st; 50 void * p; 51 52 if (image == 0) 53 return (EINVAL); 54 55 image->m_base = MAP_FAILED, image->m_size = 0; 56 57 if ((fd = open (filename, O_RDONLY)) == -1) 58 return (errno); 59 60 if (fstat (fd, &st) == -1) 61 { 62 result = errno; 63 goto cleanup_and_leave; 64 } 65 66 p = mmap (0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 67 if (p == MAP_FAILED) 68 { 69 result = errno; 70 goto cleanup_and_leave; 71 } 72 73 image->m_base = p, image->m_size = st.st_size; 74 75 cleanup_and_leave: 76 close (fd); 77 return (result); 78 } 79 80 /* 81 * file_image_pagein. 82 */ 83 int file_image_pagein (file_image * image) 84 { 85 file_image w; 86 long s; 87 size_t k; 88 volatile char c = 0; 89 90 if (image == 0) 91 return (EINVAL); 92 93 if ((w.m_base = image->m_base) == 0) 94 return (EINVAL); 95 if ((w.m_size = image->m_size) == 0) 96 return (0); 97 98 if (madvise (w.m_base, w.m_size, MADV_WILLNEED) == -1) 99 { 100 #ifndef MACOSX 101 return (errno); 102 #else 103 /* madvise MADV_WILLNEED need not succeed here */ 104 /* but that is fine */ 105 #endif 106 } 107 108 109 #ifndef MACOSX 110 if ((s = sysconf (_SC_PAGESIZE)) == -1) 111 s = 0x1000; 112 #else 113 s = getpagesize(); 114 #endif 115 116 k = (size_t)(s); 117 while (w.m_size > k) 118 { 119 c ^= ((char*)(w.m_base))[0]; 120 w.m_base = (char*)(w.m_base) + k; 121 w.m_size -= k; 122 } 123 if (w.m_size > 0) 124 { 125 c ^= ((char*)(w.m_base))[0]; 126 w.m_base = (char*)(w.m_base) + w.m_size; 127 w.m_size -= w.m_size; 128 } 129 130 return (0); 131 } 132 133 /* 134 * file_image_close 135 */ 136 int file_image_close (file_image * image) 137 { 138 if (image == 0) 139 return (EINVAL); 140 141 if (munmap (image->m_base, image->m_size) == -1) 142 return (errno); 143 144 image->m_base = 0, image->m_size = 0; 145 return (0); 146 } 147