]> git.ipfire.org Git - thirdparty/git.git/commit - t/test-lib-functions.sh
t9300: factor out portable "head -c" replacement
authorJeff King <peff@peff.net>
Thu, 30 Jun 2016 09:07:54 +0000 (05:07 -0400)
committerJunio C Hamano <gitster@pobox.com>
Fri, 1 Jul 2016 17:17:39 +0000 (10:17 -0700)
commit48860819e80260abae480407d0bd75dd58e70bb7
treeaa6d9940e317423ce6025f17320f7e091b29ebb4
parent05219a1276341e72d8082d76b7f5ed394b7437a4
t9300: factor out portable "head -c" replacement

It is sometimes useful to be able to read exactly N bytes from a
pipe. Doing this portably turns out to be surprisingly difficult
in shell scripts.

We want a solution that:

  - is portable

  - never reads more than N bytes due to buffering (which
    would mean those bytes are not available to the next
    program to read from the same pipe)

  - handles partial reads by looping until N bytes are read
    (or we see EOF)

  - is resilient to stray signals giving us EINTR while
    trying to read (even though we don't send them, things
    like SIGWINCH could cause apparently-random failures)

Some possible solutions are:

  - "head -c" is not portable, and implementations may
    buffer (though GNU head does not)

  - "read -N" is a bash-ism, and thus not portable

  - "dd bs=$n count=1" does not handle partial reads. GNU dd
    has iflags=fullblock, but that is not portable

  - "dd bs=1 count=$n" fixes the partial read problem (all
    reads are 1-byte, so there can be no partial response).
    It does make a lot of write() calls, but for our tests
    that's unlikely to matter.  It's fairly portable. We
    already use it in our tests, and it's unlikely that
    implementations would screw up any of our criteria. The
    most unknown one would be signal handling.

  - perl can do a sysread() loop pretty easily. On my Linux
    system, at least, it seems to restart the read() call
    automatically. If that turns out not to be portable,
    though, it would be easy for us to handle it.

That makes the perl solution the least bad (because we
conveniently omitted "length of code" as a criterion).
It's also what t9300 is currently using, so we can just pull
the implementation from there.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t9300-fast-import.sh
t/test-lib-functions.sh