diff --git a/NEWS.md b/NEWS.md index dcabb06f..9790be0a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,11 @@ UNRELEASED * The `chroot`(8) wrapper and `fakechroot`(1) command can work with POSIX shell. +* The `fakechroot`(1) command now supports an environment variable called + `FAKECHROOT_NOEXPAND_SYMLINK_TARGET`, which disables path expansion on + the targets of symlink syscalls. This more closely resmebles traditional + `chroot` behavior, which treats the target of a symlink as an opaque + string rather than a path. ## Version 2.19 diff --git a/man/fakechroot.pod b/man/fakechroot.pod index 3b77abc0..9e73b878 100644 --- a/man/fakechroot.pod +++ b/man/fakechroot.pod @@ -302,6 +302,16 @@ to make debootstrap(8) working correctly. To prevent some looping, the command substitution is done only if C variable is not set currently. +=item B + +Fakechroot defaults to expanding the target of a symlink so that any absolute +symlinks created inside a fakechroot session will continue to work outside of +it. If that behavior is undesirable, setting this environment variable will +cause the symlink and symlinkat syscalls to create symlinks with the raw target +paths requested by the invoker. Note that this does not affect the path of the +symlink being created in any way, which still gets expanded according to the +usual chroot rules. + =item B, B Fakechroot is implemented by wrapping system calls. This is accomplished by diff --git a/src/libfakechroot.c b/src/libfakechroot.c index 16d597e5..4ee29931 100644 --- a/src/libfakechroot.c +++ b/src/libfakechroot.c @@ -59,6 +59,7 @@ char *preserve_env_list[] = { "FAKECHROOT_ELFLOADER_OPT_ARGV0", "FAKECHROOT_EXCLUDE_PATH", "FAKECHROOT_LDLIBPATH", + "FAKECHROOT_NOEXPAND_SYMLINK_TARGET", "FAKECHROOT_VERSION", "FAKEROOTKEY", "FAKED_MODE", diff --git a/src/symlink.c b/src/symlink.c index 1c8965d3..8a9c7748 100644 --- a/src/symlink.c +++ b/src/symlink.c @@ -27,7 +27,10 @@ wrapper(symlink, int, (const char * oldpath, const char * newpath)) { char tmp[FAKECHROOT_PATH_MAX]; debug("symlink(\"%s\", \"%s\")", oldpath, newpath); - expand_chroot_rel_path(oldpath); + char *noexpand_symlink_target = getenv("FAKECHROOT_NOEXPAND_SYMLINK_TARGET"); + if (!noexpand_symlink_target) + expand_chroot_rel_path(oldpath); + strcpy(tmp, oldpath); oldpath = tmp; expand_chroot_path(newpath); diff --git a/src/symlinkat.c b/src/symlinkat.c index 0b948c8c..8da9ecfe 100644 --- a/src/symlinkat.c +++ b/src/symlinkat.c @@ -30,7 +30,10 @@ wrapper(symlinkat, int, (const char * oldpath, int newdirfd, const char * newpat { char tmp[FAKECHROOT_PATH_MAX]; debug("symlinkat(\"%s\", %d, \"%s\")", oldpath, newdirfd, newpath); - expand_chroot_rel_path(oldpath); + char *noexpand_symlink_target = getenv("FAKECHROOT_NOEXPAND_SYMLINK_TARGET"); + if (!noexpand_symlink_target) + expand_chroot_rel_path(oldpath); + strcpy(tmp, oldpath); oldpath = tmp; expand_chroot_path_at(newdirfd, newpath);