stdio-common: In tst-setvbuf2, close helper thread descriptor only if opened

The helper thread may get canceled before the open system
call succeds.  Then ThreadData.fd remains zero, and eventually
the xclose call in end_reader_thread fails because descriptor 0
is not open.

Instead, initialize the fd member to -1 (not a valid descriptor)
and close the descriptor only if valid.  Do this in a new end_thread
helper routine.

Also add more error checking to close operations.

Fixes commit 95b780c1d0 ("stdio: Add
more setvbuf tests").
This commit is contained in:
Florian Weimer 2025-04-08 10:39:44 +02:00
parent fb3d821afa
commit 4fa959d13d
1 changed files with 21 additions and 18 deletions

View File

@ -240,6 +240,21 @@ typedef struct {
/* It's OK if this is static, we only run one at a time. */ /* It's OK if this is static, we only run one at a time. */
ThreadData thread_data; ThreadData thread_data;
static void
end_thread (pthread_t *ptid)
{
if (*ptid)
{
pthread_cancel (*ptid);
xpthread_join (*ptid);
/* The descriptor was passed in, or the helper thread made
sufficient progress and opened the file. */
if (thread_data.fd >= 0)
xclose (thread_data.fd);
*ptid = 0;
}
}
static void * static void *
writer_thread_proc (void *closure) writer_thread_proc (void *closure)
{ {
@ -306,7 +321,7 @@ static void
start_writer_thread_n (const char *fname) start_writer_thread_n (const char *fname)
{ {
debug; debug;
thread_data.fd = 0; thread_data.fd = -1;
thread_data.fname = fname; thread_data.fname = fname;
writer_thread_tid = xpthread_create (NULL, writer_thread_proc, writer_thread_tid = xpthread_create (NULL, writer_thread_proc,
(void *)&thread_data); (void *)&thread_data);
@ -316,13 +331,7 @@ static void
end_writer_thread (void) end_writer_thread (void)
{ {
debug; debug;
if (writer_thread_tid) end_thread (&writer_thread_tid);
{
pthread_cancel (writer_thread_tid);
xpthread_join (writer_thread_tid);
xclose (thread_data.fd);
writer_thread_tid = 0;
}
} }
static void static void
@ -339,7 +348,7 @@ static void
start_reader_thread_n (const char *fname) start_reader_thread_n (const char *fname)
{ {
debug; debug;
thread_data.fd = 0; thread_data.fd = -1;
thread_data.fname = fname; thread_data.fname = fname;
reader_thread_tid = xpthread_create (NULL, reader_thread_proc, reader_thread_tid = xpthread_create (NULL, reader_thread_proc,
(void *)&thread_data); (void *)&thread_data);
@ -349,13 +358,7 @@ static void
end_reader_thread (void) end_reader_thread (void)
{ {
debug; debug;
if (reader_thread_tid) end_thread (&reader_thread_tid);
{
pthread_cancel (reader_thread_tid);
xpthread_join (reader_thread_tid);
xclose (thread_data.fd);
reader_thread_tid = 0;
}
} }
/*------------------------------------------------------------*/ /*------------------------------------------------------------*/
@ -852,7 +855,7 @@ do_second_part (FILE *fp,
} }
fclose (fp); xfclose (fp);
return rv; return rv;
} }
@ -939,7 +942,7 @@ recurse (FILE *fp,
break; break;
default: /* parent */ default: /* parent */
fclose (fp); xfclose (fp);
xwaitpid (pid, &status, 0); xwaitpid (pid, &status, 0);
if (WIFEXITED (status) if (WIFEXITED (status)
&& WEXITSTATUS (status) == 0) && WEXITSTATUS (status) == 0)