14
14
use Symfony \Component \Console \Command \Command ;
15
15
use Symfony \Component \Console \Command \HelpCommand ;
16
16
use Symfony \Component \Console \Command \ListCommand ;
17
+ use Symfony \Component \Console \Command \SignalableCommandInterface ;
17
18
use Symfony \Component \Console \CommandLoader \CommandLoaderInterface ;
18
19
use Symfony \Component \Console \Event \ConsoleCommandEvent ;
19
20
use Symfony \Component \Console \Event \ConsoleErrorEvent ;
@@ -79,13 +80,18 @@ class Application implements ResetInterface
79
80
private $ singleCommand = false ;
80
81
private $ initialized ;
81
82
private $ signalRegistry ;
83
+ private $ signalsToDispatchEvent = [];
82
84
83
85
public function __construct (string $ name = 'UNKNOWN ' , string $ version = 'UNKNOWN ' )
84
86
{
85
87
$ this ->name = $ name ;
86
88
$ this ->version = $ version ;
87
89
$ this ->terminal = new Terminal ();
88
90
$ this ->defaultCommand = 'list ' ;
91
+ $ this ->signalRegistry = new SignalRegistry ();
92
+ if (\defined ('SIGINT ' )) {
93
+ $ this ->signalsToDispatchEvent = [SIGINT , SIGTERM , SIGUSR1 , SIGUSR2 ];
94
+ }
89
95
}
90
96
91
97
/**
@@ -101,9 +107,14 @@ public function setCommandLoader(CommandLoaderInterface $commandLoader)
101
107
$ this ->commandLoader = $ commandLoader ;
102
108
}
103
109
104
- public function setSignalRegistry ( SignalRegistry $ signalRegistry )
110
+ public function getSignalRegistry (): SignalRegistry
105
111
{
106
- $ this ->signalRegistry = $ signalRegistry ;
112
+ return $ this ->signalRegistry ;
113
+ }
114
+
115
+ public function setSignalsToDispatchEvent (int ...$ signalsToDispatchEvent )
116
+ {
117
+ $ this ->signalsToDispatchEvent = $ signalsToDispatchEvent ;
107
118
}
108
119
109
120
/**
@@ -268,14 +279,20 @@ public function doRun(InputInterface $input, OutputInterface $output)
268
279
$ command = $ this ->find ($ alternative );
269
280
}
270
281
271
- if ($ this ->signalRegistry ) {
272
- foreach ($ this ->signalRegistry ->getHandlingSignals () as $ handlingSignal ) {
273
- $ event = new ConsoleSignalEvent ($ command , $ input , $ output , $ handlingSignal );
274
- $ onSignalHandler = function () use ($ event ) {
282
+ if ($ this ->dispatcher ) {
283
+ foreach ($ this ->signalsToDispatchEvent as $ signal ) {
284
+ $ event = new ConsoleSignalEvent ($ command , $ input , $ output , $ signal );
285
+
286
+ $ this ->signalRegistry ->register ($ signal , function ($ signal , $ hasNext ) use ($ event ) {
275
287
$ this ->dispatcher ->dispatch ($ event , ConsoleEvents::SIGNAL );
276
- };
277
288
278
- $ this ->signalRegistry ->register ($ handlingSignal , $ onSignalHandler );
289
+ // No more handlers, we try to simulate PHP default behavior
290
+ if (!$ hasNext ) {
291
+ if (!\in_array ($ signal , [SIGUSR1 , SIGUSR2 ], true )) {
292
+ exit (0 );
293
+ }
294
+ }
295
+ });
279
296
}
280
297
}
281
298
@@ -926,6 +943,12 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
926
943
}
927
944
}
928
945
946
+ if ($ command instanceof SignalableCommandInterface) {
947
+ foreach ($ command ->getSubscribedSignals () as $ signal ) {
948
+ $ this ->signalRegistry ->register ($ signal , [$ command , 'handleSignal ' ]);
949
+ }
950
+ }
951
+
929
952
if (null === $ this ->dispatcher ) {
930
953
return $ command ->run ($ input , $ output );
931
954
}
0 commit comments