1
0
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:
Alex Brainman 2012-09-19 16:55:21 +10:00
parent 7cda7dbe9a
commit 28cb9fd509
2 changed files with 41 additions and 2 deletions

View File

@ -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)

View File

@ -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)
}
}