Change wrealpath to return a maybe_t

Simplify the wrealpath interface and avoid manual invocations of free() by
changing wrealpath to return a maybe_t<wcstring>.
This commit is contained in:
ridiculousfish 2017-10-11 00:08:26 -07:00
parent 05c0cb713d
commit 1f130bcc9c
4 changed files with 16 additions and 21 deletions

View file

@ -37,10 +37,8 @@ int builtin_realpath(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
return STATUS_INVALID_ARGS;
}
wchar_t *real_path = wrealpath(argv[optind], NULL);
if (real_path) {
streams.out.append(real_path);
free((void *)real_path);
if (auto real_path = wrealpath(argv[optind])) {
streams.out.append(*real_path);
} else {
// We don't actually know why it failed. We should check errno.
streams.err.append_format(_(L"%ls: Invalid path: %ls\n"), cmd, argv[optind]);

View file

@ -1182,13 +1182,15 @@ static void expand_home_directory(wcstring &input) {
}
}
const wchar_t *realhome = home ? wrealpath(home->as_string(), NULL) : nullptr;
maybe_t<wcstring> realhome;
if (home)
realhome = wrealpath(home->as_string());
if (realhome) {
input.replace(input.begin(), input.begin() + tail_idx, realhome);
input.replace(input.begin(), input.begin() + tail_idx, *realhome);
} else {
input[0] = L'~';
}
free((void *)realhome);
}
}

View file

@ -338,10 +338,10 @@ void safe_perror(const char *message) {
errno = err;
}
wchar_t *wrealpath(const wcstring &pathname, wchar_t *resolved_path) {
if (pathname.size() == 0) return NULL;
maybe_t<wcstring> wrealpath(const wcstring &pathname) {
if (pathname.empty()) return none();
cstring real_path("");
cstring real_path;
cstring narrow_path = wcs2string(pathname);
// Strip trailing slashes. This is needed to be bug-for-bug compatible with GNU realpath which
@ -370,7 +370,7 @@ wchar_t *wrealpath(const wcstring &pathname, wchar_t *resolved_path) {
} else {
// Only call realpath() on the portion up to the last component.
narrow_res = realpath(narrow_path.substr(0, pathsep_idx).c_str(), tmpbuff);
if (!narrow_res) return NULL;
if (!narrow_res) return none();
pathsep_idx++;
}
real_path.append(narrow_res);
@ -379,12 +379,7 @@ wchar_t *wrealpath(const wcstring &pathname, wchar_t *resolved_path) {
real_path.append(narrow_path.substr(pathsep_idx, cstring::npos));
}
}
wcstring wreal_path = str2wcstring(real_path);
if (resolved_path) {
wcslcpy(resolved_path, wreal_path.c_str(), PATH_MAX);
return resolved_path;
}
return wcsdup(wreal_path.c_str());
return str2wcstring(real_path);
}
wcstring wdirname(const wcstring &path) {

View file

@ -10,6 +10,7 @@
#include <string>
#include "common.h"
#include "maybe.h"
/// Wide character version of fopen(). This sets CLO_EXEC.
FILE *wfopen(const wcstring &path, const char *mode);
@ -58,10 +59,9 @@ const wcstring wgetcwd();
/// Wide character version of chdir().
int wchdir(const wcstring &dir);
/// Wide character version of realpath function. Just like the GNU version of realpath, wrealpath
/// will accept 0 as the value for the second argument, in which case the result will be allocated
/// using malloc, and must be free'd by the user.
wchar_t *wrealpath(const wcstring &pathname, wchar_t *resolved_path);
/// Wide character version of realpath function.
/// \returns the canonicalized path, or none if the path is invalid.
maybe_t<wcstring> wrealpath(const wcstring &pathname);
/// Wide character version of readdir().
bool wreaddir(DIR *dir, wcstring &out_name);