LexLeo 0.0.0-dev+f8e5087-dirty
Technical documentation
Loading...
Searching...
No Matches
osal_file_posix.c
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-3.0-or-later
2 * Copyright (C) 2026 Sylvain Labopin
3 */
4
23#include "internal/osal_file_internal.h"
24
25#include "osal/file/osal_file_ops.h"
26
28#include "osal/mem/osal_mem.h"
29
34
48{
49 switch (errnum) {
50 case 0:
52
53#ifdef EINVAL
54 case EINVAL:
56#endif
57
58#ifdef ENOENT
59 case ENOENT:
61#endif
62
63#ifdef EACCES
64 case EACCES:
66#endif
67
68#ifdef EPERM
69 case EPERM:
71#endif
72
73#ifdef EEXIST
74 case EEXIST:
76#endif
77
78#ifdef ENOSPC
79 case ENOSPC:
81#endif
82
83#ifdef ENAMETOOLONG
84 case ENAMETOOLONG:
86#endif
87
88#ifdef ENOTDIR
89 case ENOTDIR:
91#endif
92
93#ifdef EISDIR
94 case EISDIR:
96#endif
97
98#ifdef EBADF
99 case EBADF:
101#endif
102
103#ifdef EFBIG
104 case EFBIG:
106#endif
107
108#ifdef EINTR
109 case EINTR:
111#endif
112
113#ifdef EMFILE
114 case EMFILE:
116#endif
117
118#ifdef ENFILE
119 case ENFILE:
121#endif
122
123#ifdef ELOOP
124 case ELOOP:
126#endif
127
128#ifdef EROFS
129 case EROFS:
131#endif
132
133#ifdef ESPIPE
134 case ESPIPE:
136#endif
137
138#ifdef EXDEV
139 case EXDEV:
141#endif
142
143#ifdef ENODEV
144 case ENODEV:
146#endif
147
148#ifdef ENXIO
149 case ENXIO:
151#endif
152
153#ifdef ESTALE
154 case ESTALE:
156#endif
157
158#ifdef ENOMEM
159 case ENOMEM:
161#endif
162
163 default:
164 return OSAL_FILE_STATUS_IO;
165 }
166}
167
191 OSAL_FILE **out,
192 const char *pathname,
193 const char *mode,
194 const osal_mem_ops_t *mem_ops
195) {
196 if (
197 !out
198 || !pathname
199 || pathname[0] == '\0'
200 || !mode
201 || (
202 osal_strcmp(mode, "rb") != 0
203 && osal_strcmp(mode, "wb") != 0
204 && osal_strcmp(mode, "ab") != 0)
205 || !mem_ops
206 ) {
208 }
209
211 mem_ops->malloc
212 && mem_ops->free
213 );
214
215 OSAL_FILE *tmp = mem_ops->malloc(sizeof(*tmp));
216 if (!tmp)
218
219 tmp->mem_ops = mem_ops;
220
221 FILE *fp = fopen(pathname, mode);
222 if (!fp) {
223 mem_ops->free(tmp);
224 return osal_file_map_errno(errno);
225 }
226
227 tmp->fp = fp;
228
229 *out = tmp;
230
231 return OSAL_FILE_STATUS_OK;
232}
233
259static size_t osal_file_read(
260 void *ptr,
261 size_t size,
262 size_t nmemb,
263 OSAL_FILE *stream,
265) {
266 if (
267 !ptr
268 || !st
269 || !stream
270 || !stream->fp
271 ) {
272 if (st) *st = OSAL_FILE_STATUS_INVALID;
273 return 0;
274 }
275
277
278 size_t ret = fread(ptr, size, nmemb, stream->fp);
279
280 if (ret < nmemb && ferror(stream->fp)) {
281 *st = osal_file_map_errno(errno);
282 }
283
284 return ret;
285}
286
312static size_t osal_file_write(
313 const void *ptr,
314 size_t size,
315 size_t nmemb,
316 OSAL_FILE *stream,
318) {
319 if (
320 !ptr
321 || !st
322 || !stream
323 || !stream->fp
324 ) {
325 if (st) *st = OSAL_FILE_STATUS_INVALID;
326 return 0;
327 }
328
330
331 size_t ret = fwrite(ptr, size, nmemb, stream->fp);
332
333 if (ret < nmemb && ferror(stream->fp)) {
334 *st = osal_file_map_errno(errno);
335 }
336
337 return ret;
338}
339
354{
355 if (!stream || !stream->fp) {
357 }
358
359 if (fflush(stream->fp) != 0) {
360 return osal_file_map_errno(errno);
361 }
362
363 return OSAL_FILE_STATUS_OK;
364}
365
380{
381 if (!stream || !stream->fp) {
383 }
384
385 if (fclose(stream->fp) != 0) {
386 return osal_file_map_errno(errno);
387 }
388
389 LEXLEO_ASSERT(stream->mem_ops && stream->mem_ops->free);
390 stream->mem_ops->free(stream);
391
392 return OSAL_FILE_STATUS_OK;
393}
394
402{
403 static const osal_file_ops_t osal_file_ops = {
405 .read = osal_file_read,
406 .write = osal_file_write,
407 .close = osal_file_close,
408 .flush = osal_file_flush,
409 };
410 return &osal_file_ops;
411}
@ OSAL_FILE_STATUS_EXISTS
@ OSAL_FILE_STATUS_OOM
@ OSAL_FILE_STATUS_OK
@ OSAL_FILE_STATUS_BADF
@ OSAL_FILE_STATUS_STALE
@ OSAL_FILE_STATUS_IO
@ OSAL_FILE_STATUS_LOOP
@ OSAL_FILE_STATUS_INTR
@ OSAL_FILE_STATUS_NAMETOOLONG
@ OSAL_FILE_STATUS_NODEV
@ OSAL_FILE_STATUS_NOENT
@ OSAL_FILE_STATUS_INVALID
@ OSAL_FILE_STATUS_NFILE
@ OSAL_FILE_STATUS_MFILE
@ OSAL_FILE_STATUS_SPIPE
@ OSAL_FILE_STATUS_PERM
@ OSAL_FILE_STATUS_FBIG
@ OSAL_FILE_STATUS_ISDIR
@ OSAL_FILE_STATUS_ROFS
@ OSAL_FILE_STATUS_NOSPC
@ OSAL_FILE_STATUS_XDEV
@ OSAL_FILE_STATUS_NOTDIR
@ OSAL_FILE_STATUS_NXIO
osal_file_status_t
#define LEXLEO_ASSERT(expr)
int osal_strcmp(const char *s1, const char *s2)
Definition osal_mem.c:40
static size_t osal_file_read(void *ptr, size_t size, size_t nmemb, OSAL_FILE *stream, osal_file_status_t *st)
Read elements from an open OSAL_FILE.
static size_t osal_file_write(const void *ptr, size_t size, size_t nmemb, OSAL_FILE *stream, osal_file_status_t *st)
Write elements to an open OSAL_FILE.
static osal_file_status_t osal_file_map_errno(int errnum)
Map a platform errno value to an osal_file_status_t.
static osal_file_status_t osal_file_close(OSAL_FILE *stream)
Close an open OSAL_FILE and release its associated wrapper.
const osal_file_ops_t * osal_file_default_ops(void)
Return the default POSIX / C stdio OSAL file operations table.
static osal_file_status_t osal_file_open(OSAL_FILE **out, const char *pathname, const char *mode, const osal_mem_ops_t *mem_ops)
Open a file resource through the POSIX / C stdio backend.
static osal_file_status_t osal_file_flush(OSAL_FILE *stream)
Flush buffered output associated with an open OSAL_FILE.
Private representation of an acquired OSAL file handle.
FILE * fp
Underlying C standard I/O file handle.
const osal_mem_ops_t * mem_ops
Memory operations table used to release this wrapper.
Operations table for the low-level OSAL file abstraction.
osal_file_status_t(* open)(OSAL_FILE **out, const char *pathname, const char *mode, const osal_mem_ops_t *mem_ops)
Open a file resource.
void *(* malloc)(size_t size)
void(* free)(void *ptr)