|
PatchworkOS
19e446b
A non-POSIX operating system.
|
Unique location in the filesystem. More...
Unique location in the filesystem.
A path is a single unique location in the filesystem hierarchy. It consists of a mount and a dentry. The mount is the filesystem that the path is in and the dentry is the actual location in that filesystem.
Note how just a dentry is not enough to uniquely identify a location in the filesystem, this is because of mountpoints. A dentry can exist in a filesystem that is mounted at multiple locations in the filesystem hierarchy, thus both a mountpoint and a dentry is needed to uniquely identify a location.
Paths can have flags appended at the end, these flags are parsed to determine the mode of the related operation.
Each flag starts with : and multiple instances of the same flag are allowed, for example /path/to/file:append:append:nonblock.
Included is a list of all available flags:
| Flag | Short | Description |
|---|---|---|
read | r | Open with read permissions. |
write | w | Open with write permissions. |
execute | x | Open with execute permissions. |
nonblock | n | The file will not block on operations that would normally block. |
append | a | Any data written to the file will be appended to the end. |
create | c | Create the file or directory if it does not exist. |
exclusive | e | Will cause the open to fail if the file or directory already exists and :create is specified. |
parents | p | Create any parent directories if they do not exist when creating a file or directory. |
truncate | t | Truncate the file to zero length if it already exists. |
directory | d | Create or remove directories. All other operations will ignore this flag. |
recursive | R | If removing a directory, remove all its contents recursively. If using getdents(), list contents recursively. |
nofollow | l | Do not follow symbolic links. |
private | P | Any files with this flag will be closed before a process starts executing. Any mounts with this flag will not be copied to a child namespace. |
propagate | g | Propagate mounts and unmounts to child namespaces. |
locked | L | Forbid unmounting this mount, useful for hiding directories or files. |
For convenience, a single letter short form is also available as shown above, these single letter forms do not need to be separated by colons, for example /path/to/file:rwcte is equivalent to /path/to/file:read:write:create:truncate:exclusive.
The parsed mode is the primary way to handle both the behaviour of vfs operations and permissions in the kernel. For example, a file opened from within a directory which was bound with only read permissions will also have read only permissions, even if the file itself would allow write permissions.
If no permissions, i.e. read, write or execute, are specified, the default is to open with the maximum currently allowed permissions.
Data Structures | |
| struct | path_t |
| Path structure. More... | |
| struct | pathname_t |
| Pathname structure. More... | |
Macros | |
| #define | PATH_DEFER(path) __attribute__((cleanup(path_defer_cleanup))) path_t* CONCAT(i, __COUNTER__) = (path) |
| Defer path put. | |
| #define | PATH_MAX_DOTDOT 1000 |
Maximum iterations to handle .. in a path. | |
| #define | PATH_MAX_SYMLINK 40 |
| Maximum iterations to handle symlinks in a path. | |
| #define | PATH_EMPTY |
| Helper to create an empty path. | |
| #define | PATH_CREATE(inMount, inDentry) |
| Helper to create a path. | |
| #define | PATH_IS_EMPTY(path) ((path).mount == NULL && (path).dentry == NULL) |
| Check if a path is empty. | |
| #define | PATH_IS_VALID(path) ((path) != NULL && (path)->mount != NULL && (path)->dentry != NULL) |
| Check if a path is valid. | |
Enumerations | |
| enum | mode_t { MODE_NONE = 0 , MODE_READ = 1 << 0 , MODE_WRITE = 1 << 1 , MODE_EXECUTE = 1 << 2 , MODE_NONBLOCK = 1 << 3 , MODE_APPEND = 1 << 4 , MODE_CREATE = 1 << 5 , MODE_EXCLUSIVE = 1 << 6 , MODE_PARENTS = 1 << 7 , MODE_TRUNCATE = 1 << 8 , MODE_DIRECTORY = 1 << 9 , MODE_RECURSIVE = 1 << 10 , MODE_NOFOLLOW = 1 << 11 , MODE_PRIVATE = 1 << 12 , MODE_PROPAGATE = 1 << 13 , MODE_LOCKED = 1 << 14 , MODE_ALL_PERMS = MODE_READ | MODE_WRITE | MODE_EXECUTE } |
| Path flags and permissions. More... | |
Functions | |
| uint64_t | pathname_init (pathname_t *pathname, const char *string) |
| Initialize a pathname. | |
| void | path_set (path_t *path, mount_t *mount, dentry_t *dentry) |
| Set a path. | |
| void | path_copy (path_t *dest, const path_t *src) |
| Copy a path. | |
| void | path_put (path_t *path) |
| Put a path. | |
| uint64_t | path_step (path_t *path, mode_t mode, const char *name, namespace_t *ns) |
| Walk a single path component. | |
| uint64_t | path_walk (path_t *path, const pathname_t *pathname, namespace_t *ns) |
| Walk a pathname to 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_to_name (const path_t *path, pathname_t *pathname) |
| Convert a path to a pathname. | |
| uint64_t | mode_to_string (mode_t mode, char *out, uint64_t length) |
| Convert a mode to a string representation. | |
| uint64_t | mode_check (mode_t *mode, mode_t maxPerms) |
| Check and adjust mode permissions. | |
| static void | path_defer_cleanup (path_t **path) |
| #define PATH_DEFER | ( | path | ) | __attribute__((cleanup(path_defer_cleanup))) path_t* CONCAT(i, __COUNTER__) = (path) |
Defer path put.
This macro will call path_put() on the given path when it goes out of scope.
| path | The path to defer. |
| #define PATH_MAX_DOTDOT 1000 |
| #define PATH_MAX_SYMLINK 40 |
| #define PATH_EMPTY |
Helper to create an empty path.
Its important to always use this as some functions, for example path_copy(), will deref the existing mount and dentry in the path.
| #define PATH_CREATE | ( | inMount, | |
| inDentry | |||
| ) |
Helper to create a path.
| inMount | The mount of the path. |
| inDentry | The dentry of the path. |
| enum mode_t |
Path flags and permissions.
We store both flags and permissions in the same enum but permissions are sometimes treated differently to flags.
| uint64_t pathname_init | ( | pathname_t * | pathname, |
| const char * | string | ||
| ) |
Initialize a pathname.
| pathname | The pathname to initialize. |
| string | The string to initialize the pathname with. |
0. On failure, ERR and errno is set to:EINVAL: Invalid parameters.ENAMETOOLONG: The string is too long or a component name is too long. Definition at line 116 of file path.c.
| void path_put | ( | path_t * | path | ) |
| uint64_t path_step | ( | path_t * | path, |
| mode_t | mode, | ||
| const char * | name, | ||
| namespace_t * | ns | ||
| ) |
Walk a single path component.
| path | The path to step from, will be updated to the new path, may be negative. |
| mode | The mode to open the new path with. |
| name | The name of the new path component. |
| ns | The namespace to access mountpoints. |
0. On failure, ERR and errno is set. Definition at line 553 of file path.c.
| uint64_t path_walk | ( | path_t * | path, |
| const pathname_t * | pathname, | ||
| namespace_t * | ns | ||
| ) |
Walk a pathname to a path.
| path | The path to start from, will be updated to the new path, may be negative. |
| pathname | The pathname to walk to. |
| ns | The namespace to access mountpoints. |
0. On failure, ERR and errno is set. Definition at line 593 of file path.c.
| 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.
Will not modify outParent and outChild on failure.
| path | The path to start from, will be updated to the parent path. |
| pathname | The pathname to traverse. |
| outLastName | The output last component name, must be at least MAX_NAME bytes. |
| ns | The namespace to access mountpoints. |
0. On failure, ERR and errno is set. Definition at line 633 of file path.c.
| 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.
Will not modify outParent and outChild on failure.
| from | The path to start from. |
| outParent | The output parent path. |
| outChild | The output child path, may be negative. |
| pathname | The pathname to traverse. |
| ns | The namespace to access mountpoints. |
0. On failure, ERR and errno is set. Definition at line 690 of file path.c.
| uint64_t path_to_name | ( | const path_t * | path, |
| pathname_t * | pathname | ||
| ) |
Convert a path to a pathname.
The resulting pathname will be absolute.
| path | The path to convert. |
| pathname | The output pathname. |
0. On failure, ERR and errno is set. Definition at line 715 of file path.c.
Convert a mode to a string representation.
The resulting string will be null terminated.
| mode | The mode to convert. |
| out | The output string buffer. |
| length | The length of the output string buffer. |
ERR and errno is set to:EINVAL: Invalid parameters.ENAMETOOLONG: The output buffer is too small. Definition at line 784 of file path.c.
Check and adjust mode permissions.
If no permissions are set in the mode, it will be adjusted to have the maximum allowed permissions.
| mode | The mode to check and adjust. |
| maxPerms | The maximum allowed permissions. |
ERR and errno is set to:EINVAL: Invalid parameters.EACCES: Requested permissions exceed maximum allowed permissions. Definition at line 816 of file path.c.