From 1f130bcc9c939f33aa9df937e22a73a64d6cf853 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 11 Oct 2017 00:08:26 -0700 Subject: [PATCH] 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. --- src/builtin_realpath.cpp | 6 ++---- src/expand.cpp | 8 +++++--- src/wutil.cpp | 15 +++++---------- src/wutil.h | 8 ++++---- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/builtin_realpath.cpp b/src/builtin_realpath.cpp index a970420cc..a7858ebb8 100644 --- a/src/builtin_realpath.cpp +++ b/src/builtin_realpath.cpp @@ -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]); diff --git a/src/expand.cpp b/src/expand.cpp index ce908e591..d5e8e25b7 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -1182,13 +1182,15 @@ static void expand_home_directory(wcstring &input) { } } - const wchar_t *realhome = home ? wrealpath(home->as_string(), NULL) : nullptr; + maybe_t 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); } } diff --git a/src/wutil.cpp b/src/wutil.cpp index 5eb99dac7..82bf2ec30 100644 --- a/src/wutil.cpp +++ b/src/wutil.cpp @@ -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 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) { diff --git a/src/wutil.h b/src/wutil.h index 618056956..959b5880a 100644 --- a/src/wutil.h +++ b/src/wutil.h @@ -10,6 +10,7 @@ #include #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 wrealpath(const wcstring &pathname); /// Wide character version of readdir(). bool wreaddir(DIR *dir, wcstring &out_name);