@@ -573,18 +573,18 @@ func (s *arduinoCoreServerImpl) runProgramAction(ctx context.Context, pme *packa
573
573
// Run recipes for upload
574
574
toolEnv := pme .GetEnvVarsForSpawnedProcess ()
575
575
if burnBootloader {
576
- if err := runTool ("erase.pattern" , uploadProperties , outStream , errStream , verbose , dryRun , toolEnv ); err != nil {
576
+ if err := runTool (uploadCtx , "erase.pattern" , uploadProperties , outStream , errStream , verbose , dryRun , toolEnv ); err != nil {
577
577
return nil , & cmderrors.FailedUploadError {Message : i18n .Tr ("Failed chip erase" ), Cause : err }
578
578
}
579
- if err := runTool ("bootloader.pattern" , uploadProperties , outStream , errStream , verbose , dryRun , toolEnv ); err != nil {
579
+ if err := runTool (uploadCtx , "bootloader.pattern" , uploadProperties , outStream , errStream , verbose , dryRun , toolEnv ); err != nil {
580
580
return nil , & cmderrors.FailedUploadError {Message : i18n .Tr ("Failed to burn bootloader" ), Cause : err }
581
581
}
582
582
} else if programmer != nil {
583
- if err := runTool ("program.pattern" , uploadProperties , outStream , errStream , verbose , dryRun , toolEnv ); err != nil {
583
+ if err := runTool (uploadCtx , "program.pattern" , uploadProperties , outStream , errStream , verbose , dryRun , toolEnv ); err != nil {
584
584
return nil , & cmderrors.FailedUploadError {Message : i18n .Tr ("Failed programming" ), Cause : err }
585
585
}
586
586
} else {
587
- if err := runTool ("upload.pattern" , uploadProperties , outStream , errStream , verbose , dryRun , toolEnv ); err != nil {
587
+ if err := runTool (uploadCtx , "upload.pattern" , uploadProperties , outStream , errStream , verbose , dryRun , toolEnv ); err != nil {
588
588
return nil , & cmderrors.FailedUploadError {Message : i18n .Tr ("Failed uploading" ), Cause : err }
589
589
}
590
590
}
@@ -702,7 +702,12 @@ func detectUploadPort(
702
702
}
703
703
}
704
704
705
- func runTool (recipeID string , props * properties.Map , outStream , errStream io.Writer , verbose bool , dryRun bool , toolEnv []string ) error {
705
+ func runTool (ctx context.Context , recipeID string , props * properties.Map , outStream , errStream io.Writer , verbose bool , dryRun bool , toolEnv []string ) error {
706
+ // if ctx is already canceled just exit
707
+ if err := ctx .Err (); err != nil {
708
+ return err
709
+ }
710
+
706
711
recipe , ok := props .GetOk (recipeID )
707
712
if ! ok {
708
713
return errors .New (i18n .Tr ("recipe not found '%s'" , recipeID ))
@@ -739,6 +744,17 @@ func runTool(recipeID string, props *properties.Map, outStream, errStream io.Wri
739
744
return errors .New (i18n .Tr ("cannot execute upload tool: %s" , err ))
740
745
}
741
746
747
+ // If the ctx is canceled, kill the running command
748
+ completed := make (chan struct {})
749
+ defer close (completed )
750
+ go func () {
751
+ select {
752
+ case <- ctx .Done ():
753
+ _ = cmd .Kill ()
754
+ case <- completed :
755
+ }
756
+ }()
757
+
742
758
if err := cmd .Wait (); err != nil {
743
759
return errors .New (i18n .Tr ("uploading error: %s" , err ))
744
760
}
0 commit comments