@@ -220,33 +220,46 @@ func tryPluginRun(dockerCli command.Cli, cmd *cobra.Command, subcommand string,
220220 return err
221221 }
222222
223- // Establish the plugin socket, adding it to the environment under a well-known key if successful.
223+ // Establish the plugin socket, adding it to the environment under a
224+ // well-known key if successful.
224225 srv , err := socket .NewPluginServer (nil )
225226 if err == nil {
226- envs = append (envs , socket .EnvKey + "=" + srv .Addr ().String ())
227+ plugincmd . Env = append (plugincmd . Env , socket .EnvKey + "=" + srv .Addr ().String ())
227228 }
228229
229- plugincmd .Env = append (envs , plugincmd .Env ... )
230+ // Set additional environment variables specified by the caller.
231+ plugincmd .Env = append (plugincmd .Env , envs ... )
230232
233+ // Background signal handling logic: block on the signals channel, and
234+ // notify the plugin via the PluginServer (or signal) as appropriate.
231235 const exitLimit = 3
232-
233236 signals := make (chan os.Signal , exitLimit )
234237 signal .Notify (signals , platformsignals .TerminationSignals ... )
235- // signal handling goroutine: listen on signals channel, and if conn is
236- // non-nil, attempt to close it to let the plugin know to exit. Regardless
237- // of whether we successfully signal the plugin or not, after 3 SIGINTs,
238- // we send a SIGKILL to the plugin process and exit
239238 go func () {
240239 retries := 0
241240 for range signals {
241+ // If stdin is a TTY, the kernel will forward
242+ // signals to the subprocess because the shared
243+ // pgid makes the TTY a controlling terminal.
244+ //
245+ // The plugin should have it's own copy of this
246+ // termination logic, and exit after 3 retries
247+ // on it's own.
242248 if dockerCli .Out ().IsTerminal () {
243- // running attached to a terminal, so the plugin will already
244- // receive signals due to sharing a pgid with the parent CLI
245249 continue
246250 }
247251
248- srv .Close ()
249-
252+ // Terminate the plugin server, which will
253+ // close all connections with plugin
254+ // subprocesses, and signal them to exit.
255+ //
256+ // Repeated invocations will result in EINVAL,
257+ // or EBADF; but that is fine for our purposes.
258+ _ = srv .Close ()
259+
260+ // If we're still running after 3 interruptions
261+ // (SIGINT/SIGTERM), send a SIGKILL to the plugin as a
262+ // final attempt to terminate, and exit.
250263 retries ++
251264 if retries >= exitLimit {
252265 _ , _ = fmt .Fprintf (dockerCli .Err (), "got %d SIGTERM/SIGINTs, forcefully exiting\n " , retries )
0 commit comments