-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No scratch
for absPath
?
#9775
base: master
Are you sure you want to change the base?
No scratch
for absPath
?
#9775
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,36 +21,43 @@ namespace fs = std::filesystem; | |
|
||
namespace nix { | ||
|
||
Path absPath(PathView path, std::optional<PathView> dir, bool resolveSymlinks) | ||
#ifdef __GNUC__ | ||
std::unique_ptr<char, FreeDeleter> getCwd() | ||
{ | ||
std::string scratch; | ||
return std::unique_ptr<char, FreeDeleter> { getcwd(NULL, 0) }; | ||
} | ||
#endif | ||
|
||
if (path[0] != '/') { | ||
// In this case we need to call `canonPath` on a newly-created | ||
// string. We set `scratch` to that string first, and then set | ||
// `path` to `scratch`. This ensures the newly-created string | ||
// lives long enough for the call to `canonPath`, and allows us | ||
// to just accept a `std::string_view`. | ||
if (!dir) { | ||
|
||
Path absPath(PathView path, std::optional<PathView> dir, bool resolveSymlinks) | ||
{ | ||
/* In some branches case we create strings that, as r-values, would | ||
not live long enough. We instead assign them to these variables | ||
so they are only deallocated at the end of this function, after | ||
the call to `canonPath` where they are used. */ | ||
std::string scratch0; | ||
std::unique_ptr<char, FreeDeleter> scratch1; | ||
[[maybe_unused]] char buf[PATH_MAX]; | ||
|
||
return canonPath( | ||
path[0] == '/' | ||
? path | ||
: (scratch0 = concatStrings( | ||
dir | ||
? *dir | ||
: | ||
#ifdef __GNU__ | ||
/* GNU (aka. GNU/Hurd) doesn't have any limitation on path | ||
lengths and doesn't define `PATH_MAX'. */ | ||
char *buf = getcwd(NULL, 0); | ||
if (buf == NULL) | ||
/* GNU (aka. GNU/Hurd) doesn't have any limitation | ||
on path lengths and doesn't define `PATH_MAX'. */ | ||
*(scratch1 = getCwd()); | ||
#else | ||
char buf[PATH_MAX]; | ||
if (!getcwd(buf, sizeof(buf))) | ||
#endif | ||
throw SysError("cannot get cwd"); | ||
scratch = concatStrings(buf, "/", path); | ||
#ifdef __GNU__ | ||
free(buf); | ||
getcwd(buf, sizeof(buf)) | ||
? buf | ||
: throw SysError("cannot get cwd"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can't we encapsulate these two branches and the whole legacy mem management issue simply into a function this seems like an unnecessary dance for a function whose concern is making paths absolute. |
||
#endif | ||
} else | ||
scratch = concatStrings(*dir, "/", path); | ||
path = scratch; | ||
} | ||
return canonPath(path, resolveSymlinks); | ||
"/", | ||
path)), | ||
resolveSymlinks); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i see the elegance in point-free programming in general, but the if-branched ersion that we had before was more readable. |
||
} | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this called so often that it must be really fast and small, so that it is worth spilling this memory management over the code that wants the cwd string?
If no, then please create a function like
std::string getCwd()
that copies the content and then frees the original string. this way we don't need anyone to know about custom deleters for this purpose.