2015-01-09 12:31:23 -07:00
|
|
|
// Copyright 2014 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
2014-12-10 07:29:24 -07:00
|
|
|
package runtime
|
|
|
|
|
|
|
|
import "unsafe"
|
|
|
|
|
|
|
|
var (
|
|
|
|
writeHeader = []byte{6 /* ANDROID_LOG_ERROR */, 'G', 'o', 0}
|
|
|
|
writePath = []byte("/dev/log/main\x00")
|
|
|
|
writeFD uintptr
|
|
|
|
writeBuf [1024]byte
|
|
|
|
writePos int
|
|
|
|
)
|
|
|
|
|
|
|
|
func writeErr(b []byte) {
|
|
|
|
// Log format: "<priority 1 byte><tag n bytes>\x00<message m bytes>\x00"
|
|
|
|
// The entire log needs to be delivered in a single syscall (the NDK
|
|
|
|
// does this with writev). Each log is its own line, so we need to
|
|
|
|
// buffer writes until we see a newline.
|
|
|
|
if writeFD == 0 {
|
|
|
|
writeFD = uintptr(open(&writePath[0], 0x1 /* O_WRONLY */, 0))
|
|
|
|
if writeFD == 0 {
|
|
|
|
// It is hard to do anything here. Write to stderr just
|
|
|
|
// in case user has root on device and has run
|
|
|
|
// adb shell setprop log.redirect-stdio true
|
|
|
|
msg := []byte("runtime: cannot open /dev/log/main\x00")
|
|
|
|
write(2, unsafe.Pointer(&msg[0]), int32(len(msg)))
|
|
|
|
exit(2)
|
|
|
|
}
|
|
|
|
copy(writeBuf[:], writeHeader)
|
|
|
|
}
|
|
|
|
dst := writeBuf[len(writeHeader):]
|
|
|
|
for _, v := range b {
|
|
|
|
if v == 0 { // android logging won't print a zero byte
|
|
|
|
v = '0'
|
|
|
|
}
|
|
|
|
dst[writePos] = v
|
|
|
|
writePos++
|
|
|
|
if v == '\n' || writePos == len(dst)-1 {
|
|
|
|
dst[writePos] = 0
|
|
|
|
write(writeFD, unsafe.Pointer(&writeBuf[0]), int32(len(writeHeader)+writePos))
|
|
|
|
memclrBytes(dst)
|
|
|
|
writePos = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|