mirror of
git://git.sv.gnu.org/coreutils.git
synced 2026-04-21 11:16:16 +02:00
tee: avoid undefined behavior after fclose()
* iopoll.c (fclose_wait): Rename from confusing fclose_nonblock name. Also adjust to do no operations on the stream after fclose() as this is undefined. Instead use fflush() to determine EAGAIN status. (fwrite_wait): Renamed from confusing fwrite_nonblock name.
This commit is contained in:
12
src/iopoll.c
12
src/iopoll.c
@@ -204,23 +204,25 @@ fail:
|
|||||||
/* wrapper for fclose() that also waits for F if non blocking. */
|
/* wrapper for fclose() that also waits for F if non blocking. */
|
||||||
|
|
||||||
extern bool
|
extern bool
|
||||||
fclose_nonblock (FILE *f)
|
fclose_wait (FILE *f)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (fclose (f) == 0)
|
if (fflush (f) == 0)
|
||||||
return true;
|
break;
|
||||||
|
|
||||||
if (! fwait_for_nonblocking_write (f))
|
if (! fwait_for_nonblocking_write (f))
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return fclose (f) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* wrapper for fwrite() that also waits for F if non blocking. */
|
/* wrapper for fwrite() that also waits for F if non blocking. */
|
||||||
|
|
||||||
extern bool
|
extern bool
|
||||||
fwrite_nonblock (char const *buf, ssize_t size, FILE *f)
|
fwrite_wait (char const *buf, ssize_t size, FILE *f)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ int iopoll (int fdin, int fdout, bool block);
|
|||||||
bool iopoll_input_ok (int fdin);
|
bool iopoll_input_ok (int fdin);
|
||||||
bool iopoll_output_ok (int fdout);
|
bool iopoll_output_ok (int fdout);
|
||||||
|
|
||||||
bool fclose_nonblock (FILE *f);
|
bool fclose_wait (FILE *f);
|
||||||
bool fwrite_nonblock (char const *buf, ssize_t size, FILE *f);
|
bool fwrite_wait (char const *buf, ssize_t size, FILE *f);
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ tee_files (int nfiles, char **files, bool pipe_check)
|
|||||||
Standard output is the first one. */
|
Standard output is the first one. */
|
||||||
for (i = 0; i <= nfiles; i++)
|
for (i = 0; i <= nfiles; i++)
|
||||||
if (descriptors[i]
|
if (descriptors[i]
|
||||||
&& ! fwrite_nonblock (buffer, bytes_read, descriptors[i]))
|
&& ! fwrite_wait (buffer, bytes_read, descriptors[i]))
|
||||||
{
|
{
|
||||||
if (fail_output (descriptors, files, i))
|
if (fail_output (descriptors, files, i))
|
||||||
ok = false;
|
ok = false;
|
||||||
@@ -332,7 +332,7 @@ tee_files (int nfiles, char **files, bool pipe_check)
|
|||||||
|
|
||||||
/* Close the files, but not standard output. */
|
/* Close the files, but not standard output. */
|
||||||
for (i = 1; i <= nfiles; i++)
|
for (i = 1; i <= nfiles; i++)
|
||||||
if (descriptors[i] && ! fclose_nonblock (descriptors[i]))
|
if (descriptors[i] && ! fclose_wait (descriptors[i]))
|
||||||
{
|
{
|
||||||
error (0, errno, "%s", quotef (files[i]));
|
error (0, errno, "%s", quotef (files[i]));
|
||||||
ok = false;
|
ok = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user