github.com/reiver/go@v0.0.0-20150109200633-1d0c7792f172/src/runtime/print1_write_android.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import "unsafe"
     8  
     9  var (
    10  	writeHeader = []byte{6 /* ANDROID_LOG_ERROR */, 'G', 'o', 0}
    11  	writePath   = []byte("/dev/log/main\x00")
    12  	writeFD     uintptr
    13  	writeBuf    [1024]byte
    14  	writePos    int
    15  )
    16  
    17  func writeErr(b []byte) {
    18  	// Log format: "<priority 1 byte><tag n bytes>\x00<message m bytes>\x00"
    19  	// The entire log needs to be delivered in a single syscall (the NDK
    20  	// does this with writev). Each log is its own line, so we need to
    21  	// buffer writes until we see a newline.
    22  	if writeFD == 0 {
    23  		writeFD = uintptr(open(&writePath[0], 0x1 /* O_WRONLY */, 0))
    24  		if writeFD == 0 {
    25  			// It is hard to do anything here. Write to stderr just
    26  			// in case user has root on device and has run
    27  			//	adb shell setprop log.redirect-stdio true
    28  			msg := []byte("runtime: cannot open /dev/log/main\x00")
    29  			write(2, unsafe.Pointer(&msg[0]), int32(len(msg)))
    30  			exit(2)
    31  		}
    32  		copy(writeBuf[:], writeHeader)
    33  	}
    34  	dst := writeBuf[len(writeHeader):]
    35  	for _, v := range b {
    36  		if v == 0 { // android logging won't print a zero byte
    37  			v = '0'
    38  		}
    39  		dst[writePos] = v
    40  		writePos++
    41  		if v == '\n' || writePos == len(dst)-1 {
    42  			dst[writePos] = 0
    43  			write(writeFD, unsafe.Pointer(&writeBuf[0]), int32(len(writeHeader)+writePos))
    44  			memclrBytes(dst)
    45  			writePos = 0
    46  		}
    47  	}
    48  }