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