mirror of
https://github.com/golang/go
synced 2024-11-24 19:10:15 -07:00
os: use small writes during console io
Fixes #3767 R=golang-dev, bradfitz, rsc CC=golang-dev https://golang.org/cl/6523043
This commit is contained in:
parent
7cda7dbe9a
commit
28cb9fd509
@ -258,8 +258,18 @@ func (f *File) writeConsole(b []byte) (n int, err error) {
|
|||||||
f.lastbits = make([]byte, len(b))
|
f.lastbits = make([]byte, len(b))
|
||||||
copy(f.lastbits, b)
|
copy(f.lastbits, b)
|
||||||
}
|
}
|
||||||
if len(runes) > 0 {
|
// syscall.WriteConsole seems to fail, if given large buffer.
|
||||||
uint16s := utf16.Encode(runes)
|
// So limit the buffer to 16000 characters. This number was
|
||||||
|
// discovered by experimenting with syscall.WriteConsole.
|
||||||
|
const maxWrite = 16000
|
||||||
|
for len(runes) > 0 {
|
||||||
|
m := len(runes)
|
||||||
|
if m > maxWrite {
|
||||||
|
m = maxWrite
|
||||||
|
}
|
||||||
|
chunk := runes[:m]
|
||||||
|
runes = runes[m:]
|
||||||
|
uint16s := utf16.Encode(chunk)
|
||||||
for len(uint16s) > 0 {
|
for len(uint16s) > 0 {
|
||||||
var written uint32
|
var written uint32
|
||||||
err = syscall.WriteConsole(f.fd, &uint16s[0], uint32(len(uint16s)), &written, nil)
|
err = syscall.WriteConsole(f.fd, &uint16s[0], uint32(len(uint16s)), &written, nil)
|
||||||
|
@ -6,6 +6,7 @@ package os_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -1066,3 +1067,31 @@ func TestDevNullFile(t *testing.T) {
|
|||||||
t.Fatalf("wrong file size have %d want 0", fi.Size())
|
t.Fatalf("wrong file size have %d want 0", fi.Size())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var testLargeWrite = flag.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
|
||||||
|
|
||||||
|
func TestLargeWriteToConsole(t *testing.T) {
|
||||||
|
if !*testLargeWrite {
|
||||||
|
t.Logf("skipping console-flooding test; enable with -large_write")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b := make([]byte, 32000)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = '.'
|
||||||
|
}
|
||||||
|
b[len(b)-1] = '\n'
|
||||||
|
n, err := Stdout.Write(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Write to os.Stdout failed: %v", err)
|
||||||
|
}
|
||||||
|
if n != len(b) {
|
||||||
|
t.Errorf("Write to os.Stdout should return %d; got %d", len(b), n)
|
||||||
|
}
|
||||||
|
n, err = Stderr.Write(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Write to os.Stderr failed: %v", err)
|
||||||
|
}
|
||||||
|
if n != len(b) {
|
||||||
|
t.Errorf("Write to os.Stderr should return %d; got %d", len(b), n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user