trace mode fails with sh: /usr/bin/tar: No such file or directory

Jan Stary hans at stare.cz
Sun Dec 24 12:50:48 UTC 2017


On Dec 24 11:44:21, hans at stare.cz wrote:
> On Dec 19 15:09:25, raimue at macports.org wrote:
> > On 2017-12-18 00:20, Clemens Lang wrote:
> > > We debugged this on IRC recently. Turns out the culprit is
> > >   https://github.com/macports/macports-base/commit/3d4c9b342d28abd0b7aaf7eb70fa4862e898542c#diff-94a7b4a6e8f8c93116146f83a92a7f44
> > > 
> > > /usr/bin/tar is a symlink to bsdtar. copyfile(3) copies the symlink, the
> > > previous method opened the file (dereferencing the symlink) and copied
> > > its contents.
> > > 
> > > When the symlink is copied (because copyfile(3) is used), the
> > > destination of the symlink is not copied, which eventually leads to file
> > > not found.
> > 
> > According to the documentation of copyfile(3), it should always follow
> > the symlink unless COPYFILE_NOFOLLOW was specified. I even checked its
> > implementation [1]. Internally, clonefileat(2) will only be called with
> > CLONE_NOFOLLOW when COPYFILE_NOFOLLOW was given – and we do not do that.
> > 
> > I did a quick test with the following code snippet which should be
> > roughly equivalent to what we use in our sip_copy_proc.c:
> > 
> > ---8<---
> > 
> > #include <copyfile.h>
> > #include <stdio.h>
> > 
> > int main(int argc, char *argv[]) {
> >     int ret;
> > 
> >     ret = copyfile("/usr/bin/tar", "/tmp/tar", NULL,
> >               COPYFILE_ALL | COPYFILE_CLONE);
> >     if (ret) {
> >         perror("copyfile");
> >         return 1;
> >     }
> > 
> >     return 0;
> > }
> > 
> > --->8---
> > 
> > I could not reproduce the problem as described on 10.12.6 Sierra. After
> > running this program, /tmp/tar is a regular file and contains the same
> > contents as /usr/bin/bsdtar.
> > 
> > I also tested on a VM with 10.13.0 High Sierra, as I still had that
> > around. It also works there as expected.
> > 
> > Does this mean Apple has a regression how copyfile(3) works with
> > symlinks on macOS 10.13.2? Can somebody with 10.13.2 please test the
> > code above and confirm this?
> 
> On my 10.13.2, this results in
> 
> $ ls -l /tmp/tar 
> lrwxr-xr-x  1 hans  wheel  6 Dec 10 11:39 /tmp/tar -> bsdtar

But without the COPYFILE_CLONE, it works as expected:


#include <copyfile.h>
#include <stdio.h>
#include <err.h>

#define SRC "/usr/bin/tar"
#define DST "/tmp/tar"

int
main()
{
	/* With COPYFILE_CLONE, it doesn't follow the /usr/bin/tar symlink */
	if (copyfile(SRC, DST, NULL, COPYFILE_ALL))
		err(1, "%s to %s", SRC, DST);
	return 0;
}


$ cc -o copyfile copyfile.c
$ ./copyfile

$ ls -l /usr/bin/{,bsd}tar /tmp/tar 
-rwxr-xr-x  1 hans  wheel  71024 Dec  1 20:38 /tmp/tar
-rwxr-xr-x  1 root  wheel  71024 Dec  1 20:38 /usr/bin/bsdtar
lrwxr-xr-x  1 root  wheel      6 Dec 10 11:39 /usr/bin/tar -> bsdtar

$ uname -a
Darwin fitbook.local 17.3.0 Darwin Kernel Version 17.3.0: Thu Nov 9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64 x86_64

	Jan



More information about the macports-dev mailing list