TARFS 0.1.5
Read-only TAR filesystem for ESP32
Loading...
Searching...
No Matches
posix.c
Go to the documentation of this file.
1/*
2 * TARFS - Immutable (read-only) filesystem for embedded systems.
3 *
4 * Copyright (c) 2026 Viacheslav Logunov
5 * SPDX-License-Identifier: MMIT
6 *
7 * Author:
8 * Viacheslav Logunov <vvb333007@gmail.com>
9 *
10 * Project:
11 * https://github.com/vvb333007/tarfs
12 *
13 *
14 * @file posix.c
15 * @brief Missing POSIX API implementation
16 */
17
18
23
24
25#include <stdint.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <stdbool.h>
29#include <stdatomic.h>
30
31#include <unistd.h>
32#include <dirent.h>
33#include <sys/errno.h>
34#include <sys/ioctl.h>
35#include <sys/socket.h>
36#include <sys/types.h>
37
38
39#include "config.h"
40#include "os.h"
41#include "fs.h"
42#include "file.h"
43#include "inode.h"
44#include "tar.h"
45#include "dir.h"
46#include "posix.h"
47
48
49#if CONFIG_TARFS_HAVE_MMAP
54void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) {
55
56 struct ioctl_req io;
57
58 /* FIOGETFD returns the FS index and local fd, suitable for tarf_ , tard_ functions */
59 if ((ioctl(fd, FIOGETFD, &io) >= 0))
60 return tarf_mmap((void *)(uintptr_t)io.fs_idx, addr, length, prot, flags, io.fd, offset);
61
62 /*errno should be set by the ioctl() */
63 return MAP_FAILED;
64
65}
66
67
72int munmap(void *addr, size_t length) {
73
74 struct tarfs_fs *fs;
75 uintptr_t vaddr = (uintptr_t )addr;
76
77 if (addr != NULL && length > 0) {
78 tarfs_lock();
79 for (int i = 0; i < TARFS_MAX_FS; i++) {
80
81 fs = tarfs_getfs(i);
82
83 if (fs != NULL &&
84 vaddr >= (uintptr_t)fs->fs_vaddr &&
85 vaddr < ((uintptr_t)fs->fs_vaddr + fs->fs_size)) {
87 return tarf_munmap((void *)(uintptr_t )i, addr, length);
88 }
89 }
90 }
91 log("address %p does not belong to mmap()\r\n", addr);
92 errno = EINVAL;
93 return -1;
94}
95#endif /* CONFIG_TARFS_HAVE_MMAP */
96
97
98
99#if CONFIG_TARFS_HAVE_DUPFD
107int dupfd(int fd) {
108
109 struct ioctl_req io;
110
111 /* FIOGETFD returns the FS index and local fd, suitable for tarf_ , tard_ functions */
112 if ((ioctl(fd, FIOGETFD, &io) >= 0)) {
113 /* TODO: this is bad, but ESP-IDF has no mechanism to convert local to global */
114 int fd_offset = fd - io.fd;
115 return fd_offset + tarf_dupfd((void *)(uintptr_t)io.fs_idx, io.fd);
116 }
117
118 /*errno should be set by the ioctl() */
119 return -1;
120}
121#endif /* CONFIG_TARFS_HAVE_DUPFD */
122
123
124#if CONFIG_TARFS_HAVE_FDOPENDIR
133DIR *fdopendir(int fd) {
134
135
136 struct ioctl_req io;
137
138 /* Convert our global fd to local fd number so tarf_ and tard_ functions can be used
139 * FIOGETFD returns the FS index and local fd
140 */
141 if (ioctl(fd, FIOGETFD, &io) >= 0)
142 return tard_fdopendir((void *)(uintptr_t)io.fs_idx, io.fd);
143
144 return NULL;
145}
146#endif /* CONFIG_TARFS_HAVE_FDOPENDIR */
147
148
149
150#if CONFIG_TARFS_HAVE_STATVFS
163int statvfs(const char *path, struct statvfs *st) {
164
165 int fs_idx;
166
167 if ((fs_idx = tarfs_fsindex(path)) >= 0)
168 return tarfs_statvfs((void *)(intptr_t)fs_idx, st);
169
170 errno = ENODEV;
171 return -1;
172}
173#endif /* CONFIG_TARFS_HAVE_STATVFS */
174
175
176#if CONFIG_TARFS_HAVE_SENDFILE
177
196ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
197
198 struct ioctl_req io;
199
200 /* Convert our global fd to local fd number so tarf_ and tard_ functions can be used
201 * FIOGETFD returns the FS index and local fd
202 */
203 if (ioctl(in_fd, FIOGETFD, &io) >= 0)
204 return tarf_sendfile((void *)(uintptr_t)io.fs_idx, out_fd, io.fd, offset, count);
205
206 /*errno should be set by the ioctl() */
207 return -1;
208}
209#endif /* #if CONFIG_TARFS_HAVE_SENDFILE */
210
211/* TODO: implement lstat*/
DIR * tard_fdopendir(void *ctx, int fd)
Associate an open directory file descriptor with a directory stream.
Definition dir.c:166
ssize_t tarf_sendfile(void *ctx, int sock, int fd, off_t *offset, size_t count)
Copy data from a TARFS file descriptor to a socket.
Definition file.c:926
void * tarf_mmap(void *ctx, void *addr, size_t length, int prot, int flags, int fd, off_t offset)
Mimics POSIX mmap().
Definition file.c:846
int tarf_dupfd(void *ctx, int fd)
Create an independent duplicate of a file descriptor.
Definition file.c:817
int tarf_munmap(void *ctx, void *addr, size_t length)
munmap().
Definition file.c:898
int tarfs_statvfs(void *ctx, struct statvfs *st)
Obtain filesystem statistics.
Definition fs.c:686
int tarfs_fsindex(const char *path)
Find the filesystem responsible for a given path.
Definition fs.c:147
struct tarfs_fs * tarfs_getfs(int i)
Lockless, not thread safe, does not increase refcounters.
Definition fs.c:54
#define TARFS_MAX_FS
Definition fs.h:29
#define FIOGETFD
Definition fs.h:47
static void tarfs_unlock()
Definition fs.h:422
static void tarfs_lock()
Platform abstraction helpers.
Definition fs.h:421
#define log(Format_,...)
Definition fs.h:445
int munmap(void *addr, size_t length)
POSIX munmap().
Definition posix.c:72
int statvfs(const char *path, struct statvfs *st)
Obtain filesystem statistics.
Definition posix.c:163
void * mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
Subset of POSIX functions.
Definition posix.c:54
DIR * fdopendir(int fd)
Associate an open directory file descriptor with a directory stream.
Definition posix.c:133
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
Zero-overhead, no-buffer file-to-socket tranfer.
Definition posix.c:196
int dupfd(int fd)
Create an independent duplicate of a file descriptor.
Definition posix.c:107
#define MAP_FAILED
Definition posix.h:41
Return/Request argument for FIOGETFD ioctl.
Definition fs.h:59
int fs_idx
Definition fs.h:60
int fd
Definition fs.h:61
The statvfs structure for systems without it (e.g.
Definition fs.h:142
This descriptor holds all file descriptors opened.
Definition fs.h:94
void const * fs_vaddr
Definition fs.h:98
size_t fs_size
Definition fs.h:100