Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 15.5% 11 / 0 / 71
Functions: 22.2% 2 / 0 / 9
Branches: 11.5% 3 / 0 / 26

OMCompiler/SimulationRuntime/c/util/omc_mmap.c
Line Branch Exec Source
1 /*
2 * This file belongs to the OpenModelica Run-Time System
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings
5 * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights
6 * reserved.
7 *
8 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE
9 * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY
10 * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
11 * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL
12 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
13 *
14 * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License
15 * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs:
16 * http://www.openmodelica.org or https://github.com/OpenModelica/ or
17 * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU
18 * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW
19 * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause.
20 *
21 * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY
23 * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF
24 * OSMC-PL.
25 *
26 */
27
28 #if !defined(OMC_NO_FILESYSTEM)
29
30 #include "omc_mmap.h"
31 #include "omc_error.h"
32 #include "omc_file.h"
33 #include <string.h>
34 #include <errno.h>
35
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39
40 #if HAVE_MMAP
41
42 1 omc_mmap_read_unix omc_mmap_open_read_unix(const char *fileName)
43 {
44 struct stat s;
45 omc_mmap_read_unix res = {0};
46 int fd = open(fileName, O_RDONLY);
47
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (fd < 0) {
48 ✗ throwStreamPrint(NULL, "Failed to open file %s for reading: %s\n", fileName, strerror(errno));
49 }
50
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if (fstat(fd, &s) < 0) {
51 ✗ close(fd);
52 ✗ throwStreamPrint(NULL, "fstat %s failed: %s\n", fileName, strerror(errno));
53 }
54 1 res.size = s.st_size;
55 1 res.data = (const char*) mmap(0, res.size, PROT_READ, MAP_SHARED, fd, 0);
56 1 close(fd);
57
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (res.data == MAP_FAILED) {
58 ✗ throwStreamPrint(NULL, "mmap(file=\"%s\",fd=%d,size=%ld kB) failed: %s\n", fileName, fd, (long) s.st_size, strerror(errno));
59 }
60 1 return res;
61 }
62
63 ✗ omc_mmap_write_unix omc_mmap_open_write_unix(const char *fileName, size_t size)
64 {
65 omc_mmap_write_unix res = {0};
66 int fd = open(fileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
67 ✗ if (fd < 0) {
68 ✗ throwStreamPrint(NULL, "Failed to open file %s for reading: %s\n", fileName, strerror(errno));
69 }
70 ✗ if (size == 0) {
71 struct stat s;
72 ✗ if (fstat(fd, &s) < 0) {
73 ✗ close(fd);
74 ✗ throwStreamPrint(NULL, "fstat %s failed: %s\n", fileName, strerror(errno));
75 }
76 ✗ res.size = s.st_size;
77 } else {
78 res.size = size;
79 ✗ lseek(fd, size, SEEK_SET);
80 }
81 ✗ res.data = res.size == 0 ? NULL : (char*) mmap(0, res.size, PROT_WRITE, MAP_SHARED, fd, 0);
82 ✗ close(fd);
83 ✗ if (res.data == MAP_FAILED) {
84 ✗ throwStreamPrint(NULL, "mmap(file=\"%s\",fd=%d,size=%ld kB) failed: %s\n", fileName, fd, (long) res.size, strerror(errno));
85 }
86 ✗ return res;
87 }
88
89 1 void omc_mmap_close_read_unix(omc_mmap_read_unix map)
90 {
91 1 munmap((void*)map.data, map.size);
92 1 }
93
94 ✗ void omc_mmap_close_write_unix(omc_mmap_write_unix map)
95 {
96 ✗ munmap((void*)map.data, map.size);
97 ✗ }
98
99 #endif /* HAVE_MMAP */
100
101 /**
102 * @brief Open and read file content into buffer.
103 *
104 * @param fileName Name of file to read.
105 * @param mode File access mode for `fopen`.
106 * @param size Size of data to read. If `0` use file size to update `size`.
107 * @param data Read file content into null terminated buffer.
108 * Allocates memory, needs to be freed with `free`.
109 * @return FILE* Pointer to open file stream. Needs to be closed with
110 * `omc_fclose`.
111 */
112 ✗ static FILE* omc_mmap_common(const char *fileName, const char *mode, size_t *size, char **data)
113 {
114 ✗ FILE *file = omc_fopen(fileName, mode);
115 size_t fileSize;
116 ✗ if (!file) {
117 ✗ throwStreamPrint(NULL, "Failed to open file %s for reading: %s\n", fileName, strerror(errno));
118 }
119
120 ✗ fseek(file, 0, SEEK_END);
121 ✗ fileSize = ftell(file);
122 ✗ rewind(file);
123
124 // Allocate +1 byte for null terminator
125 ✗ size_t allocSize = (*size > fileSize ? *size : fileSize) + 1;
126 ✗ if (*size == 0) {
127 ✗ *size = fileSize;
128 }
129 ✗ if (*size > fileSize) {
130 ✗ *data = (char*) calloc(*size + 1, sizeof(char));
131 } else {
132 ✗ *data = (char*) malloc((*size + 1) * sizeof(char));
133 }
134 ✗ if (!*data) {
135 ✗ omc_fclose(file);
136 ✗ throwStreamPrint(NULL, "Memory allocation failed for file %s\n", fileName);
137 }
138
139 ✗ size_t bytesToRead = (*size > fileSize ? fileSize : *size);
140 ✗ omc_fread(*data, bytesToRead, 1, file, 0);
141 ✗ (*data)[bytesToRead] = '\0';
142
143 ✗ return file;
144 }
145
146 ✗ omc_mmap_read_inmemory omc_mmap_open_read_inmemory(const char *fileName)
147 {
148 ✗ omc_mmap_read_inmemory res = {0};
149 res.size = 0;
150 ✗ fclose(omc_mmap_common(fileName, "rb", &res.size, (char**)&res.data));
151 ✗ return res;
152 }
153
154 ✗ omc_mmap_write_inmemory omc_mmap_open_write_inmemory(const char *fileName, size_t size)
155 {
156 ✗ omc_mmap_write_inmemory res = {0};
157 ✗ res.size = size;
158 ✗ res.file = omc_mmap_common(fileName, "rb+", &res.size, &res.data);
159 ✗ return res;
160 }
161
162 ✗ void omc_mmap_close_read_inmemory(omc_mmap_read_inmemory map)
163 {
164 ✗ free((void*)map.data);
165 ✗ }
166
167 ✗ void omc_mmap_close_write_inmemory(omc_mmap_write_inmemory map)
168 {
169 ✗ rewind(map.file);
170 ✗ if (1 != fwrite(map.data, map.size, 1, map.file)) {
171 ✗ free(map.data);
172 ✗ throwStreamPrint(NULL, "Failed to write back to file");
173 }
174 ✗ free((void*)map.data);
175 ✗ }
176
177
178 #ifdef __cplusplus
179 }
180 #endif
181
182 #endif /* OMC_NO_FILESYSTEM */
183