Last active
August 29, 2015 13:57
-
-
Save submachine/9624465 to your computer and use it in GitHub Desktop.
A sequence of calls to test ftell with fseek/rewind/fread/fwrite functions while in append mode.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <assert.h> | |
#include <unistd.h> | |
const char *data = "zzzzzzzzzz"; | |
const char *more_data = "aaaaaaaaaa"; | |
#define TEST_FILE_PATH "tst-rewind-ftell.out" | |
/* http://pubs.opengroup.org/onlinepubs/007908775/xsh/stdio.html | |
When opening with any 'a' mode, the position of the file position | |
indicator after fopen is implementation defined. For glibc, this it is at | |
the end of the file for 'a' and at the beginning of the file for 'a+'. */ | |
int | |
main () | |
{ | |
FILE *stream; | |
long pos, writesize, filesize, nelem; | |
char buf[10]; | |
#define WRITE(ptr) \ | |
do \ | |
{ \ | |
writesize = strlen(ptr); \ | |
fwrite (ptr, 1, writesize, stream); \ | |
filesize += writesize; \ | |
} while (0) | |
#define FILESIZE() filesize | |
/* New file => pos is 0. */ | |
unlink (TEST_FILE_PATH); | |
filesize = 0; /* For book-keeping. */ | |
stream = fopen (TEST_FILE_PATH, "a"); | |
pos = ftell (stream); | |
assert (pos == 0); | |
/* pos moves with writes. */ | |
WRITE (data); | |
pos = ftell (stream); | |
assert (pos == FILESIZE ()); | |
/* rewind sets pos back to 0 again. */ | |
rewind (stream); | |
pos = ftell (stream); | |
assert (pos == 0); | |
/* fopen (a) sets pos at end. */ | |
fclose (stream); | |
stream = fopen (TEST_FILE_PATH, "a"); | |
pos = ftell (stream); | |
assert (pos == FILESIZE ()); | |
/* fseek(0) -> fwrite sets pos jumps back to end. */ | |
fseek (stream, 0, SEEK_SET); | |
pos = ftell (stream); | |
assert (pos == 0); | |
WRITE (more_data); | |
pos = ftell (stream); | |
assert (pos == FILESIZE ()); | |
/* fopen (a+) sets pos at beginning. */ | |
fclose (stream); | |
stream = fopen (TEST_FILE_PATH, "a+"); | |
pos = ftell (stream); | |
assert (pos == 0); | |
/* and now! write sets pos back at end. */ | |
WRITE (more_data); | |
pos = ftell (stream); | |
assert (pos == FILESIZE ()); | |
/* rewind sets pos back at 0 again. */ | |
rewind (stream); | |
pos = ftell (stream); | |
assert (pos == 0); | |
/* Since we did rewind, it is safe to read now. */ | |
/* read moves pos forward. */ | |
nelem = fread (buf, sizeof (buf), 1, stream); | |
assert (nelem == 1); | |
assert (strncmp (buf, data, sizeof (buf)) == 0); | |
pos = ftell (stream); | |
assert (pos == sizeof (buf)); | |
fseek (stream, 0, SEEK_CUR); | |
/* Since we did fseek, it is safe to write now. */ | |
/* write sets pos back at end. */ | |
WRITE (more_data); | |
pos = ftell (stream); | |
assert (pos == FILESIZE ()); | |
/* This write is there only so that we do 'fflush' | |
after it so we become eligible to read again. */ | |
WRITE (more_data); | |
fflush (stream); | |
/* Since we did fflush, it is safe to read now. */ | |
/* nothing to read, we are at EOF. */ | |
nelem = fread (buf, sizeof (buf), 1, stream); | |
assert (nelem == 0); | |
assert (feof (stream) && !ferror (stream)); | |
pos = ftell (stream); | |
assert (pos == FILESIZE ()); | |
/* read from mid-file works. */ | |
fseek (stream, sizeof (buf), SEEK_SET); | |
nelem = fread (buf, sizeof (buf), 1, stream); | |
assert (nelem == 1); | |
assert (strncmp (buf, more_data, sizeof (buf)) == 0); | |
pos = ftell (stream); | |
assert (pos == 2 * sizeof (buf)); | |
fclose (stream); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment