gioui.org/ui@v0.0.0-20190926171558-ce74bc0cbaea/app/log_android.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package app 4 5 /* 6 #cgo LDFLAGS: -llog 7 8 #include <stdlib.h> 9 #include <android/log.h> 10 */ 11 import "C" 12 13 import ( 14 "bufio" 15 "log" 16 "os" 17 "runtime" 18 "syscall" 19 "unsafe" 20 ) 21 22 func init() { 23 // Android's logcat already includes timestamps. 24 log.SetFlags(log.Flags() &^ log.LstdFlags) 25 logFd(os.Stdout.Fd()) 26 logFd(os.Stderr.Fd()) 27 } 28 29 func logFd(fd uintptr) { 30 r, w, err := os.Pipe() 31 if err != nil { 32 panic(err) 33 } 34 if err := syscall.Dup3(int(w.Fd()), int(fd), syscall.O_CLOEXEC); err != nil { 35 panic(err) 36 } 37 go func() { 38 tag := C.CString("gio") 39 defer C.free(unsafe.Pointer(tag)) 40 // 1024 is the truncation limit from android/log.h, plus a \n. 41 lineBuf := bufio.NewReaderSize(r, 1024) 42 // The buffer to pass to C, including the terminating '\0'. 43 buf := make([]byte, lineBuf.Size()+1) 44 cbuf := (*C.char)(unsafe.Pointer(&buf[0])) 45 for { 46 line, _, err := lineBuf.ReadLine() 47 if err != nil { 48 break 49 } 50 copy(buf, line) 51 buf[len(line)] = 0 52 C.__android_log_write(C.ANDROID_LOG_INFO, tag, cbuf) 53 } 54 // The garbage collector doesn't know that w's fd was dup'ed. 55 // Avoid finalizing w, and thereby avoid its finalizer closing its fd. 56 runtime.KeepAlive(w) 57 }() 58 }