11import { CmdLetBase } from '../../../commands/cmdlet.js' ;
22import { Output } from '../../../io/output.js' ;
33import { Token } from '../../../io/token.js' ;
4- import { Exception } from '../../../misc/exception.js' ;
54import { Files } from '../../../misc/files.js' ;
65import { Format } from '../../../misc/format.js' ;
76import { Var } from '../../../vars/var.js' ;
8- import { Clone } from './clone .js' ;
7+ import { Fork } from './fork .js' ;
98import { CoreFilter } from './core_filter.js' ;
109import { CorePattern } from './core_pattern.js' ;
1110import { Dumpable } from './dumpable.js' ;
@@ -21,22 +20,17 @@ export class CorpseCmdLet extends CmdLetBase {
2120 private static readonly USAGE : string = `Usage: corpse
2221corpse - create a corpse file` ;
2322
24- private static readonly CHILD_SLEEP_DURATION : number = 0.1 ;
2523 private static readonly PARENT_SLEEP_DURATION : number = 0.5 ;
2624 private static readonly WAIT_DURATION : number = 20 ;
27- private static readonly PARENT_DELAY_DURATION : number = 2 ;
2825 private static readonly ELF_MAGIC : number = 0x7f454c46 ;
2926
3027 private rlimit : Rlimit | null = null ;
3128 private dumpable : Dumpable | null = null ;
32- private clone : Clone | null = null ;
29+ private clone : Fork | null = null ;
3330 private proc : Proc | null = null ;
3431
3532 public runSync ( tokens : Token [ ] ) : Var {
36- if ( tokens . length != 0 ) {
37- Output . writeln ( CorpseCmdLet . USAGE ) ;
38- return Var . ZERO ;
39- }
33+ if ( tokens . length != 0 ) return this . usage ( ) ;
4034
4135 const corePattern = CorePattern . get ( ) ;
4236 this . status ( `Got core pattern: '${ corePattern } '` ) ;
@@ -48,109 +42,33 @@ corpse - create a corpse file`;
4842 run 'setenforce 0' to disable` ) ;
4943 }
5044
51- /* set the rlimit */
52- const rlimit = this . rlimit as Rlimit ;
53- const limit = rlimit . get ( ) ;
54- this . debug (
55- `Read rlimit - soft: ${ limit . sortLimit } , hard: ${ limit . hardLimit } ` ,
56- ) ;
57- if ( rlimit . isUnlimited ( limit ) ) {
58- this . debug ( 'Rlimit is unlimited' ) ;
59- } else {
60- this . debug ( 'Setting rlimit to unlimited' ) ;
61- rlimit . set ( Rlimit . UNLIMITED ) ;
62- }
63- this . status ( 'Rlimit has been configured' ) ;
45+ /* run the clone */
46+ const debugFileName = Files . getRandomFileName ( 'debug' ) ;
47+ this . status ( `Creating debug file: '${ debugFileName } '` ) ;
48+ const debugFile = new File ( debugFileName , 'w' ) ;
49+ const debug = ( msg : string ) => {
50+ debugFile . write ( `${ msg } \n` ) ;
51+ debugFile . flush ( ) ;
52+ } ;
6453
54+ this . status ( 'Reconfiguring exception handling' ) ;
6555 try {
66- /* Set the core filter*/
67- const coreFilter = CoreFilter . get ( ) ;
68- this . status ( `Read core filter: 0x${ coreFilter . toString ( 16 ) } ` ) ;
69- if ( coreFilter . equals ( CoreFilter . NEEDED ) ) {
70- this . debug ( 'Core filter is already set' ) ;
71- } else {
72- this . debug ( 'Setting core filter' ) ;
73- CoreFilter . trySet ( CoreFilter . NEEDED ) ;
74- }
75- this . status ( 'Core filter has been configured' ) ;
76-
77- try {
78- /* set dumpable */
79- const dumpable = this . dumpable as Dumpable ;
80- const isDumpable = dumpable . get ( ) ;
81- this . status ( `Read dumpable: ${ isDumpable } ` ) ;
82- if ( isDumpable === 0 ) {
83- this . debug ( 'Setting dumpable' ) ;
84- dumpable . set ( 1 ) ;
85- } else {
86- this . debug ( 'Dumpable is already set' ) ;
87- }
88- this . status ( 'Dumpable has been configured' ) ;
89-
90- /* run the clone */
91- try {
92- const debugFileName = Files . getRandomFileName ( 'debug' ) ;
93- this . status ( `Creating debug file: '${ debugFileName } '` ) ;
94- const debugFile = new File ( debugFileName , 'w' ) ;
95- const debug = ( msg : string ) => {
96- debugFile . write ( `${ msg } \n` ) ;
97- debugFile . flush ( ) ;
98- } ;
99-
100- this . status ( 'Reconfiguring exception handling' ) ;
101- Exception . propagate ( ) ;
102- try {
103- const clone = this . clone as Clone ;
104- const childPid = clone . clone (
105- ( childPid : number ) => {
106- this . runParent ( childPid ) ;
107- } ,
108- ( ) => {
109- this . runChild ( debug ) ;
110- } ,
111- ) ;
112- this . debug (
113- `Checking for corpse - core pattern: '${ corePattern } ', pid: ${ childPid } ` ,
114- ) ;
115- this . checkCorpse ( corePattern , childPid ) ;
116- } finally {
117- this . status ( 'Restoring exception handling' ) ;
118- Exception . suppress ( ) ;
119- this . debug ( `Checking debug file: '${ debugFileName } '` ) ;
120- this . checkDebugFile ( debugFileName ) ;
121- }
122- } finally {
123- /* Restore dumpable */
124- this . status ( 'Restoring dumpable' ) ;
125- if ( isDumpable === 0 ) {
126- this . debug ( 'Resetting dumpable' ) ;
127- dumpable . set ( isDumpable ) ;
128- } else {
129- this . debug ( 'No need to reset dumpable' ) ;
130- }
131- this . debug ( 'Restored dumpable' ) ;
132- }
133- } finally {
134- /* Restore core filter */
135- this . status ( 'Restoring core filter' ) ;
136- if ( coreFilter . equals ( CoreFilter . NEEDED ) ) {
137- this . debug ( 'No need to restore core filter' ) ;
138- } else {
139- this . debug ( 'Restoring core filter' ) ;
140- CoreFilter . trySet ( coreFilter ) ;
141- }
142- this . debug ( 'Restored core filter' ) ;
143- }
56+ const clone = this . clone as Fork ;
57+ const childPid = clone . fork (
58+ ( childPid : number ) => {
59+ this . runParent ( childPid ) ;
60+ } ,
61+ ( ) => {
62+ this . runChild ( debug ) ;
63+ } ,
64+ ) ;
65+ this . debug (
66+ `Checking for corpse - core pattern: '${ corePattern } ', pid: ${ childPid } ` ,
67+ ) ;
68+ this . checkCorpse ( corePattern , childPid ) ;
14469 } finally {
145- /* Restore rlimit */
146- this . status ( 'Restoring rlimit' ) ;
147- if ( rlimit . isUnlimited ( limit ) ) {
148- this . debug ( 'No need to restore rlimit' ) ;
149- } else {
150- this . debug ( 'Restoring rlimit' ) ;
151- rlimit . set ( limit ) ;
152- }
153- this . debug ( 'Restored rlimit' ) ;
70+ this . debug ( `Checking debug file: '${ debugFileName } '` ) ;
71+ this . checkDebugFile ( debugFileName ) ;
15472 }
15573
15674 return Var . ZERO ;
@@ -161,17 +79,14 @@ corpse - create a corpse file`;
16179
16280 const proc = this . proc as Proc ;
16381
164- this . debug ( `Delaying: ${ CorpseCmdLet . PARENT_DELAY_DURATION } s` ) ;
165- Thread . sleep ( CorpseCmdLet . PARENT_DELAY_DURATION ) ;
166-
16782 const limit =
16883 CorpseCmdLet . WAIT_DURATION / CorpseCmdLet . PARENT_SLEEP_DURATION ;
16984
17085 this . debug ( `Parent limit: ${ limit } ` ) ;
171- this . debug ( `Delay between signals: ${ CorpseCmdLet . PARENT_SLEEP_DURATION } s` ) ;
86+ this . debug (
87+ `Delay between waitpids: ${ CorpseCmdLet . PARENT_SLEEP_DURATION } s` ,
88+ ) ;
17289 for ( let i = 0 ; i < limit ; i ++ ) {
173- proc . kill ( childPid , Proc . SIGABRT ) ;
174-
17590 const status = proc . waitpid ( childPid ) ;
17691 this . debug (
17792 [
@@ -197,14 +112,22 @@ corpse - create a corpse file`;
197112 debug ( `PID: ${ pid } ` ) ;
198113
199114 try {
200- const limit =
201- CorpseCmdLet . WAIT_DURATION / CorpseCmdLet . CHILD_SLEEP_DURATION ;
202- debug ( `Child limit: ${ limit } ` ) ;
203- debug ( `Delay between sleeps: ${ CorpseCmdLet . CHILD_SLEEP_DURATION } s` ) ;
204- for ( let i = 0 ; i < limit ; i ++ ) {
205- Thread . sleep ( CorpseCmdLet . CHILD_SLEEP_DURATION ) ;
206- }
207- debug ( `Child limit exceeded` ) ;
115+ const rlimit = this . rlimit as Rlimit ;
116+ rlimit . set ( Rlimit . UNLIMITED ) ;
117+ debug ( `set rlimit` ) ;
118+
119+ CoreFilter . set ( CoreFilter . NEEDED ) ;
120+ debug ( `set core filter` ) ;
121+
122+ const dumpable = this . dumpable as Dumpable ;
123+ dumpable . set ( 1 ) ;
124+ debug ( `set dumpable` ) ;
125+
126+ debug ( `Restoring default signal action using rt_sigaction` ) ;
127+ proc . rt_sigaction ( Proc . SIGABRT , Proc . SIG_DFL ) ;
128+
129+ debug ( `Suicide` ) ;
130+ proc . kill ( pid , Proc . SIGABRT ) ;
208131 } catch ( error ) {
209132 if ( error instanceof Error ) {
210133 debug ( `ERROR: ${ error . message } ` ) ;
@@ -283,7 +206,7 @@ corpse - create a corpse file`;
283206 try {
284207 this . rlimit = new Rlimit ( ) ;
285208 this . dumpable = new Dumpable ( ) ;
286- this . clone = new Clone ( ) ;
209+ this . clone = new Fork ( ) ;
287210 this . proc = new Proc ( ) ;
288211 } catch {
289212 return false ;
0 commit comments