+2018-06-24 Bruno Haible <bruno@clisp.org>
+
+ af_alg: Fail in continuable manner on Linux/powerpc64le.
+ Reported by Assaf Gordon <assafgordon@gmail.com>
+ in <https://lists.gnu.org/archive/html/coreutils/2018-06/msg00034.html>.
+ * lib/af_alg.c (afalg_stream): On non-seekable streams, try a single-
+ byte send() as the first round.
+
2018-06-24 Bruno Haible <bruno@clisp.org>
af_alg: Fix state of stream after sendfile() succeeds.
for (;;)
{
char buf[BLOCKSIZE];
- ssize_t size = fread (buf, 1, sizeof buf, stream);
+ /* When the stream is not seekable, start with a single-byte block,
+ so that we can use ungetc() in the case that send() fails. */
+ size_t blocksize = (nseek == 0 && off < 0 ? 1 : BLOCKSIZE);
+ ssize_t size = fread (buf, 1, blocksize, stream);
if (size == 0)
{
/* On Linux < 4.9, the value for an empty stream is wrong (all 0).
nseek -= size;
if (send (ofd, buf, size, MSG_MORE) != size)
{
- result = (fseeko (stream, nseek, SEEK_CUR) == 0
- ? -EAFNOSUPPORT : -EIO);
+ if (nseek == -1)
+ {
+ /* 1 byte of pushback buffer is guaranteed on stream, even
+ if stream is not seekable. */
+ ungetc ((unsigned char) buf[0], stream);
+ result = -EAFNOSUPPORT;
+ }
+ else if (fseeko (stream, nseek, SEEK_CUR) == 0)
+ /* The position of stream has been restored. */
+ result = -EAFNOSUPPORT;
+ else
+ result = -EIO;
break;
}
if (result == 0 && read (ofd, resblock, hashlen) != hashlen)
{
if (nseek == 0 || fseeko (stream, nseek, SEEK_CUR) == 0)
+ /* The position of stream has been restored. */
result = -EAFNOSUPPORT;
else
result = -EIO;