TEST(stdio_ext, __fpending) { FILE* fp = fopen("/dev/null", "w"); ASSERT_EQ(0U, __fpending(fp)); ASSERT_EQ('x', fputc('x', fp)); ASSERT_EQ(1U, __fpending(fp)); ASSERT_EQ('y', fputc('y', fp)); ASSERT_EQ(2U, __fpending(fp)); fflush(fp); ASSERT_EQ(0U, __fpending(fp)); fclose(fp); }
int main (void) { ASSERT (__fpending (stdout) == 0); fputs ("foo", stdout); ASSERT (__fpending (stdout) == 3); fflush (stdout); ASSERT (__fpending (stdout) == 0); exit (0); }
TEST(stdio_ext, _flushlbf) { FILE* fp = fopen("/dev/null", "w"); char buf[128]; ASSERT_EQ(0, setvbuf(fp, buf, _IOLBF, sizeof(buf))); ASSERT_EQ('a', fputc('a', fp)); ASSERT_EQ(1U, __fpending(fp)); _flushlbf(); ASSERT_EQ(0U, __fpending(fp)); fclose(fp); }
void close_stdout (void) { bool prev_fail = ferror (stdout); bool none_pending = (0 == __fpending (stdout)); bool fclose_fail = fclose (stdout); if (prev_fail || fclose_fail) { int e = fclose_fail ? errno : 0; char const *write_error; /* If ferror returned zero, no data remains to be flushed, and we'd otherwise fail with EBADF due to a failed fclose, then assume that it's ok to ignore the fclose failure. That can happen when a program like cp is invoked like this `cp a b >&-' (i.e., with stdout closed) and doesn't generate any output (hence no previous error and nothing to be flushed). */ if (e == EBADF && !prev_fail && none_pending) return; write_error = _("write error"); if (file_name) error (exit_failure, e, "%s: %s", quotearg_colon (file_name), write_error); else error (exit_failure, e, "%s", write_error); } }
TEST(stdio_ext, __fpurge) { FILE* fp = tmpfile(); ASSERT_EQ('a', fputc('a', fp)); ASSERT_EQ(1U, __fpending(fp)); __fpurge(fp); ASSERT_EQ(0U, __fpending(fp)); ASSERT_EQ('b', fputc('b', fp)); ASSERT_EQ('\n', fputc('\n', fp)); ASSERT_EQ(2U, __fpending(fp)); rewind(fp); char buf[16]; char* s = fgets(buf, sizeof(buf), fp); ASSERT_TRUE(s != nullptr); ASSERT_STREQ("b\n", s); fclose(fp); }
int close_stream( FILE *f ) { if ( ferror(f) ) { if ( !fclose(f) ) { errno = 0; } return EOF; } if ( fclose(f) && (__fpending(f) || errno != EBADF) ) { return EOF; } return 0; }
void close_stdout_status (int status) { int e = ferror (stdout) ? 0 : -1; if (__fpending (stdout) == 0) return; if (fclose (stdout) != 0) e = errno; if (0 <= e) { char const *write_error = _("write error"); if (file_name) error (status, e, "%s: %s", quotearg_colon (file_name), write_error); else error (status, e, "%s", write_error); } }
void close_stdout (void) { int e = ferror (stdout) ? 0 : -1; /* If the stream's error bit is clear and there is nothing to flush, then return right away. */ if (e && __fpending (stdout) == 0) return; if (fclose (stdout) != 0) e = errno; if (0 <= e) { char const *write_error = _("write error"); if (file_name) error (exit_failure, e, "%s: %s", quotearg_colon (file_name), write_error); else error (exit_failure, e, "%s", write_error); } }
int close_stream (FILE *stream) { bool some_pending = (__fpending (stream) != 0); bool prev_fail = (ferror (stream) != 0); bool fclose_fail = (fclose (stream) != 0); /* Return an error indication if there was a previous failure or if fclose failed, with one exception: ignore an fclose failure if there was no previous error, no data remains to be flushed, and fclose failed with EBADF. That can happen when a program like cp is invoked like this `cp a b >&-' (i.e., with standard output closed) and doesn't generate any output (hence no previous error and nothing to be flushed). */ if (prev_fail || (fclose_fail && (some_pending || errno != EBADF))) { if (! fclose_fail) errno = 0; return EOF; } return 0; }