0

I'm trying to create a C program that emulates a Bash shell.

For the cd file instruction I use chdir("file") but it isn't correct because chdir() always resolves symlinks while cd doesn't by default.

I'm looking for a way to get a function that changes the current working directory without resolving symlinks.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
babaoreum
  • 23
  • 5
  • 1
    Why do you think `cd` does not resolve symlinks? – jhnc Nov 07 '22 at 21:02
  • Because I've tested it. – babaoreum Nov 07 '22 at 21:27
  • 2
    Perhaps you are using "resolve" with an different definition? bash `cd` always resolves symlinks, but it may pre- or post-process instances of `..` in the provided path (`cd -L`, `cd -P`) and it may search elsewhere for relative paths (`CDPATH`). If it didn't resolve the symlinks, it woudn't be able to change directory. Consider: `ln -s /nonexistent x; cd x` – jhnc Nov 07 '22 at 21:32
  • Sorry if I'm misunderstood. When I do `ln -s dir dir2` then `cd dir2` then `pwd` the path is `xxx/dir2`. It cannot be achieved with `chdir()`. This is what I mean. – babaoreum Nov 07 '22 at 21:43
  • `$PWD` is a variable that bash manages. It doesn't have to match `realpath .`: `mkdir -p a/b/c b c; ln -s a/b/c x; p()(echo "# cd $*";cd "$@"; echo "PWD=$PWD"; echo "realpath=$(realpath .)"); q()(p "$@";p -L "$@"; p -P "$@"); q x; q x/../c` – jhnc Nov 07 '22 at 21:59
  • I know, but I want to emulate a bash shell. $PWD might be useful to get the initial non-resolved path, but then I have to use chdir() to change the current working directory – babaoreum Nov 07 '22 at 22:10
  • 1
    You have to _yourself_ store the path, as Bash does. In Bash program `chdir()` also returns the resolved path. – KamilCuk Nov 07 '22 at 22:12
  • The thing is the `cd` instruction in bash does not resolves symlinks, whereas the `chdir()` function in C resolves them. I want to find a way NOT to resolve symlinks in C. – babaoreum Nov 07 '22 at 23:01
  • Maybe I am not using the word "resolve" right. If have a symlink `france2 -> world/europe/france` i want `cd france2/../` to give me my current path. Is that clear? – babaoreum Nov 07 '22 at 23:06
  • For better or worse, there is `cd -P /some/path` (physical) and `cd -L /some/path` (logical) and you can control whether Bash uses physical or logical mappings (Bash manual for [`cd`](https://www.gnu.org/software/bash/manual/bash.html#index-cd)). By default, the mode is 'logical'; you can set 'physical' mode with [`set -P`](https://www.gnu.org/software/bash/manual/bash.html#index-set) or `set -o physical`. You unset that with `set +P` or `set +o physical`. The shell does a lot of tinkering to fool you about where the current directory is. – Jonathan Leffler Nov 08 '22 at 04:46
  • I know it, I'm trying to emulate a Bash shell. I use readlink() to read some instruction (in this case, cd some/path and I want my program to emulate what cd would do, ie change the current working directory without resolving symlinks. How to do that? – babaoreum Nov 08 '22 at 16:42

0 Answers0