mirror of
https://github.com/rwinkhart/sys.git
synced 2026-08-28 04:46:44 -04:00
windows: support nil done parameter in ReadFile and WriteFile
Win32 defines the `done` param as optional for ReadFile and WriteFile functions. We should support this case too. Fixes golang/go#65365. Change-Id: I961ff66a63d3a8ffa5560b6dab21fbd4ac9817ae Reviewed-on: https://go-review.googlesource.com/c/sys/+/559375 Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com> Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
@@ -572,13 +572,17 @@ func Write(fd Handle, p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ReadFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error {
|
func ReadFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error {
|
||||||
err := readFile(fd, p, done, overlapped)
|
var n uint32
|
||||||
|
err := readFile(fd, p, &n, overlapped)
|
||||||
if raceenabled {
|
if raceenabled {
|
||||||
if *done > 0 {
|
if n > 0 {
|
||||||
raceWriteRange(unsafe.Pointer(&p[0]), int(*done))
|
raceWriteRange(unsafe.Pointer(&p[0]), int(n))
|
||||||
}
|
}
|
||||||
raceAcquire(unsafe.Pointer(&ioSync))
|
raceAcquire(unsafe.Pointer(&ioSync))
|
||||||
}
|
}
|
||||||
|
if done != nil {
|
||||||
|
*done = n
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,9 +590,13 @@ func WriteFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error
|
|||||||
if raceenabled {
|
if raceenabled {
|
||||||
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
raceReleaseMerge(unsafe.Pointer(&ioSync))
|
||||||
}
|
}
|
||||||
err := writeFile(fd, p, done, overlapped)
|
var n uint32
|
||||||
if raceenabled && *done > 0 {
|
err := writeFile(fd, p, &n, overlapped)
|
||||||
raceReadRange(unsafe.Pointer(&p[0]), int(*done))
|
if raceenabled && n > 0 {
|
||||||
|
raceReadRange(unsafe.Pointer(&p[0]), int(n))
|
||||||
|
}
|
||||||
|
if done != nil {
|
||||||
|
*done = n
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1275,3 +1275,58 @@ uintptr_t beep(void) {
|
|||||||
t.Fatal("LoadLibraryEx unexpectedly found beep.dll")
|
t.Fatal("LoadLibraryEx unexpectedly found beep.dll")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReadWriteFileOverlapped(t *testing.T) {
|
||||||
|
name := filepath.Join(t.TempDir(), "test.txt")
|
||||||
|
fd, err := windows.CreateFile(windows.StringToUTF16Ptr(name), windows.GENERIC_READ|windows.GENERIC_WRITE, 0, nil, windows.CREATE_NEW, windows.FILE_FLAG_OVERLAPPED, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer windows.CloseHandle(fd)
|
||||||
|
|
||||||
|
content := []byte("hello")
|
||||||
|
// Test that we can write to a file using overlapped I/O.
|
||||||
|
var ow windows.Overlapped
|
||||||
|
ow.HEvent, err = windows.CreateEvent(nil, 0, 0, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer windows.CloseHandle(ow.HEvent)
|
||||||
|
if err := windows.WriteFile(fd, content, nil, &ow); err != nil && err != windows.ERROR_IO_PENDING {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := windows.WaitForSingleObject(ow.HEvent, windows.INFINITE); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var n uint32
|
||||||
|
if err := windows.GetOverlappedResult(fd, &ow, &n, true); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if n != uint32(len(content)) {
|
||||||
|
t.Fatalf("got %d bytes written; want %d", n, len(content))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that we can read from a file using overlapped I/O.
|
||||||
|
var or windows.Overlapped
|
||||||
|
or.HEvent, err = windows.CreateEvent(nil, 0, 0, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer windows.CloseHandle(ow.HEvent)
|
||||||
|
buf := make([]byte, len(content))
|
||||||
|
if err := windows.ReadFile(fd, buf, nil, &or); err != nil && err != windows.ERROR_IO_PENDING {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := windows.WaitForSingleObject(or.HEvent, windows.INFINITE); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := windows.GetOverlappedResult(fd, &or, &n, true); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if string(buf) != string(content) {
|
||||||
|
t.Fatalf("got %q; want %q", buf, content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user