Skip to content

close(STDOUT) does not wait on MS-Windows #4106

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
p5pRT opened this issue Jun 19, 2001 · 6 comments · May be fixed by #23262
Open

close(STDOUT) does not wait on MS-Windows #4106

p5pRT opened this issue Jun 19, 2001 · 6 comments · May be fixed by #23262

Comments

@p5pRT
Copy link

p5pRT commented Jun 19, 2001

Migrated from rt.perl.org#7142 (status was 'open')

Searchable as RT7142$

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2001

From @gisle

The following program fails to work on Windows. The program
terminates before the child finish. If another file handle than
STDOUT is used, then it works as expected. It also works as expected
on Linux.

open(STDOUT, qq(| perl -pe "sleep 1;")) || die;
print STDOUT "Hi\n" for 1..2;
close(STDOUT);
Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl v5.6.1:

Configured by gislea at Tue Jun 19 12:57:27 2001.

Summary of my perl5 (revision 5 version 6 subversion 1) configuration:
  Platform:
    osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    usethreads=undef use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=undef d_sfio=undef uselargefiles=undef usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
  Compiler:
    cc='cl', ccflags ='-nologo -O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT  -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DPERL_MSVCRT_READFIX',
    optimize='-O1 -MD -DNDEBUG',
    cppflags='-DWIN32'
    ccversion='', gccversion='', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=4
    alignbytes=8, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='', ldflags ='-nologo -nodefaultlib -release  -libpath:"C:\Perl\lib\CORE"  -machine:x86'
    libpth="C:\Program Files\Microsoft.NET\FrameworkSDK\Lib\" "C:\Perl\lib\CORE"
    libs=  oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib msvcrt.lib
    perllibs=  oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib msvcrt.lib
    libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl56.lib
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release  -libpath:"C:\Perl\lib\CORE"  -machine:x86'

Locally applied patches:
    ACTIVEPERL_LOCAL_PATCHES_ENTRY


@INC for perl v5.6.1:
    C:/Perl/lib
    C:/Perl/site/lib
    .


Environment for perl v5.6.1:
    HOME (unset)
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=C:\PROGRA~1\MICROS~3\Common\msdev98\BIN;C:\PROGRA~1\MICROS~3\VC98\BIN;C:\PROGRA~1\MICROS~3\Common\TOOLS\WINNT;C:\PROGRA~1\MICROS~3\Common\TOOLS;C:\DevStudio\SharedIDE\BIN;C:\DevStudio\VC\BIN;C:\DevStudio\VC\BIN\WINNT;C:\Python21\;C:\t32;c:\bin;C:\Perl\bin\;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;C:\WINNT\Microsoft.NET\Framework\v1.0.2728;C:\Program Files\Microsoft.NET\FrameworkSDK\Bin;h:\bin;C:\Program Files\Microsoft SQL Server\80\Tools\Binn\;\\rake\t32;G:\DevStudio\VC\DEVSTUDIO\VC\BIN;G:\DevStudio\VC\DEVSTUDIO\VC\BIN\WINNT
    PERLDB_OPTS=RemotePort=127.0.0.1:2000
    PERL_BADLANG (unset)
    SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented May 25, 2016

From [email protected]

I can reproduce the issue with 5.10 and 5.22. The problem randomly breaks OpenSSL builds.

@p5pRT
Copy link
Author

p5pRT commented May 25, 2016

From [Unknown Contact. See original ticket]

I can reproduce the issue with 5.10 and 5.22. The problem randomly breaks OpenSSL builds.

@richardleach
Copy link
Contributor

Still present in v5.30.0 on Win 10.

@toddr
Copy link
Member

toddr commented Feb 4, 2020

@gisle FYI your case was moved here.

@tonycoz
Copy link
Contributor

tonycoz commented Apr 23, 2025

non-Windows perl keeps process ids for piped opens in the PL_fdpid array, and for STD... handles openn_cleanup() carefully copies the process id from the original popenned fd to the STD... handle:

perl5/doio.c

Lines 1092 to 1107 in 6c95af2

#if !defined(WIN32)
/* PL_fdpid isn't used on Windows, so avoid this useless work.
* XXX Probably the same for a lot of other places. */
{
Pid_t pid;
SV *sv;
sv = *av_fetch(PL_fdpid,fd,TRUE);
SvUPGRADE(sv, SVt_IV);
pid = SvIVX(sv);
SvIV_set(sv, 0);
sv = *av_fetch(PL_fdpid,savefd,TRUE);
SvUPGRADE(sv, SVt_IV);
SvIV_set(sv, pid);
}
#endif

Windows being Windows, it does it's own thing, using a separate array w32_fdpid (which is a macro for PL_sys_intern.fdpid) to store piped process ids, and openn_cleanup() doesn't try to handle that.

This means by the time we get to close(STDOUT) there's no process id associated with fd 1, so win32_pclose() fails to wait, and the parent process finishes execution without waiting for the child process to exit.

At this point I don't know why Win32 uses its own array here.

tonycoz added a commit to tonycoz/perl5 that referenced this issue Apr 24, 2025
This duplicated the PL_fdpid already used by every other platform
but didn't handle the transfer done when STD handles were reopened
as pipes.

Along with re-working win32_pclose() to behave much closer to
Perl_my_pclose() from util.c and enabling the PID transfer done for
STD handles on Win32, this fixes Perl#4106

Still needs tests.
tonycoz added a commit to tonycoz/perl5 that referenced this issue Apr 30, 2025
tonycoz added a commit to tonycoz/perl5 that referenced this issue Apr 30, 2025
This duplicated the PL_fdpid already used by every other platform
but didn't handle the transfer done when STD handles were reopened
as pipes.

Along with re-working win32_pclose() to behave much closer to
Perl_my_pclose() from util.c and enabling the PID transfer done for
STD handles on Win32, this fixes Perl#4106

Still needs tests.
tonycoz added a commit to tonycoz/perl5 that referenced this issue May 1, 2025
This includes an old test I wrote for pclose blocking on non-Win32
(which up until this fix used distinct pclose code from Win32) and
test code for Perl#4106, which is the main issue being fixed by this patch
series.
tonycoz added a commit to tonycoz/perl5 that referenced this issue May 1, 2025
This duplicated the PL_fdpid already used by every other platform
but didn't handle the transfer done when STD handles were reopened
as pipes.

Along with re-working win32_pclose() to behave much closer to
Perl_my_pclose() from util.c and enabling the PID transfer done for
STD handles on Win32, this fixes Perl#4106
tonycoz added a commit to tonycoz/perl5 that referenced this issue May 6, 2025
This includes an old test I wrote for pclose blocking on non-Win32
(which up until this fix used distinct pclose code from Win32) and
test code for Perl#4106, which is the main issue being fixed by this patch
series.
tonycoz added a commit to tonycoz/perl5 that referenced this issue May 6, 2025
This duplicated the PL_fdpid already used by every other platform
but didn't handle the transfer done when STD handles were reopened
as pipes.

Along with re-working win32_pclose() to behave much closer to
Perl_my_pclose() from util.c and enabling the PID transfer done for
STD handles on Win32, this fixes Perl#4106
@tonycoz tonycoz linked a pull request May 6, 2025 that will close this issue
tonycoz added a commit to tonycoz/perl5 that referenced this issue May 6, 2025
This duplicated the PL_fdpid already used by every other platform
but didn't handle the transfer done when STD handles were reopened
as pipes.

Along with re-working win32_pclose() to behave much closer to
Perl_my_pclose() from util.c and enabling the PID transfer done for
STD handles on Win32, this fixes Perl#4106
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants