|
51 | 51 | #define PERL_NO_GET_CONTEXT
|
52 | 52 | #include "XSUB.h"
|
53 | 53 |
|
| 54 | +#if defined(USE_PERLIO) |
| 55 | +#include "perliol.h" /* For PerlIOUnix_refcnt */ |
| 56 | +#endif |
| 57 | + |
54 | 58 | #include <fcntl.h>
|
55 | 59 | #ifndef __GNUC__
|
56 | 60 | /* assert.h conflicts with #define of assert in perl.h */
|
@@ -3622,7 +3626,7 @@ do_popen(const char *mode, const char *command, IV narg, SV **args) {
|
3622 | 3626 |
|
3623 | 3627 | win32_close(p[child]);
|
3624 | 3628 |
|
3625 |
| - sv_setiv(*av_fetch(w32_fdpid, p[parent], TRUE), childpid); |
| 3629 | + sv_setiv(*av_fetch(PL_fdpid, p[parent], TRUE), childpid); |
3626 | 3630 |
|
3627 | 3631 | /* set process id so that it can be returned by perl's open() */
|
3628 | 3632 | PL_forkprocess = childpid;
|
@@ -3665,34 +3669,40 @@ win32_pclose(PerlIO *pf)
|
3665 | 3669 | #ifdef USE_RTL_POPEN
|
3666 | 3670 | return _pclose(pf);
|
3667 | 3671 | #else
|
| 3672 | + /* this should roughly match Perl_my_pclose() in util.c */ |
3668 | 3673 | dTHX;
|
3669 |
| - int childpid, status; |
3670 |
| - SV *sv; |
| 3674 | + int fd = PerlIO_fileno(pf); |
3671 | 3675 |
|
3672 |
| - sv = *av_fetch(w32_fdpid, PerlIO_fileno(pf), TRUE); |
3673 |
| - |
3674 |
| - if (SvIOK(sv)) |
3675 |
| - childpid = SvIVX(sv); |
| 3676 | + SV **svp = av_fetch(PL_fdpid, fd, FALSE); |
| 3677 | + int childpid; |
| 3678 | + if (svp) { |
| 3679 | + childpid = (SvTYPE(*svp) == SVt_IV) ? SvIVX(*svp) : -1; |
| 3680 | + SvREFCNT_dec(*svp); |
| 3681 | + *svp = NULL; |
| 3682 | + } |
3676 | 3683 | else
|
3677 |
| - childpid = 0; |
| 3684 | + childpid = -1; |
3678 | 3685 |
|
3679 |
| - if (!childpid) { |
3680 |
| - errno = EBADF; |
3681 |
| - return -1; |
3682 |
| - } |
| 3686 | + bool should_wait = PerlIOUnix_refcnt(fd) == 1 && childpid > 0; |
3683 | 3687 |
|
3684 |
| -#ifdef USE_PERLIO |
3685 |
| - PerlIO_close(pf); |
3686 |
| -#else |
3687 |
| - fclose(pf); |
3688 |
| -#endif |
3689 |
| - SvIVX(sv) = 0; |
| 3688 | + bool close_failed = (PerlIO_close(pf) == EOF); |
3690 | 3689 |
|
3691 |
| - if (win32_waitpid(childpid, &status, 0) == -1) |
3692 |
| - return -1; |
| 3690 | + int status; |
| 3691 | + dSAVE_ERRNO; |
| 3692 | + int wait_result; |
| 3693 | + if (should_wait) { |
| 3694 | + wait_result = win32_waitpid(childpid, &status, 0); |
| 3695 | + } |
3693 | 3696 |
|
3694 |
| - return status; |
| 3697 | + if (close_failed) { |
| 3698 | + RESTORE_ERRNO; /* error from the close */ |
| 3699 | + return -1; |
| 3700 | + } |
3695 | 3701 |
|
| 3702 | + return should_wait |
| 3703 | + ? (wait_result < 0 ? wait_result : |
| 3704 | + (status == 0 ? 0 : (errno = 0, status))) |
| 3705 | + : 0; |
3696 | 3706 | #endif /* USE_RTL_POPEN */
|
3697 | 3707 | }
|
3698 | 3708 |
|
@@ -5685,7 +5695,6 @@ Perl_sys_intern_init(pTHX)
|
5685 | 5695 | w32_perlshell_tokens = NULL;
|
5686 | 5696 | w32_perlshell_vec = (char**)NULL;
|
5687 | 5697 | w32_perlshell_items = 0;
|
5688 |
| - w32_fdpid = newAV(); |
5689 | 5698 | Newx(w32_children, 1, child_tab);
|
5690 | 5699 | w32_num_children = 0;
|
5691 | 5700 | # ifdef USE_ITHREADS
|
@@ -5728,7 +5737,6 @@ Perl_sys_intern_clear(pTHX)
|
5728 | 5737 |
|
5729 | 5738 | Safefree(w32_perlshell_tokens);
|
5730 | 5739 | Safefree(w32_perlshell_vec);
|
5731 |
| - /* NOTE: w32_fdpid is freed by sv_clean_all() */ |
5732 | 5740 | Safefree(w32_children);
|
5733 | 5741 | if (w32_timerid) {
|
5734 | 5742 | KillTimer(w32_message_hwnd, w32_timerid);
|
@@ -5767,7 +5775,6 @@ Perl_sys_intern_dup(pTHX_ struct interp_intern *src, struct interp_intern *dst)
|
5767 | 5775 | dst->perlshell_tokens = NULL;
|
5768 | 5776 | dst->perlshell_vec = (char**)NULL;
|
5769 | 5777 | dst->perlshell_items = 0;
|
5770 |
| - dst->fdpid = newAV(); |
5771 | 5778 | Newxz(dst->children, 1, child_tab);
|
5772 | 5779 | dst->pseudo_id = 0;
|
5773 | 5780 | dst->cur_tid = 0;
|
|
0 commit comments