18typedef struct path_flag_short
41typedef struct path_flag
67 if (flag ==
NULL || length == 0)
75 if (len == length &&
strncmp(flag,
flags[i].name, length) == 0)
82 for (
size_t i = 0; i < length; i++)
101 static const bool forbidden[
UINT8_MAX + 1] = {
113 return !forbidden[(
uint8_t)ch];
118 if (pathname ==
NULL)
142 while (
string[index] !=
'\0' &&
string[index] !=
':')
144 if (
string[index] ==
'/')
146 currentNameLength = 0;
163 pathname->
string[index] =
string[index];
167 pathname->
string[index] =
'\0';
169 if (
string[index] !=
':')
175 const char*
flags = &
string[index];
179 while (
string[index] ==
':')
184 if (
string[index] ==
'\0')
189 const char* token = &
string[index];
190 while (
string[index] !=
'\0' &&
string[index] !=
':')
200 uint64_t tokenLength = &
string[index] - token;
214 pathname->
mode |= mode;
394 ctx->
mount = nextMount;
439 if (readCount ==
ERR)
443 symlinkPath[readCount] =
'\0';
466 if (length == 1 && name[0] ==
'.')
471 if (length == 2 && name[0] ==
'.' && name[1] ==
'.')
537 const char* component = p;
538 while (*p !=
'\0' && *p !=
'/')
542 size_t length = p - component;
567 .mount = path->
mount,
606 .mode = pathname->
mode,
607 .mount = path->
mount,
654 while (len > 1 &&
string[len - 1] ==
'/')
656 string[len - 1] =
'\0';
660 char* lastSlash =
strrchr(
string,
'/');
661 if (lastSlash ==
NULL)
668 char* lastComponent = lastSlash + 1;
672 if (lastSlash ==
string)
687 return path_walk(path, &parentPathname, ns);
732 if (dentry ==
mount->source)
739 dentry =
mount->target;
751 if ((
size_t)(ptr -
buffer) < len + 1)
786 if (out ==
NULL || length == 0)
795 if (mode &
flags[i].mode)
798 if (index + nameLength + 1 >= length)
#define MAX_NAME
Maximum length of names.
#define MAX_PATH
Maximum length of filepaths.
EFI_PHYSICAL_ADDRESS buffer
#define DENTRY_IS_SYMLINK(dentry)
Check if the vnode associated with a dentry is a symbolic link.
dentry_t * dentry_lookup(dentry_t *parent, const char *name, size_t length)
Lookup a dentry for the given name without traversing mountpoints.
dentry_t * dentry_rcu_get(const dentry_t *parent, const char *name, size_t length)
Get a dentry from the dentry cache in an RCU read-side critical section without traversing mountpoint...
void namespace_rcu_get_root(namespace_t *ns, mount_t **mount, dentry_t **dentry)
Get the root mount of a namespace in an RCU read critical section.
bool namespace_rcu_traverse(namespace_t *ns, mount_t **mount, dentry_t **dentry)
If the given path is a mountpoint in the namespace, traverse to the mounted filesystem in an RCU read...
#define PATH_MAX_DOTDOT
Maximum iterations to handle .. in a path.
mode_t
Path flags and permissions.
void path_put(path_t *path)
Put a path.
uint64_t mode_check(mode_t *mode, mode_t maxPerms)
Check and adjust mode permissions.
uint64_t mode_to_string(mode_t mode, char *out, uint64_t length)
Convert a mode to a string representation.
#define PATH_MAX_SYMLINK
Maximum iterations to handle symlinks in a path.
uint64_t path_step(path_t *path, mode_t mode, const char *name, namespace_t *ns)
Walk a single path component.
void path_set(path_t *path, mount_t *mount, dentry_t *dentry)
Set a path.
uint64_t path_walk_parent(path_t *path, const pathname_t *pathname, char *outLastName, namespace_t *ns)
Walk a pathname to its parent and get the name of the last component.
uint64_t path_walk_parent_and_child(const path_t *from, path_t *outParent, path_t *outChild, const pathname_t *pathname, namespace_t *ns)
Traverse a pathname to its parent and child paths.
uint64_t path_walk(path_t *path, const pathname_t *pathname, namespace_t *ns)
Walk a pathname to a path.
uint64_t pathname_init(pathname_t *pathname, const char *string)
Initialize a pathname.
void path_copy(path_t *dest, const path_t *src)
Copy a path.
uint64_t path_to_name(const path_t *path, pathname_t *pathname)
Convert a path to a pathname.
static void rcu_read_unlock(void)
RCU read-side critical section end.
#define RCU_READ_SCOPE()
RCU read-side critical section for the current scope.
static void rcu_read_lock(void)
RCU read-side critical section begin.
#define REF_TRY(ptr)
Increment reference count, but only if the current count is not zero.
#define UNREF_DEFER(ptr)
RAII-style cleanup for scoped references.
#define REF(ptr)
Increment reference count.
#define UNREF(ptr)
Decrement reference count.
#define TEST_DEFINE(_name)
Define a test function to be run by TEST_ALL().
#define TEST_ASSERT(cond)
Assert a condition in a test.
size_t vfs_readlink(vnode_t *symlink, char *buffer, size_t size)
Read the path in a symbolic link.
#define ENOENT
No such file or directory.
#define EINVAL
Invalid argument.
#define ELOOP
Too many symbolic links encountered.
#define ENAMETOOLONG
File name too long.
#define ENONET
Machine is not on the network.
#define errno
Error number variable.
#define EACCES
Permission denied.
#define ARRAY_SIZE(x)
Get the number of elements in a static array.
uint64_t mount(const char *mountpoint, const char *fs, const char *options)
System call for mounting a filesystem.
uint64_t symlink(const char *target, const char *linkpath)
System call for creating a symbolic link.
#define NULL
Pointer error value.
#define ERR
Integer error value.
static uint64_t path_walk_acquire(path_walk_ctx_t *ctx)
static uint64_t path_walk_get_result(path_walk_ctx_t *ctx, path_t *path)
static void path_walk_release(path_walk_ctx_t *ctx)
static const path_flag_t flags[]
static void path_walk_set_lookup(path_walk_ctx_t *ctx, dentry_t *dentry)
static bool path_is_char_valid(char ch)
static uint64_t path_rcu_dotdot(path_walk_ctx_t *ctx)
static bool path_is_name_valid(const char *name)
static path_flag_short_t shortFlags[UINT8_MAX+1]
static uint64_t path_rcu_symlink(path_walk_ctx_t *ctx, dentry_t *symlink)
static mode_t path_flag_to_mode(const char *flag, size_t length)
static uint64_t path_rcu_step(path_walk_ctx_t *ctx, const char *name, size_t length)
static void path_walk_cleanup(path_walk_ctx_t *ctx)
static uint64_t path_rcu_walk(path_walk_ctx_t *ctx)
#define atomic_load(object)
_PUBLIC void * memmove(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC char * strncpy(char *_RESTRICT s1, const char *_RESTRICT s2, size_t n)
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC int strncmp(const char *s1, const char *s2, size_t n)
_PUBLIC size_t strlen(const char *s)
_PUBLIC char * strrchr(const char *s, int c)
_PUBLIC int strcmp(const char *s1, const char *s2)
_PUBLIC void * memset(void *s, int c, size_t n)
size_t strnlen_s(const char *s, size_t maxsize)
Directory entry structure.
char name[MAX_NAME]
The name of the dentry, immutable after creation.
dentry_t * parent
The parent dentry, will be itself if this is the root dentry, immutable after creation.
dentry_t * target
The dentry which the source is mounted to, can be NULL for the root filesystem.
mount_t * parent
The parent mount, can be NULL for the root filesystem.
dentry_t * source
The dentry to appear at target once mounted, usually the root dentry of the mounted filesystem.
const pathname_t * pathname