Rewrite realpath without memory allocation.
This commit is contained in:
+12
-16
@@ -7,27 +7,23 @@
|
||||
|
||||
/// @brief Extracts the parent directory of the given path and saves it inside
|
||||
/// the given buffer, e.g., from "/home/user/test.txt" it extracts "/home/user".
|
||||
/// If the path does not contain a '/', it will return ".".
|
||||
/// @param path the path we are parsing.
|
||||
/// @param buffer the buffer where we save the directory name.
|
||||
/// @param buflen the length of the buffer.
|
||||
/// @return 1 if succesfull, or 0 if the buffer cannot contain the path.
|
||||
int dirname(const char *path, char *buffer, size_t buflen);
|
||||
|
||||
// TODO: doxygen comment.
|
||||
/// @brief
|
||||
/// @param path
|
||||
/// @result
|
||||
char *basename(const char *path);
|
||||
/// @brief Extract the component after the final '/'.
|
||||
/// @param path the path from which we extract the final component.
|
||||
/// @return a pointer after the final '/', or path itself it none was found.
|
||||
const char *basename(const char *path);
|
||||
|
||||
/// @brief Return the canonicalized absolute pathname.
|
||||
/// @param path The path we are canonicalizing.
|
||||
/// @param resolved The canonicalized path.
|
||||
/// @return
|
||||
/// If there is no error, realpath() returns a pointer to the resolved.
|
||||
/// Otherwise, it returns NULL, the contents of the array resolved
|
||||
/// are undefined, and errno is set to indicate the error.
|
||||
/// @details
|
||||
/// If resolved is NULL, then realpath() uses malloc
|
||||
/// to allocate a buffer of up to PATH_MAX bytes to hold the
|
||||
/// resolved pathname, and returns a pointer to this buffer.
|
||||
char *realpath(const char *path, char *resolved);
|
||||
/// @param path the path we are canonicalizing.
|
||||
/// @param buffer where we will store the canonicalized path.
|
||||
/// @param buflen the size of the buffer.
|
||||
/// @return If there is no error, realpath() returns a pointer to the buffer.
|
||||
/// Otherwise, it returns NULL, the contents of the array buffer are undefined,
|
||||
/// and errno is set to indicate the error.
|
||||
char *realpath(const char *path, char *buffer, size_t buflen);
|
||||
|
||||
+24
-15
@@ -43,18 +43,22 @@ int dirname(const char *path, char *buffer, size_t buflen)
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *basename(const char *path)
|
||||
const char *basename(const char *path)
|
||||
{
|
||||
char *p = strrchr(path, '/');
|
||||
|
||||
return p ? p + 1 : (char *)path;
|
||||
// Search for the last slash.
|
||||
const char *last_slash = NULL;
|
||||
for (const char *it = path; *it; it++) {
|
||||
if ((*it) == '/') {
|
||||
last_slash = it;
|
||||
}
|
||||
}
|
||||
return last_slash ? last_slash + 1 : path;
|
||||
}
|
||||
|
||||
char *realpath(const char *path, char *resolved)
|
||||
char *realpath(const char *path, char *buffer, size_t buflen)
|
||||
{
|
||||
assert(path && "Provided null path.");
|
||||
if (resolved == NULL)
|
||||
resolved = malloc(sizeof(char) * PATH_MAX);
|
||||
assert(buffer && "Provided null buffer.");
|
||||
char abspath[PATH_MAX];
|
||||
// Initialize the absolute path.
|
||||
memset(abspath, '\0', PATH_MAX);
|
||||
@@ -94,22 +98,27 @@ char *realpath(const char *path, char *resolved)
|
||||
// Go to previous directory if /../ is found
|
||||
else if (!strncmp("/../", abspath + absidx, 4)) {
|
||||
// Go to a valid path character (pathidx points to the next one)
|
||||
if (pathidx)
|
||||
if (pathidx) {
|
||||
pathidx--;
|
||||
while (pathidx && resolved[pathidx] != '/') {
|
||||
}
|
||||
while (pathidx && buffer[pathidx] != '/') {
|
||||
pathidx--;
|
||||
}
|
||||
absidx += 3;
|
||||
} else if (!strncmp("/./", abspath + absidx, 3)) {
|
||||
absidx += 2;
|
||||
} else {
|
||||
resolved[pathidx++] = abspath[absidx++];
|
||||
if ((pathidx + 1) >= buflen) {
|
||||
return NULL;
|
||||
}
|
||||
buffer[pathidx++] = abspath[absidx++];
|
||||
}
|
||||
}
|
||||
// Remove the last /
|
||||
if (pathidx > 1)
|
||||
resolved[pathidx - 1] = '\0';
|
||||
else
|
||||
resolved[1] = '\0';
|
||||
return resolved;
|
||||
if (pathidx > 1) {
|
||||
buffer[pathidx - 1] = '\0';
|
||||
} else {
|
||||
buffer[1] = '\0';
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user