bool
do_exec(char *cmd)
{
+ return do_exec3(cmd,0,0);
+}
+
+bool
+do_exec3(char *cmd, int fd, int do_report)
+{
register char **a;
register char *s;
char flags[10];
}
{
dTHR;
+ int e = errno;
+
if (ckWARN(WARN_EXEC))
warner(WARN_EXEC, "Can't exec \"%s\": %s",
PL_Argv[0], Strerror(errno));
+ if (do_report) {
+ PerlLIO_write(fd, (void*)&e, sizeof(int));
+ PerlLIO_close(fd);
+ }
}
}
do_execfree();
#define do_close Perl_do_close
#define do_eof Perl_do_eof
#define do_exec Perl_do_exec
+#define do_exec3 Perl_do_exec3
#define do_execfree Perl_do_execfree
#define do_gv_dump Perl_do_gv_dump
#define do_gvgv_dump Perl_do_gvgv_dump
#define do_close CPerlObj::Perl_do_close
#define do_eof CPerlObj::Perl_do_eof
#define do_exec CPerlObj::Perl_do_exec
+#define do_exec3 CPerlObj::Perl_do_exec3
#define do_execfree CPerlObj::Perl_do_execfree
#define do_gv_dump CPerlObj::Perl_do_gv_dump
#define do_gvgv_dump CPerlObj::Perl_do_gvgv_dump
do_close
do_eof
do_exec
+do_exec3
do_execfree
do_hv_dump
do_gv_dump
#define do_eof pPerl->Perl_do_eof
#undef do_exec
#define do_exec pPerl->Perl_do_exec
+#undef do_exec3
+#define do_exec3 pPerl->Perl_do_exec3
#undef do_execfree
#define do_execfree pPerl->Perl_do_execfree
#undef do_gv_dump
(P) The lexer got into a bad state parsing a string with brackets.
+=item panic: kid popen errno read
+
+(F) forked child returned an incomprehensible message about its errno.
+
=item panic: last
(P) We popped the context stack to a block context, and then discovered
VIRTUAL bool do_close _((GV* gv, bool not_implicit));
VIRTUAL bool do_eof _((GV* gv));
VIRTUAL bool do_exec _((char* cmd));
+VIRTUAL bool do_exec3 _((char* cmd, int fd, int flag));
VIRTUAL void do_execfree _((void));
#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
I32 do_ipcctl _((I32 optype, SV** mark, SV** sp));
register I32 pid;
SV *sv;
I32 doexec = strNE(cmd,"-");
+ I32 did_pipes = 0;
+ int pp[2];
PERL_FLUSHALL_FOR_CHILD;
#ifdef OS2
}
if (PerlProc_pipe(p) < 0)
return Nullfp;
+ if (doexec && PerlProc_pipe(pp) >= 0)
+ did_pipes = 1;
while ((pid = (doexec?vfork():fork())) < 0) {
if (errno != EAGAIN) {
PerlLIO_close(p[This]);
+ if (did_pipes) {
+ PerlLIO_close(pp[0]);
+ PerlLIO_close(pp[1]);
+ }
if (!doexec)
croak("Can't fork");
return Nullfp;
#define THIS that
#define THAT This
PerlLIO_close(p[THAT]);
+ if (did_pipes) {
+ PerlLIO_close(pp[0]);
+#if defined(HAS_FCNTL) && defined(F_SETFD)
+ fcntl(pp[1], F_SETFD, FD_CLOEXEC);
+#endif
+ }
if (p[THIS] != (*mode == 'r')) {
PerlLIO_dup2(p[THIS], *mode == 'r');
PerlLIO_close(p[THIS]);
#define NOFILE 20
#endif
for (fd = PL_maxsysfd + 1; fd < NOFILE; fd++)
- PerlLIO_close(fd);
+ if (fd != pp[1])
+ PerlLIO_close(fd);
#endif
- do_exec(cmd); /* may or may not use the shell */
+ do_exec3(cmd,pp[1],did_pipes); /* may or may not use the shell */
PerlProc__exit(1);
}
/*SUPPRESS 560*/
}
do_execfree(); /* free any memory malloced by child on vfork */
PerlLIO_close(p[that]);
+ if (did_pipes)
+ PerlLIO_close(pp[1]);
if (p[that] < p[This]) {
PerlLIO_dup2(p[This], p[that]);
PerlLIO_close(p[This]);
(void)SvUPGRADE(sv,SVt_IV);
SvIVX(sv) = pid;
PL_forkprocess = pid;
+ if (did_pipes && pid > 0) {
+ int errkid;
+ int n = 0, n1;
+
+ while (n < sizeof(int)) {
+ n1 = PerlLIO_read(pp[0],
+ (void*)(((char*)&errkid)+n),
+ (sizeof(int)) - n);
+ if (n1 <= 0)
+ break;
+ n += n1;
+ }
+ if (n) { /* Error */
+ if (n != sizeof(int))
+ croak("panic: kid popen errno read");
+ PerlLIO_close(pp[0]);
+ errno = errkid; /* Propagate errno from kid */
+ return Nullfp;
+ }
+ }
+ if (did_pipes)
+ PerlLIO_close(pp[0]);
return PerlIO_fdopen(p[This], mode);
}
#else