I'm trying to use std::filesystem::current_path()
to change the working directory to something that might be a symlink. If the target is a symlink, the link is getting resolved and the working directory becomes the target of the link rather than the path I specified. My main issue with this is it makes relative paths incorrect.
As an example:
#include <filesystem>
#include <iostream>
using namespace std;
using namespace std::filesystem;
auto main(int, char **) -> int {
// create absolute directory then symlink to it
create_directory("/tmp/tgt");
create_directory_symlink("/tmp/tgt", "/tmp/dir");
cout << "cwd0: " << current_path() << '\n';
current_path("/tmp/dir");
cout << "cwd1: " << current_path() << '\n';
remove("/tmp/tgt");
remove("/tmp/dir");
return 0;
}
Running this from within the /tmp
directory, the output is.
cwd0: "/tmp"
cwd1: "/tmp/tgt"
but what I want is for cwd1
to show /tmp/dir
Is there a portable mechanism to change the working directory to a symlink?
I'm trying to use std::filesystem::current_path()
to change the working directory to something that might be a symlink. If the target is a symlink, the link is getting resolved and the working directory becomes the target of the link rather than the path I specified. My main issue with this is it makes relative paths incorrect.
As an example:
#include <filesystem>
#include <iostream>
using namespace std;
using namespace std::filesystem;
auto main(int, char **) -> int {
// create absolute directory then symlink to it
create_directory("/tmp/tgt");
create_directory_symlink("/tmp/tgt", "/tmp/dir");
cout << "cwd0: " << current_path() << '\n';
current_path("/tmp/dir");
cout << "cwd1: " << current_path() << '\n';
remove("/tmp/tgt");
remove("/tmp/dir");
return 0;
}
Running this from within the /tmp
directory, the output is.
cwd0: "/tmp"
cwd1: "/tmp/tgt"
but what I want is for cwd1
to show /tmp/dir
Is there a portable mechanism to change the working directory to a symlink?
Share Improve this question edited Feb 6 at 20:19 genpfault 52.1k12 gold badges91 silver badges148 bronze badges asked Feb 6 at 19:21 ryan0270ryan0270 1,18712 silver badges35 bronze badges2 Answers
Reset to default 3std::filesystem::current_path()
"Changes the current working directory to p, as if by POSIX chdir
", and chdir()
follows symlinks. There is no option in the standard library to avoid this.
Your working directory has to be a directory. A symlink is not a directory. So no, this feature does not exist.
On the other hand, shells often emulate such behavior. For instance, in bash, if you do
cd /tmp
ln -s /some/other/dir foo
cd foo
cd ..
you end up back in /tmp
, not in /some/other
. The explanation is that cd ..
doesn't actually do chdir("..")
(which would put you in /some/other
for exactly the reason you stated). Instead, the shell uses an internal variable to keep track of the "logical" current directory, based on the sequence of previous cd
commands, and compute what the new working directory should be on that basis.
So if you want behavior like that, you'll have to emulate it yourself, just as shells do. It's not something the OS provides for you.