25#include <sys/dirent.h>
78 struct tarfs_inode const *di_ino;
79 struct tarfs_inode const *di_cino;
86 const char *text = path;
88 while(*text && *text !=
'\r' && *text !=
'\n' &&
89 *subpath && *subpath !=
'\r' && *subpath !=
'\n' &&
95 if (*subpath != 0 && *subpath !=
'\r' && *subpath !=
'\n')
110 ((atomic_load_explicit(&fs->fs_usedfd, memory_order_relaxed) & (1u << fd)) != 0);
133 if (*tail ==
'\0' || *tail ==
'\r' || *tail ==
'\n')
141 if (*tail ==
'\0' || *tail ==
'\r' || *tail ==
'\n')
147 slash = strchr(tail,
'/');
154 return slash[1] ==
'\0' || slash[1] ==
'\r' || slash[1] ==
'\n';
168 struct tarfs_dir *dir;
174 log(
"filesystem %d has gone, fd == %d is dead\r\n", (
int)(uintptr_t)ctx, fd);
183 log(
"fd == %d is dead\r\n", fd);
199 dir->di_cino = dir->di_ino;
203 dir->di_prefix =
tar_strdup1((
const char *)dir->di_ino->in_path, NULL);
204 if (dir->di_prefix != NULL) {
206 int nlen = strlen(dir->di_prefix);
208 if (dir->di_prefix[nlen - 1] ==
'/')
209 dir->di_prefix[nlen - 1] =
'\0';
211 log(
"prefix: '%s' opened, fd=%d\r\n", dir->di_prefix, fd);
240 if ((fd =
tarf_open(ctx,
name, O_DIRECTORY|O_RDONLY, 0)) >= 0) {
246 log(
"failed to open()/fdopendir() '%s'\r\n",
name);
266 struct tarfs_dir *dir = (
struct tarfs_dir *)pdir;
268 log(
"closing dir fd=%d\r\n", dir->di_fd);
272 if (dir->di_prefix != NULL)
295 struct tarfs_dir *dir = (
struct tarfs_dir *)pdir;
296 struct tarfs_inode const *cur;
301 while (cur->in_next != NULL) {
308 log(
"end of directory '%s' reached\r\n", dir->di_prefix);
314 const char *p =
remove_subpath((
char const *)cur->in_path, dir->di_prefix);
320 if (len <
sizeof(dir->di_ent.d_name)) {
322 memcpy(dir->di_ent.d_name, p, len);
323 dir->di_ent.d_name[len] =
'\0';
326 case TART_DIR: dir->di_ent.d_type = DT_DIR;
break;
329 case TART_CONT: dir->di_ent.d_type = DT_REG;
break;
330 default: dir->di_ent.d_type = DT_UNKNOWN;
break;
334 dir->di_ent.d_ino = 0;
342 errno = ENAMETOOLONG;
346 log(
"end of alphalist is reached\r\n");
359 struct tarfs_dir * dir = (
struct tarfs_dir *)pdir;
373 struct tarfs_dir * dir = (
struct tarfs_dir *)pdir;
378 if (dir->di_off > offset) {
380 dir->di_cino = dir->di_ino;
383 while(dir->di_off < offset) {
385 log(
"offset %ld is not reachable, stopped at offset %u\r\n", offset, (
unsigned int)dir->di_off);
403 struct tarfs_dir * dir = (
struct tarfs_dir *)pdir;
long tard_telldir(void *ctx, DIR *pdir)
Return the current directory position.
static bool is_sanefd(struct tarfs_fs *fs, int fd)
int tard_closedir(void *ctx, DIR *pdir)
Close a directory stream.
DIR * tard_fdopendir(void *ctx, int fd)
Associate an open directory file descriptor with a directory stream.
struct dirent * tard_readdir(void *ctx, DIR *pdir)
Read the next directory entry.
int tard_dirfd(void *ctx, DIR *pdir)
The function tard_dirfd() returns the file descriptor associated with the directory stream pdir.
DIR * tard_opendir(void *ctx, const char *name)
Open a directory for reading.
static const char * remove_subpath(const char *path, const char *subpath)
static int is_direct_child(const char *path, const char *prefix)
Check if 'path' is direct child of 'prefix'; Prefix MUST NOT have '/' at the end.
void tard_seekdir(void *ctx, DIR *pdir, long offset)
Reposition a directory stream.
int tarf_close(void *ctx, int fd)
int tarf_open(void *ctx, const char *path0, int flags, int mode)
Open a TARFS file or directory.
int tarfs_unref(struct tarfs_fs *fs)
void * tarfs_calloc(size_t count, size_t size)
calloc() based on a memory backend; Memory backend must set errno if there were errors
struct tarfs_fs * tarfs_getfs(int i)
Lockless, not thread safe, does not increase refcounters.
struct tarfs_fs * tarfs_getfs_addref(int i)
Thread safe, increases refcounter, uses mutex!
tart_t inode_type(struct tarfs_inode const *ino)
void tarfs_os_free(void *buffer)
TARFS File API: tarf_open(), tarf_close(), tarf_read(), tarf_pread(), tarf_lseek(),...
This descriptor holds all file descriptors opened.
struct tarfs_fp fs_fd[16]
tarfs_inode_t const *const * fs_ino
int tar_strncmp(const char *s1, const char *s2, size_t len)
char * tar_strdup1(const char *s1, const char *s1_end)
Duplicate a TAR string as a regular NUL-terminated C string.
int tar_strlen(const char *s1, const char *s1_end)
Return the length of a TAR string.