Jeff King [off-list ref] writes:
The packetize() function takes its input on stdin, and requires 4
separate sub-processes to format a simple string. We can do much better
by getting the length via the shell's "${#packet}" construct. The one
caveat is that the shell can't put a NUL into a variable, so we'll have
to continue to provide the stdin form for a few calls.
Yuck. Binary protocol and shell variables do not mix well.
Documentation/CodingGuidelines forbids ${#parameter} in the first
place and we seem to use it only when we know we are using bash.
Perhaps we should start considering to lift it. I dunno.
quoted hunk
+# convert function arguments or stdin (if not arguments given) to pktline
+# representation. If multiple arguments are given, they are separated by
+# whitespace and put in a single packet. Note that data containing NULs must be
+# given on stdin, and that empty input becomes an empty packet, not a flush
+# packet (for that you can just print 0000 yourself).
quoted hunk
packetize() {
+ if test $# -gt 0
+ then
+ packet="$*"
+ printf '%04x%s' "$((4 + ${#packet}))" "$packet"
This allows
packetize "want $hash_head"
to be written like so:
packetize want "$hash_head"
which maybe is a handy thing to do.
quoted hunk
+ else
+ cat >packetize.tmp &&
+ len=$(wc -c <packetize.tmp) &&
+ printf '%04x' "$(($len + 4))" &&
+ cat packetize.tmp &&
+ rm -f packetize.tmp
perl -e '
my $data = do { local $?; <STDIN> };
printf "%04x%s", length($data), $data;
'
That's one process but much heavier than cat/wc/printf/cat, I guess.
quoted hunk
+ fi
}
# Parse the input as a series of pktlines, writing the result to stdout.