mirror of
https://github.com/golang/sys.git
synced 2026-02-08 11:46:04 +03:00
Merge remote-tracking branch 'upstream/master' into 59016-FailureActionsFlag
This commit is contained in:
@@ -21,7 +21,7 @@ import (
|
||||
// Copied from internal/testenv.HasExec
|
||||
func hasExec() bool {
|
||||
switch runtime.GOOS {
|
||||
case "js", "ios":
|
||||
case "wasip1", "js", "ios":
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -37,14 +37,14 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
|
||||
return nil, err
|
||||
}
|
||||
defer DestroyEnvironmentBlock(block)
|
||||
blockp := uintptr(unsafe.Pointer(block))
|
||||
blockp := unsafe.Pointer(block)
|
||||
for {
|
||||
entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)))
|
||||
entry := UTF16PtrToString((*uint16)(blockp))
|
||||
if len(entry) == 0 {
|
||||
break
|
||||
}
|
||||
env = append(env, entry)
|
||||
blockp += 2 * (uintptr(len(entry)) + 1)
|
||||
blockp = unsafe.Add(blockp, 2*(len(entry)+1))
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
|
||||
@@ -95,12 +95,17 @@ func ComposeCommandLine(args []string) string {
|
||||
// DecomposeCommandLine breaks apart its argument command line into unescaped parts using CommandLineToArgv,
|
||||
// as gathered from GetCommandLine, QUERY_SERVICE_CONFIG's BinaryPathName argument, or elsewhere that
|
||||
// command lines are passed around.
|
||||
// DecomposeCommandLine returns error if commandLine contains NUL.
|
||||
func DecomposeCommandLine(commandLine string) ([]string, error) {
|
||||
if len(commandLine) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
utf16CommandLine, err := UTF16FromString(commandLine)
|
||||
if err != nil {
|
||||
return nil, errorspkg.New("string with NUL passed to DecomposeCommandLine")
|
||||
}
|
||||
var argc int32
|
||||
argv, err := CommandLineToArgv(StringToUTF16Ptr(commandLine), &argc)
|
||||
argv, err := CommandLineToArgv(&utf16CommandLine[0], &argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/svc"
|
||||
"golang.org/x/sys/windows/svc/mgr"
|
||||
)
|
||||
@@ -259,6 +260,16 @@ func testMultipleRecoverySettings(t *testing.T, s *mgr.Service, rebootMsgShould,
|
||||
}
|
||||
}
|
||||
|
||||
func testControl(t *testing.T, s *mgr.Service, c svc.Cmd, expectedErr error, expectedStatus svc.Status) {
|
||||
status, err := s.Control(c)
|
||||
if err != expectedErr {
|
||||
t.Fatalf("Unexpected return from s.Control: %v (expected %v)", err, expectedErr)
|
||||
}
|
||||
if expectedStatus != status {
|
||||
t.Fatalf("Unexpected status from s.Control: %+v (expected %+v)", status, expectedStatus)
|
||||
}
|
||||
}
|
||||
|
||||
func remove(t *testing.T, s *mgr.Service) {
|
||||
err := s.Delete()
|
||||
if err != nil {
|
||||
@@ -302,6 +313,7 @@ func TestMyService(t *testing.T) {
|
||||
t.Fatalf("service %s is not installed", name)
|
||||
}
|
||||
defer s.Close()
|
||||
defer s.Delete()
|
||||
|
||||
c.BinaryPathName = exepath
|
||||
c = testConfig(t, s, c)
|
||||
@@ -347,6 +359,11 @@ func TestMyService(t *testing.T) {
|
||||
testRecoveryActionsOnNonCrashFailures(t, s, false)
|
||||
testMultipleRecoverySettings(t, s, fmt.Sprintf("%s failed", name), fmt.Sprintf("sc query %s", name), true)
|
||||
|
||||
expectedStatus := svc.Status{
|
||||
State: svc.Stopped,
|
||||
}
|
||||
testControl(t, s, svc.Stop, windows.ERROR_SERVICE_NOT_ACTIVE, expectedStatus)
|
||||
|
||||
remove(t, s)
|
||||
}
|
||||
|
||||
|
||||
@@ -45,17 +45,25 @@ func (s *Service) Start(args ...string) error {
|
||||
return windows.StartService(s.Handle, uint32(len(args)), p)
|
||||
}
|
||||
|
||||
// Control sends state change request c to the service s.
|
||||
// Control sends state change request c to the service s. It returns the most
|
||||
// recent status the service reported to the service control manager, and an
|
||||
// error if the state change request was not accepted.
|
||||
// Note that the returned service status is only set if the status change
|
||||
// request succeeded, or if it failed with error ERROR_INVALID_SERVICE_CONTROL,
|
||||
// ERROR_SERVICE_CANNOT_ACCEPT_CTRL, or ERROR_SERVICE_NOT_ACTIVE.
|
||||
func (s *Service) Control(c svc.Cmd) (svc.Status, error) {
|
||||
var t windows.SERVICE_STATUS
|
||||
err := windows.ControlService(s.Handle, uint32(c), &t)
|
||||
if err != nil {
|
||||
if err != nil &&
|
||||
err != windows.ERROR_INVALID_SERVICE_CONTROL &&
|
||||
err != windows.ERROR_SERVICE_CANNOT_ACCEPT_CTRL &&
|
||||
err != windows.ERROR_SERVICE_NOT_ACTIVE {
|
||||
return svc.Status{}, err
|
||||
}
|
||||
return svc.Status{
|
||||
State: svc.State(t.CurrentState),
|
||||
Accepts: svc.Accepted(t.ControlsAccepted),
|
||||
}, nil
|
||||
}, err
|
||||
}
|
||||
|
||||
// Query returns current status of service s.
|
||||
|
||||
@@ -626,6 +626,22 @@ func TestCommandLineRecomposition(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// check that windows.DecomposeCommandLine returns error for strings with NUL
|
||||
testsWithNUL := []string{
|
||||
"\x00abcd",
|
||||
"ab\x00cd",
|
||||
"abcd\x00",
|
||||
"\x00abcd\x00",
|
||||
"\x00ab\x00cd\x00",
|
||||
"\x00\x00\x00",
|
||||
}
|
||||
for _, test := range testsWithNUL {
|
||||
_, err := windows.DecomposeCommandLine(test)
|
||||
if err == nil {
|
||||
t.Errorf("Failed to return error while decomposing %#q string with NUL inside", test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWinVerifyTrust(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user