stdio: line buffering, test fgetpos and fsetpos (DONE)

This commit is contained in:
Lephenixnoir 2022-01-10 21:32:24 +01:00
parent 0c2f81e5bb
commit 06b66252c9
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
5 changed files with 46 additions and 18 deletions

24
STATUS
View File

@ -91,13 +91,13 @@ TEST: Function/symbol/macro needs to be tested
7.19.4.3 tmpfile TODO
7.19.4.4 tmpnam TODO
7.19.5.1 fclose TEST
7.19.5.2 fflush TEST
7.19.5.3 fopen TEST
7.19.5.1 fclose -
7.19.5.2 fflush -
7.19.5.3 fopen TEST ("a" and "+" modes remain)
(EXT) fdopen TEST
7.19.5.4 freopen TEST
7.19.5.5 setbuf TEST
7.19.5.6 setvbuf TEST
7.19.5.5 setbuf -
7.19.5.6 setvbuf -
7.19.6.1 fprintf LDEPS(fwrite)
7.19.6.2 fscanf TODO
@ -130,14 +130,14 @@ TEST: Function/symbol/macro needs to be tested
7.19.7.10 puts LDEPS(fputs)
7.19.7.11 ungetc TODO
7.19.8.1 fread TEST
7.19.8.2 fwrite TEST
7.19.8.1 fread TEST ("a" and "+" modes remain)
7.19.8.2 fwrite TEST ("a" and "+" modes remain)
7.19.9.1 fgetpos TEST
7.19.9.2 fseek TEST
7.19.9.3 fsetpos TEST
7.19.9.4 ftell TEST
7.19.9.5 rewind TEST
7.19.9.1 fgetpos -
7.19.9.2 fseek -
7.19.9.3 fsetpos -
7.19.9.4 ftell -
7.19.9.5 rewind -
7.19.10.1 clearerr -
7.19.10.2 feof -

View File

@ -77,6 +77,12 @@ ssize_t __fp_write(FILE *fp, void const *data, size_t size)
{
size_t written = 0;
if(fp->append) {
int rc = fseek(fp, 0, SEEK_END);
if(rc < 0)
return EOF;
}
while(written < size) {
ssize_t rc = write(fp->fd, data + written, size - written);

View File

@ -4,6 +4,11 @@
size_t fread(void *data, size_t membsize, size_t nmemb, FILE *fp)
{
if(!fp->readable) {
fp->error = 1;
return 0;
}
size_t size;
if(__builtin_umul_overflow(membsize, nmemb, &size)) {
fp->error = 1;

View File

@ -6,7 +6,10 @@ int fsetpos(FILE *fp, fpos_t const *pos)
if(fflush(fp) == EOF)
return -1;
lseek(fp->fd, *pos, SEEK_SET);
off_t rc = lseek(fp->fd, *pos, SEEK_SET);
if(rc < 0)
return -1;
fp->fdpos = *pos;
fp->eof = 0;
return 0;

View File

@ -4,6 +4,11 @@
size_t fwrite(void const *data, size_t membsize, size_t nmemb, FILE *fp)
{
if(!fp->writable) {
fp->error = 1;
return 0;
}
size_t size;
if(__builtin_umul_overflow(membsize, nmemb, &size)) {
fp->error = 1;
@ -17,20 +22,29 @@ size_t fwrite(void const *data, size_t membsize, size_t nmemb, FILE *fp)
__fp_buffer_mode_write(fp);
// TODO: fwrite: line buffering
size_t size_written = 0;
while(size_written < size) {
/* Fill the buffer */
size_t size_frag = fp->bufsize - fp->bufpos;
if(size_frag > size - size_written)
void const *last_line = NULL;
if(size_frag >= size - size_written) {
size_frag = size - size_written;
/* In the last run, if line buffering is enabled and
there is a newline, stop at that newline and flush
before the last write to buffer */
if(fp->bufmode == _IOLBF) last_line = memrchr(
data + size_written, '\n', size_frag);
}
if(last_line)
size_frag = (last_line + 1) - (data + size_written);
memcpy(fp->buf + fp->bufpos, data + size_written, size_frag);
size_written += size_frag;
fp->bufpos += size_frag;
if(fp->bufpos >= fp->bufsize) {
if(fp->bufpos >= fp->bufsize || last_line) {
ssize_t rc = __fp_write(fp, fp->buf, fp->bufpos);
if(rc <= 0) /* error */
break;