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 */
file_image_open(file_image * image,const char * filename)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 */
file_image_pagein(file_image * image)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 */
file_image_close(file_image * image)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