github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/mobile/app/stdio_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 app 6 7 // Android redirects stdout and stderr to /dev/null. 8 // As these are common debugging utilities in Go, 9 // we redirect them to logcat. 10 // 11 // Unfortunately, logcat is line oriented, so we must buffer. 12 13 /* 14 #cgo LDFLAGS: -llog 15 #include <android/log.h> 16 #include <string.h> 17 */ 18 import "C" 19 20 import ( 21 "bufio" 22 "log" 23 "os" 24 "unsafe" 25 ) 26 27 var ( 28 ctag = C.CString("GoStdio") 29 ctagLog = C.CString("GoLog") 30 ) 31 32 type infoWriter struct{} 33 34 func (infoWriter) Write(p []byte) (n int, err error) { 35 cstr := C.CString(string(p)) 36 C.__android_log_write(C.ANDROID_LOG_INFO, ctagLog, cstr) 37 C.free(unsafe.Pointer(cstr)) 38 return len(p), nil 39 } 40 41 func lineLog(f *os.File, priority C.int) { 42 const logSize = 1024 // matches android/log.h. 43 r := bufio.NewReaderSize(f, logSize) 44 for { 45 line, _, err := r.ReadLine() 46 str := string(line) 47 if err != nil { 48 str += " " + err.Error() 49 } 50 cstr := C.CString(str) 51 C.__android_log_write(priority, ctag, cstr) 52 C.free(unsafe.Pointer(cstr)) 53 if err != nil { 54 break 55 } 56 } 57 } 58 59 func init() { 60 log.SetOutput(infoWriter{}) 61 // android logcat includes all of log.LstdFlags 62 log.SetFlags(log.Flags() &^ log.LstdFlags) 63 64 r, w, err := os.Pipe() 65 if err != nil { 66 panic(err) 67 } 68 os.Stderr = w 69 go lineLog(r, C.ANDROID_LOG_ERROR) 70 71 r, w, err = os.Pipe() 72 if err != nil { 73 panic(err) 74 } 75 os.Stdout = w 76 go lineLog(r, C.ANDROID_LOG_INFO) 77 }