A tar anomaly

During my customary cpan-outdated | cpanm cycle, I ran into a test failure:

t\01_compile.t .. ok
Use of uninitialized value $zero in concatenation (.) or string at t\02_all.t line 38.

#   Failed test 'zero = '
#   at t\02_all.t line 38.
# Looks like you failed 1 test of 6.

I switched to the work directory, and ran perl Makefile.PL:

C:\...\File-Which-1.20> perl Makefile.PL
Checking if your kit is complete...
Warning: the following files are missing in your kit:
Please inform the author.
Generating a nmake-style Makefile
Writing Makefile for File::Which
Writing MYMETA.yml and MYMETA.json

Without thinking, I decided this must have been a simple oversight on the part of the author(s), and I filed a bug report.

Slaven immediately noticed something else was going on, and, soon after, found a thread on Cygwin’s mailing list referring to something that would explain the problem. Apparently, I had run into something that was by design. I just had never noticed this before (and I have been using Cygwin for longer than I care to remember). Note that I am rather confused in the issue thread. That usually happens to me when I am trying to grasp for answers in the face of something that defies logic.

Here is what I had in my %PATH%:

C:\...\File-Which-1.20> pwhich -a tar
C:\Program Files\git\usr\bin\tar.EXE

Prior to installing Visual Studio 2015 RC2 CTP, I usually worked with no Cygwin or MinGW utilities in my path, and only added them when a specific need arose. This worked really well with cpanm: HTTP::Tiny and Archive::Tar do the job fine.

But, with this release, I decided it would not hurt too much to append C:\Program Files\git\bin and C:\Program Files\git\usr\bin to my %PATH%, which led to my discovery of this problem. I am pointing this out, because it is important to keep in mind that this is not a Cygwin-specific issue.

So, what’s going on? How come both 0 and 0.exe, and all and all.exe were all present in File-Which-1.20.tar.gz, but 0.exe and all.exe disappeared during extraction.

Extracting files from a tar archive is not supposed to evaporate them now, is it?

Time for some screenshots. First, using tar bundled with git distributed alongside Visual Studio 2015 RC2 CTP by Microsoft:

[ screenshot ]

Now, tar from Cygwin:

[ screenshot ]

And, finally, tar from MSYS2 MinGW64:

[ screenshot ]

For the record, if I repeat the same steps using 7z, I always get the expected results.

What these screenshots show are: 1) If you add test.exe and test to a tar archive in that order, you lose test.exe on extraction; 2) If you touch test.exe and test in that order, you lose test.

Others have observed this behavior before. I just wasn’t aware of it, and it caught me by surprise.

I am afraid following that thread did not provide me with a lot of enlightenment regarding why this particular trade-off was the best possible tradeoff. For example, Christopher Faylor says:

What you are seeing is a Cygwin accommodation for the fact that .exe is a special extension. Cygwin is not a new project. Its handling of .exe has been hashed and rehashed throughout the life of the project. The current behavior is the compromise that we’ve settled on.

So, what you are seeing is expected. Continuing to argue without familiarizing yourself with past discussions is not likely to expose anything new.

It would be nice to see how this current consensus came about, but, I doubt there will be any changes.

I am confused as to why this behavior also carries over to MinGW versions of these tools. After all, I thought the whole point of MinGW was not to try to provide a POSIX layer.

Of course, none of this really helps you if you are just trying to get things done. Graham fixed the problem by putting auxilary test files for Windows and other systems in separate subdirectories, therefore avoiding the requirement to have 0 and 0.exe, and all and all.exe in the same location.

My inference from the various discussions is that if you can get libarchive to build using, say, Microsoft tools, the resulting utilities would work the way one expects. My first naive attempts did not work well.

In the mean time, just be aware of this problem.

Thank you Slaven and Graham for your work.

PS: You can discuss this post on r/perl and HN.