PatchworkOS  c9fea19
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 with which the path is opened.

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 if it does not exist.
exclusive e Will cause the open to fail if the file already exists.
truncate t Truncate the file to zero length if it already exists.
directory d Allow opening directories.
recursive R Behaviour differs, but allows for recursive operations, for example when used with remove it

will remove directories and their children recursively. |

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 opened paths and permissions through out 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.

See also
Namespaces for information on mode inheritance when binding paths.

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_VALID_CHAR(ch)    (strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-. ()[]{}~!@#$%^&?',;=+", (ch)))
 Check if a char is valid.
 
#define PATH_HANDLE_DOTDOT_MAX_ITER   1000
 Maximum iterations to handle .. in a path.
 
#define PATHNAME_IS_VALID(pathname)   ((pathname) != NULL && (pathname)->isValid)
 Check if a pathname is valid.
 
#define PATHNAME(string)
 Helper to create a pathname.
 
#define PATH_EMPTY
 Helper to create an empty path.
 
#define PATH_CREATE(inMount, inDentry)
 Helper to create a path.
 

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_TRUNCATE = 1 << 7 , MODE_DIRECTORY = 1 << 8 , MODE_RECURSIVE = 1 << 9 , MODE_AMOUNT = 10 ,
  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, const char *name, namespace_t *ns)
 Walk a single step in a path.
 
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.
 
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 97 of file path.h.

◆ PATH_VALID_CHAR

#define PATH_VALID_CHAR (   ch)     (strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-. ()[]{}~!@#$%^&?',;=+", (ch)))

Check if a char is valid.

A valid char is one of the following ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-. ()[]{}~!#$%^&?’,;=+`.

Todo:
Replace with array lookup.
Parameters
chThe char to check.
Returns
true if the char is valid, false otherwise.

Definition at line 110 of file path.h.

◆ PATH_HANDLE_DOTDOT_MAX_ITER

#define PATH_HANDLE_DOTDOT_MAX_ITER   1000

Maximum iterations to handle .. in a path.

This is to prevent infinite loops in case of a corrupted filesystem.

Definition at line 118 of file path.h.

◆ PATHNAME_IS_VALID

#define PATHNAME_IS_VALID (   pathname)    ((pathname) != NULL && (pathname)->isValid)

Check if a pathname is valid.

A valid pathname is not NULL and has its isValid flag set to true.

This flag is set in pathname_init().

Parameters
pathnameThe pathname to check.
Returns
true if the pathname is valid, false otherwise.

Definition at line 153 of file path.h.

◆ PATHNAME

#define PATHNAME (   string)
Value:
({ \
pathname_t* pathname = alloca(sizeof(pathname_t)); \
pathname_init(pathname, string); \
pathname; \
})
#define alloca(size)
Definition alloca.h:11
Pathname structure.
Definition path.h:137

Helper to create a pathname.

This macro will create a pathname on the stack and initialize it with the given string.

This is also the reason we have the isValid flag in the pathname_t structure, to be able to check if this macro failed without having to return an error code, streamlining the code a bit.

Parameters
stringThe string to initialize the pathname with.
Returns
The initialized pathname.

Definition at line 166 of file path.h.

◆ PATH_EMPTY

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

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 194 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:65

Helper to create a path.

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

Definition at line 207 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_TRUNCATE 
MODE_DIRECTORY 
MODE_RECURSIVE 
MODE_AMOUNT 
MODE_ALL_PERMS 

Definition at line 73 of file path.h.

Function Documentation

◆ pathname_init()

uint64_t pathname_init ( pathname_t pathname,
const char *  string 
)

Initialize a pathname.

If the string is invalid, it will error and set pathname->isValid to false.

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 89 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 196 of file path.c.

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 221 of file path.c.

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 246 of file path.c.

Here is the caller graph for this function:

◆ path_step()

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

Walk a single step in a path.

Parameters
pathThe path to traverse, will be updated to the new path, may be negative.
nameThe name of the child dentry.
nsThe namespace to access mountpoints.
Returns
On success, 0. On failure, ERR and errno is set.

Definition at line 323 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 347 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 440 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 497 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 522 of file path.c.

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

◆ path_defer_cleanup()

static void path_defer_cleanup ( path_t **  path)
inlinestatic

Definition at line 302 of file path.h.

Here is the call graph for this function: