PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches

Unique location in the filesystem. More...

Collaboration diagram for Path:

Detailed Description

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.

Flags/Mode

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)
 

Macro Definition Documentation

◆ PATH_DEFER

#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.

Parameters
pathThe path to defer.

Definition at line 106 of file path.h.

◆ PATH_MAX_DOTDOT

#define PATH_MAX_DOTDOT   1000

Maximum iterations to handle .. in a path.

This is to prevent infinite loops.

Definition at line 113 of file path.h.

◆ PATH_MAX_SYMLINK

#define PATH_MAX_SYMLINK   40

Maximum iterations to handle symlinks in a path.

This is to prevent infinite loops.

Definition at line 120 of file path.h.

◆ PATH_EMPTY

#define PATH_EMPTY
Value:
(path_t) \
{ \
.mount = NULL, .dentry = NULL \
}
#define NULL
Pointer error value.
Definition NULL.h:25
Path structure.
Definition path.h:127

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.

Returns
An empty path.

Definition at line 163 of file path.h.

◆ PATH_CREATE

#define PATH_CREATE (   inMount,
  inDentry 
)
Value:
(path_t) \
{ \
.mount = REF(inMount), .dentry = REF(inDentry), \
}
#define REF(ptr)
Increment reference count.
Definition ref.h:82

Helper to create a path.

Parameters
inMountThe mount of the path.
inDentryThe dentry of the path.
Returns
The created path.

Definition at line 176 of file path.h.

◆ PATH_IS_EMPTY

#define PATH_IS_EMPTY (   path)    ((path).mount == NULL && (path).dentry == NULL)

Check if a path is empty.

Parameters
pathThe path to check.
Returns
true if the path is empty, false otherwise.

Definition at line 188 of file path.h.

◆ PATH_IS_VALID

#define PATH_IS_VALID (   path)    ((path) != NULL && (path)->mount != NULL && (path)->dentry != NULL)

Check if a path is valid.

Parameters
pathThe path to check.
Returns
true if the path is valid, false otherwise.

Definition at line 196 of file path.h.

Enumeration Type Documentation

◆ mode_t

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.

Enumerator
MODE_NONE 
MODE_READ 
MODE_WRITE 
MODE_EXECUTE 
MODE_NONBLOCK 
MODE_APPEND 
MODE_CREATE 
MODE_EXCLUSIVE 
MODE_PARENTS 
MODE_TRUNCATE 
MODE_DIRECTORY 
MODE_RECURSIVE 
MODE_NOFOLLOW 
MODE_PRIVATE 
MODE_PROPAGATE 
MODE_LOCKED 
MODE_ALL_PERMS 

Definition at line 78 of file path.h.

Function Documentation

◆ pathname_init()

uint64_t pathname_init ( pathname_t pathname,
const char *  string 
)

Initialize a pathname.

Parameters
pathnameThe pathname to initialize.
stringThe string to initialize the pathname with.
Returns
On success, 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.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ path_set()

void path_set ( path_t path,
mount_t mount,
dentry_t dentry 
)

Set a path.

Will deref the existing mount and dentry in the path if they are not NULL.

Parameters
pathThe path to set.
mountThe mount to set.
dentryThe dentry to set.

Definition at line 242 of file path.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ path_copy()

void path_copy ( path_t dest,
const path_t src 
)

Copy a path.

Will deref the existing mount and dentry in the destination path if they are not NULL.

Parameters
destThe destination path.
srcThe source path.

Definition at line 268 of file path.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ path_put()

void path_put ( path_t path)

Put a path.

Will deref the mount and dentry in the path if they are not NULL.

Parameters
pathThe path to put.

Definition at line 273 of file path.c.

Here is the caller graph for this function:

◆ path_step()

uint64_t path_step ( path_t path,
mode_t  mode,
const char *  name,
namespace_t ns 
)

Walk a single path component.

Parameters
pathThe path to step from, will be updated to the new path, may be negative.
modeThe mode to open the new path with.
nameThe name of the new path component.
nsThe namespace to access mountpoints.
Returns
On success, 0. On failure, ERR and errno is set.

Definition at line 553 of file path.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ path_walk()

uint64_t path_walk ( path_t path,
const pathname_t pathname,
namespace_t ns 
)

Walk a pathname to a path.

Parameters
pathThe path to start from, will be updated to the new path, may be negative.
pathnameThe pathname to walk to.
nsThe namespace to access mountpoints.
Returns
On success, 0. On failure, ERR and errno is set.

Definition at line 593 of file path.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ path_walk_parent()

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.

Parameters
pathThe path to start from, will be updated to the parent path.
pathnameThe pathname to traverse.
outLastNameThe output last component name, must be at least MAX_NAME bytes.
nsThe namespace to access mountpoints.
Returns
On success, 0. On failure, ERR and errno is set.

Definition at line 633 of file path.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ path_walk_parent_and_child()

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.

Parameters
fromThe path to start from.
outParentThe output parent path.
outChildThe output child path, may be negative.
pathnameThe pathname to traverse.
nsThe namespace to access mountpoints.
Returns
On success, 0. On failure, ERR and errno is set.

Definition at line 690 of file path.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ path_to_name()

uint64_t path_to_name ( const path_t path,
pathname_t pathname 
)

Convert a path to a pathname.

The resulting pathname will be absolute.

Parameters
pathThe path to convert.
pathnameThe output pathname.
Returns
On success, 0. On failure, ERR and errno is set.

Definition at line 715 of file path.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mode_to_string()

uint64_t mode_to_string ( mode_t  mode,
char *  out,
uint64_t  length 
)

Convert a mode to a string representation.

The resulting string will be null terminated.

Parameters
modeThe mode to convert.
outThe output string buffer.
lengthThe length of the output string buffer.
Returns
On success, the length of the resulting string, excluding the null terminator. On failure, ERR and errno is set to:
  • EINVAL: Invalid parameters.
  • ENAMETOOLONG: The output buffer is too small.

Definition at line 784 of file path.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mode_check()

uint64_t mode_check ( mode_t mode,
mode_t  maxPerms 
)

Check and adjust mode permissions.

If no permissions are set in the mode, it will be adjusted to have the maximum allowed permissions.

Parameters
modeThe mode to check and adjust.
maxPermsThe maximum allowed permissions.
Returns
On success, the adjusted mode. On failure, ERR and errno is set to:
  • EINVAL: Invalid parameters.
  • EACCES: Requested permissions exceed maximum allowed permissions.

Definition at line 816 of file path.c.

Here is the caller graph for this function:

◆ path_defer_cleanup()

static void path_defer_cleanup ( path_t **  path)
inlinestatic

Definition at line 316 of file path.h.

Here is the call graph for this function: