The Hackerlab at regexps.com

File-name Manipulation Functions

up: libhackerlab
next: Parsing Command-line Options
prev: An Errorless Front-end to the VU File-system Interface

The functions in this chapter are for managing strings which are file names. Though the actual implementation is unix-specific, the calling conventions for these functions (based on the design of GNU Emacs) should support other operating systems as well.

WARNING: some of the functions in this chapter use `must_malloc' when it would be better to use some other allocation function. This is likely to be fixed in a future release.


Home Directories

up: File-name Manipulation Functions
next: File-name Algebra

Function file_name_home_directory

char * file_name_home_directory (void);

Return the user's home directory.

The path returned should not be freed by the caller and may be returned more than once by file_name_home_directory .

The home directory is defined to be the value of the environment variable HOME, unless that variable is unbound or is bound to an empty string. If HOME is undefined, then the home directory is found using getpwuid and the real user id of the process.

If the home directory can not be computed, or storage can not be allocated, panic is called to force the process to exit.

The directory name returned is formatted as if returned by file_name_as_directory (it will end with a single / ).



Function file_name_is_absolute

int file_name_is_absolute (t_uchar * f);

     return f && f[0] && (f[0] == '/');



Function file_name_tilde_expand

t_uchar * file_name_tilde_expand (alloc_limits limits, char * fname);

Return a newly allocated copy of fname with a leading ~ or ~user expanded to the appropriate home directory.

If allocation fails (but does not call panic ) this function returns 0 .

If asked to expand ~ , and unable to find a home directory for the current process, this function panics and exits.

If asked to expand ~user , and unable to find a home directory for user , this function returns a newly allocated copy of fname .




File-name Algebra

up: File-name Manipulation Functions
next: Paths
prev: Home Directories

Function file_name_tail

char * file_name_tail (alloc_limits limits, char * fname);

Return a newly allocated string containing only the last element of the file-name fname . The last element is everything following the last "/" or all of fname if it contains no "/" characters.

     "/usr/bin/ls"   =>      "ls"
     "/usr/bin/"     =>      ""
     "ls"            =>      "ls"

If allocation fails (but does not call panic ) this function returns 0 .



Function file_name_head

t_uchar * file_name_head (alloc_limits limits, char * fname);

/usr/bin/ls => / usr/bin/ls => usr ls => ls 0 => 0



Function file_name_sans_head

t_uchar * file_name_sans_head (alloc_limits limits, char * fname);

/ => 0 /usr/bin/ls => usr/bin/ls usr/bin/ls => bin/ls usr/ => 0 ls => 0 0 => 0



Function file_name_as_directory

t_uchar * file_name_as_directory (alloc_limits limits, t_uchar * f);

Return a newly allocated copy of file-name f , ensuring that the copy ends in a single "/" .

     "/usr/bin/ls"   =>      "/usr/bin/ls/"
     "/usr/bin/"     =>      "/usr/bin/"
     "/usr/bin///"   =>      "/usr/bin/"
     "ls"            =>      "ls/"
     "/"             =>      "/"

If allocation fails (but does not call panic ) this function returns 0 .



Function file_name_from_directory

t_uchar * file_name_from_directory (alloc_limits limits, t_uchar * f);

Return a newly allocated copy of file-name f , removing all trailing "/" characters. The root directory is treated specially:

     "/usr/bin/ls"   =>      "/usr/bin/ls"
     "ls"            =>      "ls"
     "/usr/bin/"     =>      "/usr/bin"
     "/usr/bin///"   =>      "/usr/bin"
     "/"             =>      "/"

If allocation fails (but does not call panic ) this function returns 0 .



Function file_name_directory

t_uchar * file_name_directory (alloc_limits limits, t_uchar * f);

Return a newly allocated copy of the directory portion of file-name f , ensuring that the copy ends with a single "/" .

The directory portion is everything except the last component of a file-name. If f already ends with a "/" , then this function is the same as file_name_as_directory . If f has no directory component, this function returns 0 :

     "/usr/bin/ls"   =>      "/usr/bin/"
     "/usr/bin///ls" =>      "/usr/bin/"
     "/usr/bin/"     =>      "/usr/bin/"
     "/usr/bin"      =>      "/usr/"
     "ls"            =>      0
     "/"             =>      "/"

If allocation fails (but does not call panic ) this function returns 0 .



Function file_name_directory_file

t_uchar * file_name_directory_file (alloc_limits limits, t_uchar * f);

Return a newly allocated copy of the directory portion of file-name f , ensuring that the copy does not end with a single "/" (with one exception).

The directory portion is everything except the last component of a file-name. If f has no directory component, this function returns 0 :

     "/usr/bin/ls"   =>      "/usr/bin"
     "/usr/bin///ls" =>      "/usr/bin"
     "/usr/bin/"     =>      "/usr/bin"
     "/usr/bin"      =>      "/usr"
     "ls"            =>      0
     "/"             =>      "/"

If allocation fails (but does not call panic ) this function returns 0 .



Function file_name_is_path_prefix

int file_name_is_path_prefix (t_uchar * maybe_prefix, t_uchar * path);

Return non-zero if maybe_prefix is equal to path or to some path-prefix of path .

For example:

     "/usr/bin"      is a prefix of  "/usr/bin/ls"
     "/usr/bin"      is a prefix of  "/usr/bin"
     "/usr/bin"      is a prefix of  "/usr/bin/"
     "/usr/bin/"     is a prefix of  "/usr/bin/"

but:

     "/usr/bin"      is _not_ a prefix of    "/usr/bin-utils/ls"
     "/usr/bin/"     is _not_ a prefix of    "/usr/bin"



Function file_name_in_vicinity

t_uchar * file_name_in_vicinity (alloc_limits limits,
                                 t_uchar * dir,
                                 t_uchar * file);

Return a newly allocated string which is dir , followed by "/" , followed by file . If dir is a directory name and file is a relative file-name, then the result is a name for file , relative to dir . If dir already ends in "/" , no additional "/" is added.

If dir is 0 or "" , a newly allocated copy of file is returned.

If file is an absolute file name (begins with "/" ) a newly allocated copy of file is returned.

     "/usr/bin", "ls"        =>      "/usr/bin/ls"
     "/usr/bin/", "ls"       =>      "/usr/bin/ls"
     "/usr/bin///", "ls"     =>      "/usr/bin/ls"
     "/etc", "/usr/bin/ls"   =>      "/usr/bin/ls"
     0, "ls"                 =>      "ls"

If allocation fails (but does not call panic ) this function returns 0 .




Paths

up: File-name Manipulation Functions
prev: File-name Algebra

Function path_parse

t_uchar ** path_parse (alloc_limits limits, char * path);

Convert a path of file-names separated by ':' to form a 0-terminated array of file-names.

An empty file-name is converted to "." .

The array is allocated by the variable sized array functions and should be freed using ar_free (see Variable Size Arrays). Note that ar_size returns the size of the array, including the final 0 .

The elements of the array are allocated by must_malloc and should be freed using must_free . THIS IS A BUG.

The function free_path can be used to free a path allocated by path_parse .

If allocation fails (but does not call panic ) this function returns 0 .



Function free_path

void free_path (alloc_limits limits, t_uchar ** path)

Free a path allocated by path_parse .



Function path_find_executable

t_uchar * path_find_executable (alloc_limits limits, 
                                t_uchar ** path,
                                t_uchar * tail);

Search on path for a file named tail that is executable by this process. Returns a newly allocated copy of the name of such a file or 0 .

The file-name returned is formed by file_name_in_vicinity (limits, path[N], tail) and should be freed by must_free .

The effective user and group ids are used to check whether or not the file can be executed (which should be the same rule used by the kernel).

If allocation fails (but does not call panic ) this function returns 0 .



libhackerlab: The Hackerlab C Library
The Hackerlab at regexps.com