Skip to content

Instantly share code, notes, and snippets.

@carenas
Created Nov 2, 2021
Embed
What would you like to do?
testcase for fseek's issue in BSD with buffered stdin
#!/bin/sh
# set CC to a suitable compiler
# pass -DWORKAROUND (or equivalent) for testing "workaround" instead
if [ ! -n "$CC" ]; then
for CC in cc gcc clang xlc cl; do
if command -v $CC >/dev/null; then
break
fi
done
fi
cat >f.c <<EOF
/*
usage: a.out <f.in
-DWORKAROUND for building POSIX workaround
*/
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
int main(void)
{
long pos;
char buf[3] = {0};
int rc;
off_t o;
rc = fread(buf, 1, 2, stdin); /* read 2 characters */
assert(rc == 2); /* also ensures !feof(stdin) and a seekable pos!=0 */
pos = ftell(stdin); /* same behaviour if using ftello or fgetpos */
assert(pos > 0);
rc = fread(buf, 1, 2, stdin);
printf("%s", buf); /* includes \n already */
assert(rc == 2);
#ifndef WORKAROUND
rc = fseek(stdin, pos, SEEK_SET); /* also BUG with fsetpos */
assert(rc == 0);
#else
o = lseek(0, pos, SEEK_SET);
assert(o == pos);
#endif
return 0;
}
EOF
cat >f.in <<EOF
1
2
3
4
EOF
$CC $1 f.c
exec 3<f.in
O1=`./a.out <&3`
O2=`head -1 <&3`
exec 3<&-
if [ "$O1" != "$O2" ]; then
echo "BUG: $O1 != $O2"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment