Files
nomad/api/internal/testutil/server_windows.go
Tim Gross 4e75e99f1a windows: use/accept platform-specific signal for stopping agent (#26780)
On Windows, the `os.Process.Signal` method returns an error when sending
`os.Interrupt` (SIGINT) because it isn't implemented. This causes test servers
in the `testutil` packages to break on Windows. Use the platform specific
syscalls to generate the SIGINT instead.

The agent's signal handler also did not correctly handle the Ctrl-C because we
were masking os.Interrupt instead of SIGINT.

Fixes: https://github.com/hashicorp/nomad/issues/26775

Co-authored-by: Chris Roberts <croberts@hashicorp.com>
2025-09-17 11:32:20 -04:00

38 lines
1.1 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
//go:build windows
package testutil
import (
"fmt"
"syscall"
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procSetCtrlHandler = kernel32.NewProc("SetConsoleCtrlHandler")
procGenCtrlEvent = kernel32.NewProc("GenerateConsoleCtrlEvent")
)
// gracefulStop performs a platform-specific graceful stop. On Windows the Go
// API does not implement SIGINT even though it's supported on Windows via
// CTRL_C_EVENT
func (s *TestServer) gracefulStop() error {
// note: err is always non-nil from these proc Call methods because it's
// always populated from GetLastError and you need to check the result
// returned against the docs.
pid := s.cmd.Process.Pid
result, _, err := procSetCtrlHandler.Call(0, 1)
if result == 0 {
return fmt.Errorf("failed to modify handlers for ctrl-c on pid %d: %w", pid, err)
}
result, _, err = procGenCtrlEvent.Call(syscall.CTRL_C_EVENT, uintptr(pid))
if result == 0 {
return fmt.Errorf("failed to send ctrl-C event to pid %d: %w", pid, err)
}
return nil
}