1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "file_image.h" 29 30 #include <unistd.h> 31 32 #include <errno.h> 33 #include <fcntl.h> 34 35 #if defined(LINUX) 36 # ifndef __USE_BSD 37 # define __USE_BSD /* madvise, MADV_WILLNEED */ 38 # endif 39 #endif /* Linux */ 40 41 #include <sys/mman.h> 42 #include <sys/stat.h> 43 44 #include <string.h> 45 46 /* 47 * file_image_open 48 */ 49 int file_image_open (file_image * image, const char * filename) 50 { 51 int result = 0; 52 int fd; 53 struct stat st; 54 void * p; 55 56 if (image == 0) 57 return (EINVAL); 58 59 image->m_base = MAP_FAILED, image->m_size = 0; 60 61 if ((fd = open (filename, O_RDONLY)) == -1) 62 return (errno); 63 64 if (fstat (fd, &st) == -1) 65 { 66 result = errno; 67 goto cleanup_and_leave; 68 } 69 70 p = mmap (0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 71 if (p == MAP_FAILED) 72 { 73 result = errno; 74 goto cleanup_and_leave; 75 } 76 77 image->m_base = p, image->m_size = st.st_size; 78 79 cleanup_and_leave: 80 close (fd); 81 return (result); 82 } 83 84 /* 85 * file_image_pagein. 86 */ 87 int file_image_pagein (file_image * image) 88 { 89 file_image w; 90 long s; 91 size_t k; 92 volatile char c = 0; 93 94 if (image == 0) 95 return (EINVAL); 96 97 if ((w.m_base = image->m_base) == 0) 98 return (EINVAL); 99 if ((w.m_size = image->m_size) == 0) 100 return (0); 101 102 if (madvise (w.m_base, w.m_size, MADV_WILLNEED) == -1) 103 { 104 #ifndef MACOSX 105 return (errno); 106 #else 107 /* madvise MADV_WILLNEED need not succeed here */ 108 /* but that is fine */ 109 #endif 110 } 111 112 113 #ifndef MACOSX 114 if ((s = sysconf (_SC_PAGESIZE)) == -1) 115 s = 0x1000; 116 #else 117 s = getpagesize(); 118 #endif 119 120 k = (size_t)(s); 121 while (w.m_size > k) 122 { 123 c ^= ((char*)(w.m_base))[0]; 124 w.m_base = (char*)(w.m_base) + k; 125 w.m_size -= k; 126 } 127 if (w.m_size > 0) 128 { 129 c ^= ((char*)(w.m_base))[0]; 130 w.m_base = (char*)(w.m_base) + w.m_size; 131 w.m_size -= w.m_size; 132 } 133 134 return (0); 135 } 136 137 /* 138 * file_image_close 139 */ 140 int file_image_close (file_image * image) 141 { 142 if (image == 0) 143 return (EINVAL); 144 145 if (munmap (image->m_base, image->m_size) == -1) 146 return (errno); 147 148 image->m_base = 0, image->m_size = 0; 149 return (0); 150 } 151