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