aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/builtin.cpp
diff options
context:
space:
mode:
authorGravatar Kurtis Rader <krader@skepticism.us>2016-04-13 17:14:50 -0700
committerGravatar Kurtis Rader <krader@skepticism.us>2016-04-28 16:03:27 -0700
commit6c329e8a839c1b5eeaf2e545b4f4084c3a8830f7 (patch)
tree65597d006e0cd94e9f74b95b67c75451b2daecd8 /src/builtin.cpp
parent5fa8370c133738aa21a3b4a7d3a89f9188068498 (diff)
provide a realpath implementation
Not all distros have a `realpath` command. Provide a function that uses the real command if available else use the fish builtin. Fixes #2932
Diffstat (limited to 'src/builtin.cpp')
-rw-r--r--src/builtin.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/builtin.cpp b/src/builtin.cpp
index b0356543..70b379b1 100644
--- a/src/builtin.cpp
+++ b/src/builtin.cpp
@@ -2988,6 +2988,33 @@ int builtin_false(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
return STATUS_BUILTIN_ERROR;
}
+/// An implementation of the external realpath command that doesn't support any options. It's meant
+/// to be used only by scripts which need to be portable. In general scripts shouldn't invoke this
+/// directly. They should just use `realpath` which will fallback to this builtin if an external
+/// command cannot be found. This behaves like the external `realpath --canonicalize-existing`;
+/// that is, it requires all path components, including the final, to exist.
+int builtin_fish_realpath(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
+ int argc = builtin_count_args(argv);
+
+ if (argc != 2) {
+ streams.err.append_format(_(L"%ls: Expected one argument, got %d\n"), argv[0], argc - 1);
+ return STATUS_BUILTIN_ERROR;
+ }
+
+ wchar_t *real_path = wrealpath(argv[1], NULL);
+ if (real_path) {
+ // Yay! We could resolve the path.
+ streams.out.append(real_path);
+ free((void *)real_path);
+ } else {
+ // The path isn't a simple filename and couldn't be resolved to an absolute path.
+ streams.err.append_format(_(L"%ls: Invalid path: %ls\n"), argv[0], argv[1]);
+ return STATUS_BUILTIN_ERROR;
+ }
+ streams.out.append(L"\n");
+ return STATUS_BUILTIN_OK;
+}
+
// END OF BUILTIN COMMANDS
// Below are functions for handling the builtin commands.
// THESE MUST BE SORTED BY NAME! Completion lookup uses binary search.
@@ -3027,6 +3054,8 @@ static const builtin_data_t builtin_datas[] = {
{L"exit", &builtin_exit, N_(L"Exit the shell")},
{L"false", &builtin_false, N_(L"Return an unsuccessful result")},
{L"fg", &builtin_fg, N_(L"Send job to foreground")},
+ {L"fish_realpath", &builtin_fish_realpath,
+ N_(L"Convert path to absolute path without symlinks")},
{L"for", &builtin_generic, N_(L"Perform a set of commands multiple times")},
{L"function", &builtin_generic, N_(L"Define a new function")},
{L"functions", &builtin_functions, N_(L"List or remove functions")},