From be1d3432aa8f4fd677757447c4c9e7ff9bf25f73 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Fri, 4 Sep 2020 18:15:16 +1000 Subject: [PATCH] windows: add TestJobObjectInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add test for CL 251197. Updates golang/go#41001 Change-Id: I6317678057eb8b18a1f7564842a92682c0c9930f Reviewed-on: https://go-review.googlesource.com/c/sys/+/253097 Run-TryBot: Alex Brainman TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- windows/syscall_windows.go | 1 + windows/syscall_windows_test.go | 37 +++++++++++++++++++++++++++++++++ windows/zsyscall_windows.go | 13 ++++++++++++ 3 files changed, 51 insertions(+) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 62cf70e9..2aa29e83 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -303,6 +303,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys ResumeThread(thread Handle) (ret uint32, err error) [failretval==0xffffffff] = kernel32.ResumeThread //sys SetPriorityClass(process Handle, priorityClass uint32) (err error) = kernel32.SetPriorityClass //sys GetPriorityClass(process Handle) (ret uint32, err error) = kernel32.GetPriorityClass +//sys QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) = kernel32.QueryInformationJobObject //sys SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) //sys GenerateConsoleCtrlEvent(ctrlEvent uint32, processGroupID uint32) (err error) //sys GetProcessId(process Handle) (id uint32, err error) diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index 0ee8d2c7..2f1513f3 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -14,6 +14,7 @@ import ( "strings" "syscall" "testing" + "unsafe" "golang.org/x/sys/windows" ) @@ -421,3 +422,39 @@ func TestProcessWorkingSetSizeEx(t *testing.T) { t.Error(err) } } + +func TestJobObjectInfo(t *testing.T) { + jo, err := windows.CreateJobObject(nil, nil) + if err != nil { + t.Fatalf("CreateJobObject failed: %v", err) + } + defer windows.CloseHandle(jo) + + var info windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION + + err = windows.QueryInformationJobObject(jo, windows.JobObjectExtendedLimitInformation, + uintptr(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info)), nil) + if err != nil { + t.Fatalf("QueryInformationJobObject failed: %v", err) + } + + const wantMemLimit = 4 * 1024 + + info.BasicLimitInformation.LimitFlags |= windows.JOB_OBJECT_LIMIT_PROCESS_MEMORY + info.ProcessMemoryLimit = wantMemLimit + _, err = windows.SetInformationJobObject(jo, windows.JobObjectExtendedLimitInformation, + uintptr(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info))) + if err != nil { + t.Fatalf("SetInformationJobObject failed: %v", err) + } + + err = windows.QueryInformationJobObject(jo, windows.JobObjectExtendedLimitInformation, + uintptr(unsafe.Pointer(&info)), uint32(unsafe.Sizeof(info)), nil) + if err != nil { + t.Fatalf("QueryInformationJobObject failed: %v", err) + } + + if have := info.ProcessMemoryLimit; wantMemLimit != have { + t.Errorf("ProcessMemoryLimit is wrong: want %v have %v", wantMemLimit, have) + } +} diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index 8a562fee..347f13db 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -212,6 +212,7 @@ var ( procResumeThread = modkernel32.NewProc("ResumeThread") procSetPriorityClass = modkernel32.NewProc("SetPriorityClass") procGetPriorityClass = modkernel32.NewProc("GetPriorityClass") + procQueryInformationJobObject = modkernel32.NewProc("QueryInformationJobObject") procSetInformationJobObject = modkernel32.NewProc("SetInformationJobObject") procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent") procGetProcessId = modkernel32.NewProc("GetProcessId") @@ -2341,6 +2342,18 @@ func GetPriorityClass(process Handle) (ret uint32, err error) { return } +func QueryInformationJobObject(job Handle, JobObjectInformationClass int32, JobObjectInformation uintptr, JobObjectInformationLength uint32, retlen *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procQueryInformationJobObject.Addr(), 5, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), uintptr(unsafe.Pointer(retlen)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + func SetInformationJobObject(job Handle, JobObjectInformationClass uint32, JobObjectInformation uintptr, JobObjectInformationLength uint32) (ret int, err error) { r0, _, e1 := syscall.Syscall6(procSetInformationJobObject.Addr(), 4, uintptr(job), uintptr(JobObjectInformationClass), uintptr(JobObjectInformation), uintptr(JobObjectInformationLength), 0, 0) ret = int(r0)