| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- // 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.
- package mobileinit
- /*
- To view the log output run:
- adb logcat GoLog:I *:S
- */
- // Android redirects stdout and stderr to /dev/null.
- // As these are common debugging utilities in Go,
- // we redirect them to logcat.
- //
- // Unfortunately, logcat is line oriented, so we must buffer.
- /*
- #cgo LDFLAGS: -landroid -llog
- #include <android/log.h>
- #include <stdlib.h>
- #include <string.h>
- */
- import "C"
- import (
- "bufio"
- "log"
- "os"
- "syscall"
- "unsafe"
- )
- var (
- ctag = C.CString("GoLog")
- // Store the writer end of the redirected stderr and stdout
- // so that they are not garbage collected and closed.
- stderr, stdout *os.File
- )
- type infoWriter struct{}
- func (infoWriter) Write(p []byte) (n int, err error) {
- cstr := C.CString(string(p))
- C.__android_log_write(C.ANDROID_LOG_INFO, ctag, cstr)
- C.free(unsafe.Pointer(cstr))
- return len(p), nil
- }
- func lineLog(f *os.File, priority C.int) {
- const logSize = 1024 // matches android/log.h.
- r := bufio.NewReaderSize(f, logSize)
- for {
- line, _, err := r.ReadLine()
- str := string(line)
- if err != nil {
- str += " " + err.Error()
- }
- cstr := C.CString(str)
- C.__android_log_write(priority, ctag, cstr)
- C.free(unsafe.Pointer(cstr))
- if err != nil {
- break
- }
- }
- }
- func init() {
- log.SetOutput(infoWriter{})
- // android logcat includes all of log.LstdFlags
- log.SetFlags(log.Flags() &^ log.LstdFlags)
- r, w, err := os.Pipe()
- if err != nil {
- panic(err)
- }
- stderr = w
- if err := syscall.Dup3(int(w.Fd()), int(os.Stderr.Fd()), 0); err != nil {
- panic(err)
- }
- go lineLog(r, C.ANDROID_LOG_ERROR)
- r, w, err = os.Pipe()
- if err != nil {
- panic(err)
- }
- stdout = w
- if err := syscall.Dup3(int(w.Fd()), int(os.Stdout.Fd()), 0); err != nil {
- panic(err)
- }
- go lineLog(r, C.ANDROID_LOG_INFO)
- }
|