Cygwin: FIFO: honor the flags argument in dup

Also improve the error handling.
This commit is contained in:
Ken Brown 2020-03-25 09:31:29 -04:00
parent 25e8727368
commit 624fda1e96
1 changed files with 33 additions and 27 deletions

View File

@ -955,56 +955,62 @@ fhandler_fifo::fcntl (int cmd, intptr_t arg)
int int
fhandler_fifo::dup (fhandler_base *child, int flags) fhandler_fifo::dup (fhandler_base *child, int flags)
{ {
int ret = -1; int i = 0;
fhandler_fifo *fhf = NULL; fhandler_fifo *fhf = NULL;
if (get_flags () & O_PATH) if (get_flags () & O_PATH)
return fhandler_base::dup (child, flags); return fhandler_base::dup (child, flags);
if (fhandler_base::dup (child, flags)) if (fhandler_base::dup (child, flags))
goto out; goto err;
fhf = (fhandler_fifo *) child; fhf = (fhandler_fifo *) child;
if (!DuplicateHandle (GetCurrentProcess (), read_ready, if (!DuplicateHandle (GetCurrentProcess (), read_ready,
GetCurrentProcess (), &fhf->read_ready, GetCurrentProcess (), &fhf->read_ready,
0, true, DUPLICATE_SAME_ACCESS)) 0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
{ {
fhf->close ();
__seterrno (); __seterrno ();
goto out; goto err;
} }
if (!DuplicateHandle (GetCurrentProcess (), write_ready, if (!DuplicateHandle (GetCurrentProcess (), write_ready,
GetCurrentProcess (), &fhf->write_ready, GetCurrentProcess (), &fhf->write_ready,
0, true, DUPLICATE_SAME_ACCESS)) 0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
{ {
NtClose (fhf->read_ready);
fhf->close ();
__seterrno (); __seterrno ();
goto out; goto err_close_read_ready;
} }
fifo_client_lock (); if (reader)
for (int i = 0; i < nhandlers; i++)
{ {
if (!DuplicateHandle (GetCurrentProcess (), fc_handler[i].h, fifo_client_lock ();
GetCurrentProcess (), for (i = 0; i < nhandlers; i++)
&fhf->fc_handler[i].h, {
0, true, DUPLICATE_SAME_ACCESS)) if (!DuplicateHandle (GetCurrentProcess (), fc_handler[i].h,
GetCurrentProcess (), &fhf->fc_handler[i].h,
0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
{
__seterrno ();
break;
}
}
if (i < nhandlers)
{ {
fifo_client_unlock (); fifo_client_unlock ();
NtClose (fhf->read_ready); goto err_close_handlers;
NtClose (fhf->write_ready);
fhf->close ();
__seterrno ();
goto out;
} }
fifo_client_unlock ();
if (!fhf->listen_client ())
goto err_close_handlers;
fhf->init_fixup_before ();
} }
fifo_client_unlock (); return 0;
if (!reader || fhf->listen_client ()) err_close_handlers:
ret = 0; for (int j = 0; j < i; j++)
if (reader) fhf->fc_handler[j].close ();
fhf->init_fixup_before (); NtClose (fhf->write_ready);
out: err_close_read_ready:
return ret; NtClose (fhf->read_ready);
err:
return -1;
} }
void void