Typedefs | |
typedef bool(* | directory_list_callback_t )(const char *directory, const char *base_name, const char *path, struct stat *info, void *user_data) |
callback for the directory_list() function | |
Functions | |
const char * | path_utils_error_string (int error) |
Given an error code return the string description. | |
int | get_basename (char *base_name, size_t base_name_size, const char *path) |
Get the basename component of a path. | |
int | get_dirname (char *dir_path, size_t dir_path_size, const char *path) |
Copy the directory components of a path. | |
int | get_directory_and_base_name (char *dir_path, size_t dir_path_size, char *base_name, size_t base_name_size, const char *path) |
Get the basaname and directory components of a path. | |
bool | is_absolute_path (const char *path) |
Tell if path is absolute or relative. | |
int | path_concat (char *path, size_t path_size, const char *head, const char *tail) |
Concatenate two components of a path. | |
int | make_path_absolute (char *absolute_path, size_t absolute_path_size, const char *path) |
Convert a path into absolute. | |
char ** | split_path (const char *path, int *count) |
Split a file system path into individual components. | |
int | normalize_path (char *normalized_path, size_t normalized_path_size, const char *path) |
Normalizes a path. | |
int | common_path_prefix (char *common_path, size_t common_path_size, int *common_count, const char *path1, const char *path2) |
Find the common prefix between two paths. | |
int | make_normalized_absolute_path (char *result_path, size_t result_path_size, const char *path) |
Make the input path absolute if it's not already, then normalize it. | |
int | find_existing_directory_ancestor (char *ancestor, size_t ancestor_size, const char *path) |
int | directory_list (const char *path, bool recursive, directory_list_callback_t callback, void *user_data) |
Walk a directory. | |
bool | is_ancestor_path (const char *ancestor, const char *path) |
Tell if one path is ancestor of another. |
typedef bool(* directory_list_callback_t)(const char *directory, const char *base_name, const char *path, struct stat *info, void *user_data) |
callback for the directory_list()
function
Please see the description of directory_list()
to see more details about this callback
[in] | directory | Directory name of the visited path |
[in] | base_name | Base name of the visited path |
[in] | path | Full name of the visited path |
[in] | info | Info about the visited directory |
[in] | user_data | Callback data passed by caller |
false
, do not recursively descend into the directory, descend if true
int common_path_prefix | ( | char * | common_path, | |
size_t | common_path_size, | |||
int * | common_count, | |||
const char * | path1, | |||
const char * | path2 | |||
) |
Find the common prefix between two paths.
Finds the common prefix between two paths, returns the common prefix and optionally the count of how many path components were common between the two paths (if common_count
is non-NULL). Please note that for absolute paths, the "/"
root prefix is treated as a common components, so the paths "/usr/lib"
and "/usr/share"
would have two common components - "/"
and "/usr"
.
Contrary to some other implementations, common_path_prefix()
works on path components, not characters, which guarantees at least some level of sanity of the returned prefixes (for example, the common prefix of "/usr/share"
and "/usr/src"
would be "/usr"
)
SUCCESS
if successful, non-zero error code otherwise. Possible errors: ENOBUFS
if the buffer space is too small int directory_list | ( | const char * | path, | |
bool | recursive, | |||
directory_list_callback_t | callback, | |||
void * | user_data | |||
) |
Walk a directory.
Walk a directory. If recursive
is true
child directories will be descended into. The supplied callback is invoked for each entry in the directory.
The callback is provided with the directory name, basename, the full pathname (i.e. directory name + basename) a stat structure for the path item and a pointer to any user supplied data specified in the user_data
parameter. If the callback returns false
for a directory the recursive descent into that directory does not occur thus effectively "pruning" the tree.
[in] | path | The path to examine |
[in] | recursive | Whether to recursively examine entries in the directory |
[in] | callback | The callback to invoke for each entry |
[in] | user_data | The data to pass into the callback |
int find_existing_directory_ancestor | ( | char * | ancestor, | |
size_t | ancestor_size, | |||
const char * | path | |||
) |
Find the first path component which is an existing directory by walking from the tail of the path to it's head, return the path of the existing directory.
If the pathname is relative and does not contain a directory, the current directory is returned as parent.
SUCCESS
if successful, non-zero error code otherwise. Possible errors: ENOBUFS
if the buffer space is too small EACCES
Search permission is denied for one of the directories. ELOOP
Too many symbolic links encountered while traversing the path. ENAMETOOLONG
File name too long. ENOMEM
Out of memory (i.e., kernel memory). int get_basename | ( | char * | base_name, | |
size_t | base_name_size, | |||
const char * | path | |||
) |
Get the basename component of a path.
Given a path, copy the basename component (in the usual case, the part following the final "/") into the buffer base_name
whose length is base_name_size
. If the path does not contain a slash, get_basename()
returns a copy of path.
[out] | base_name | The basename component |
[in] | base_name_size | The size of the base_name buffer |
[in] | path | The full path to parse |
SUCCESS
if successful, non-zero error code otherwise. Possible errors: ENOBUFS
if the buffer space is too small EINVAL
The path was a NULL pointer int get_directory_and_base_name | ( | char * | dir_path, | |
size_t | dir_path_size, | |||
char * | base_name, | |||
size_t | base_name_size, | |||
const char * | path | |||
) |
Get the basaname and directory components of a path.
Given a path, copy the directory components into the buffer dir_path
whose length is dir_path_size
and copy the basename component into the buffer base_name
whose length is base_name_size
.
[out] | base_name | The basename component |
[in] | base_name_size | The size of the base_name buffer |
[out] | dir_path | The directory component |
[in] | dir_path_size | The size of the dir_path buffer |
[in] | path | The full path to parse |
SUCCESS
if successful, non-zero error code otherwise. Possible errors: ENOBUFS
If the buffer space is too small EACCES
Permission to read or search a component of the filename was denied. ENAMETOOLONG
The size of the null-terminated pathname exceeds PATH_MAX bytes. ENOENT
The current working directory has been unlinked. EINVAL
The path was a NULL pointer int get_dirname | ( | char * | dir_path, | |
size_t | dir_path_size, | |||
const char * | path | |||
) |
Copy the directory components of a path.
Given a path, copy the directory components (in the usual case, the path up to, but not including the final "/") into the buffer dir_path
whose length is dir_path_size
. If the path does not contain a slash, get_dirname()
returns the current working directory.
[out] | dir_path | The directory component |
[in] | dir_path_size | The size of the dir_path buffer |
[in] | path | The full path to parse |
SUCCESS
if successful, non-zero error code otherwise. Possible errors: ENOBUFS
If the buffer space is too small EACCES
Permission to read or search a component of the filename was denied. ENAMETOOLONG
The size of the null-terminated pathname exceeds PATH_MAX bytes. ENOENT
The current working directory has been unlinked. EINVAL
The path was a NULL pointer bool is_absolute_path | ( | const char * | path | ) |
Tell if path is absolute or relative.
[in] | path | The path to check |
true
if the path is absolute, false
otherwise. bool is_ancestor_path | ( | const char * | ancestor, | |
const char * | path | |||
) |
Tell if one path is ancestor of another.
Test to see if the path passed in the ancestor
parameter is an ancestor of the path passed in the path parameter returning true if it is, false
otherwise.
The test is "static" as such it is performed on the string components in each path. Live symbolic links in the file system are not taken into consideration. The test operates by splitting each path into it's individual components and then comparing each component pairwise for string equality. Both paths mush share a common root component for the test to be meaningful (e.g. don't attempt to compare an absolute path with a relative path).
Example:
is_ancestor_path("/a/b/c" "/a/b/c/d") => true is_ancestor_path("/a/b/c/d" "/a/b/c/d") => false // equal, not ancestor is_ancestor_path("/a/x/c" "/a/b/c/d") => false
true
if ancestor
is an ancestor of path
int make_normalized_absolute_path | ( | char * | result_path, | |
size_t | result_path_size, | |||
const char * | path | |||
) |
Make the input path absolute if it's not already, then normalize it.
SUCCESS
if successful, non-zero error code otherwise. Possible errors: ENOBUFS
if the buffer space is too small int make_path_absolute | ( | char * | absolute_path, | |
size_t | absolute_path_size, | |||
const char * | path | |||
) |
Convert a path into absolute.
Given a path make it absolute storing the absolute path in into the buffer absolute_path
whose length is absolute_path_size
.
Returns SUCCESS
if successful, non-zero error code otherwise. Possible errors:
ENOBUFS
If the buffer space is too small ENOMEM
If user memory cannot be mapped ENOENT
If directory does not exist (i.e. it has been deleted) EFAULT
If memory access violation occurs while copying EINVAL
The path was a NULL pointer int normalize_path | ( | char * | normalized_path, | |
size_t | normalized_path_size, | |||
const char * | path | |||
) |
Normalizes a path.
Normalizes a path copying the resulting normalized path into the buffer normalized_path
whose length is normalized_size
.
A path is normalized when:
. path components (except if
. is the only component)
.. path componentsThe input path may either be an absolute path or a path fragment.
As a special case if the input path is NULL
, the empty string ""
, or "."
the returned normalized path will be "."
.
".."
path components point to the parent directory which effectively means poping the parent off the path. But what happens when there are more ".."
path components than ancestors in the path? The answer depends on whether the path is an absolute path or a path fragment. If the path is absolute then the extra ".."
components which would move above the root (/) are simply ignored. This effectively limits the path to the root. However if the path is not absolute, rather it is a path fragment, and there are more ".."
components than ancestors which can be "popped off" then as many ".."
components will be popped off the fragement as possible without changing the meaning of the path fragment. In this case some extra ".."
components will be left in the path and the function will return the error ERROR_COULD_NOT_NORMALIZE_PATH_FULLY
. However the function will still normalize as much of the path fragment as is possible. The behavior of ".."
components when the input path is a fragment is adopted because after normalizing a path fragment then the normalized path fragment if made absolute should reference the same file system name as if the unnormalized fragment were made absolute. Note this also means ERROR_COULD_NOT_NORMALIZE_PATH_FULLY
will never be returned if the input path is absolute.
SUCCESS
if successful, non-zero error code otherwise. Possible errors: ENOBUFS
If the buffer space is too small ERROR_COULD_NOT_NORMALIZE_PATH_FULLY
If not all ".."
path components could be removed int path_concat | ( | char * | path, | |
size_t | path_size, | |||
const char * | head, | |||
const char * | tail | |||
) |
Concatenate two components of a path.
Given two paths, head
& tail
, copy their concatenation into the buffer path
whose length is path_size
.
[out] | path | The full path |
[in] | path_size | The size of the path buffer |
[in] | head | The first component of the path |
[in] | tail | The second component of the path |
SUCCESS
if successful, non-zero error code otherwise. ENOBUFS
If the buffer space is too small const char* path_utils_error_string | ( | int | error | ) |
Given an error code return the string description.
[in] | error | The error code |
NULL
is returned. char** split_path | ( | const char * | path, | |
int * | count | |||
) |
Split a file system path into individual components.
Split a file system path into individual components. Return a pointer to an array of char pointers, each array entry is a pointer to a copy of the component. As a special case if the path begins with / then the first component is "/" so the caller can identify the pah as absolute with the first component being the root. The last entry in the array is NULL
serving as a termination sentinel. An optional integer count parameter can be provided, which if non-NULL will have the number of components written into it. Thus the caller can iterate on the array until it sees a NULL
pointer or iterate count times indexing the array.
The caller is responsible for calling free()
on the returned array. This frees both the array of component pointers and the copies of each component in one operation because the copy of each component is stored in the same allocation block.
The original path parameter is not modified.
In the event of an error NULL
is returned and count (if specified) will be -1.
Examples:
char **components, **component; int i; components = split_path(path, NULL); for (component = components; *component; component++) printf("\"%s\" ", *component); free(components);
-OR-
components = split_path(path, &count); for (i = 0; i < count; i++) printf("\"%s\" ", components[i]); free(components);
[in] | path | The original path |
[out] | count | The number of components the path was split into |