For C-level Win32::Job improvement (missing parts)
That would go inside PAR-Packer-1.049\myldr\boot.c and maybe PAR-Packer-1.049\myldr\main.c around "SPAWN"
With help from Re: Read STDOUT from Win32::Job while process is running, Re^5: Read STDOUT from Win32::Job while process is running, https://stackoverflow.com/questions/24012773/c-winapi-how-to-kill-child-processes-when-the-calling-parent-process-is-for
A patch
It compiles with some c/c++ warnings and what knot
It doesnt add tests for this specific feature
The existing test suite is failing a few tests ; not sure if related to my patch (my machine is slow)
-------------------
t/20-pp.t (Wstat: 256 Tests: 34 Failed: 1)
Failed test: 28
Non-zero exit status: 1
t/90-rt122949.t (Wstat: 4096 Tests: 109 Failed: 16)
Failed tests: 7, 9, 11, 13, 15, 17, 43, 49, 65, 75, 77
79, 81, 83, 91, 93
Non-zero exit status: 16
t/90-rt129312.t (Wstat: 512 Tests: 4 Failed: 2)
Failed tests: 3-4
Non-zero exit status: 2
Files=15, Tests=229, 739 wallclock secs ( 0.31 usr + 0.05 sys = 0.36
+ CPU)
Result: FAIL
Failed 3/15 test programs. 19/229 subtests failed.
dmake: Error code 255, while making 'test_dynamic'
Untested if it actually works to end child when parent is killed (test suite still running)
I tested it, a.exe spawns a.exe, first a.exe is killed, second a.exe doesnt kill itself
I've no time to debug further, probably fudged something from https://stackoverflow.com/questions/24012773/c-winapi-how-to-kill-child-processes-when-the-calling-parent-process-is-for
diff -ruN PAR-Packer-1.049/myldr/boot.c PAR-Packer-1.049-new/myldr/boo
+t.c
--- PAR-Packer-1.049/myldr/boot.c 2019-05-24 14:14:42.000000000 -07
+00
+++ PAR-Packer-1.049-new/myldr/boot.c 2019-09-01 00:28:35.031250000
+ -0700
@@ -82,6 +82,8 @@
#endif
#ifdef WIN32
+#include "mywin32job.h"
+
#define unpack_S(p) (*(WORD*)(p))
#define unpack_L(p) (*(DWORD*)(p))
@@ -249,6 +251,7 @@
/* finally spawn the custom Perl interpreter */
argv[0] = my_perl;
#ifdef WIN32
+ HANDLE killJob = createJobObject("par_daddy_child_ender_PAR_ARGV_
+0");
hinstLib = LoadLibrary("user32");
if (hinstLib != NULL) {
ProcAdd = (pALLOW) GetProcAddress(hinstLib, "AllowSetForegrou
+ndWindow");
@@ -275,6 +278,7 @@
rc = spawnvp(P_WAIT, my_perl, (char* const*)argv);
par_cleanup(stmpdir);
+ closeHandle( killJob );
exit(rc);
#else
execvp(my_perl, argv);
diff -ruN PAR-Packer-1.049/myldr/main.c PAR-Packer-1.049-new/myldr/mai
+n.c
--- PAR-Packer-1.049/myldr/main.c 2018-03-31 08:31:17.000000000 -07
+00
+++ PAR-Packer-1.049-new/myldr/main.c 2019-09-01 00:28:01.015625000
+ -0700
@@ -4,7 +4,9 @@
#include "perlxsi.c"
#include "my_par_pl.c"
-
+#ifdef WIN32
+#include "mywin32job.h"
+#endif
/* Workaround for mapstart: the only op which needs a different ppadd
+r */
#undef Perl_pp_mapstart
#define Perl_pp_mapstart Perl_pp_grepstart
@@ -85,6 +87,11 @@
Perl_atfork_unlock);
#endif
+#ifdef WIN32
+ HANDLE killJob = createJobObject("par_daddy_child_ender_PAR_ARGV_
+0");
+ assignProcessToJobObject( killJob, GetCurrentProcess() );
+#endif
+
if (!PL_do_undump) {
my_perl = perl_alloc();
if (!my_perl)
@@ -148,5 +155,8 @@
perl_free( my_perl );
PERL_SYS_TERM();
+#ifdef WIN32
+ closeHandle( killJob );
+#endif
return exitstatus;
}
diff -ruN PAR-Packer-1.049/myldr/mywin32job.h PAR-Packer-1.049-new/myl
+dr/mywin32job.h
--- PAR-Packer-1.049/myldr/mywin32job.h 1969-12-31 16:00:00.0000000
+00 -0800
+++ PAR-Packer-1.049-new/myldr/mywin32job.h 2019-09-01 00:26:06.609
+375000 -0700
@@ -0,0 +1,25 @@
+/* 2019-09-01-00:16:03 Anonymous Monk */
+#define _WIN32_WINNT 0x0500
+#include <windows.h>
+
+#ifndef JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
+ #define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x2000
+#endif
+
+int createJobObject( char *name ) {
+ HANDLE job;
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0, };
+ jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_
+JOB_CLOSE;
+ job = (int)CreateJobObjectA( NULL, name );
+ SetInformationJobObject( job, 9, &jeli, sizeof(jeli) );
+ return job;
+}
+
+int assignProcessToJobObject( int job, int pid ) {
+ HANDLE hProc = OpenProcess( PROCESS_SET_QUOTA |PROCESS_TERMINATE,
+ 0, pid );
+ return (int)AssignProcessToJobObject( job, hProc );
+}
+
+int closeHandle( int handle ) {
+ return (int)CloseHandle( (HANDLE)handle );
+}