[PATCH 3/6] Make fflush (NULL) flush input files (bug 32369)

Florian Weimer fweimer@redhat.com
Wed Jan 15 17:27:22 GMT 2025


* Joseph Myers:

> diff --git a/libio/genops.c b/libio/genops.c
> index 2197bfe7a1..e4378ca48f 100644
> --- a/libio/genops.c
> +++ b/libio/genops.c
> @@ -730,6 +730,13 @@ _IO_flush_all (void)
>  	   )
>  	  && _IO_OVERFLOW (fp, EOF) == EOF)
>  	result = EOF;
> +      if (_IO_fileno (fp) >= 0
> +	  && ((fp->_mode <= 0 && fp->_IO_read_ptr < fp->_IO_read_end)
> +	      || (_IO_vtable_offset (fp) == 0
> +		  && fp->_mode > 0 && (fp->_wide_data->_IO_read_ptr
> +				       < fp->_wide_data->_IO_read_end)))
> +	  && _IO_SYNC (fp) != 0)
> +	result = EOF;
>  
>        _IO_funlockfile (fp);
>        run_fp = NULL;

I was confused for a bit why exit would block indefinitely with a locked
input stream prior this change, but then I realized that we
unconditionally lock the stream before this check.

> +  FILE *temp = tmpfile ();
> +  TEST_VERIFY_EXIT (temp != NULL);
> +  fprintf (temp, "abc");
> +  TEST_COMPARE (fflush (temp), 0);
> +  TEST_COMPARE (lseek (fileno (temp), 0, SEEK_SET), 0);
> +  TEST_COMPARE (fgetc (temp), 'a');
> +  TEST_COMPARE (fflush (NULL), 0);
> +  TEST_COMPARE (lseek (fileno (temp), 0, SEEK_CUR), 1);
> +  xfclose (temp);
> +
> +  /* Likewise, but in wide mode.  */
> +  temp = tmpfile ();
> +  TEST_VERIFY_EXIT (temp != NULL);
> +  fwprintf (temp, L"abc");
> +  TEST_COMPARE (fflush (temp), 0);
> +  TEST_COMPARE (lseek (fileno (temp), 0, SEEK_SET), 0);
> +  TEST_COMPARE (fgetwc (temp), L'a');
> +  TEST_COMPARE (fflush (NULL), 0);
> +  TEST_COMPARE (lseek (fileno (temp), 0, SEEK_CUR), 1);
> +  xfclose (temp);
> +
> +  return 0;
> +}

Could you add tests that do the flush via fork and exit?

Thanks,
Florian



More information about the Libc-alpha mailing list