6
6
7
7
#include " android/log.h"
8
8
9
+ #include " erl_printf.h"
10
+
9
11
#define LOG_TAG " ErlangThread"
10
12
#define LOGV (...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
11
13
#define LOGE (...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
12
14
15
+ #define ALLOC (X ) malloc(X)
16
+ #define REALLOC (X,Y ) realloc(X,Y)
17
+ #define FREE (X ) free(X)
18
+
19
+ #define ANDROID_VPRINTF_BUF_INC_SIZE 1024
20
+
21
+ int (*ref_erts_vdsprintf)(erts_dsprintf_buf_t *dsbufp, const char *format, va_list arglist) = NULL ;
22
+
23
+ static erts_dsprintf_buf_t * grow_android_vprintf_buf (erts_dsprintf_buf_t *dsbufp, size_t need)
24
+ {
25
+ char *buf;
26
+ size_t size;
27
+
28
+ if (!dsbufp->str ) {
29
+ size = (((need + ANDROID_VPRINTF_BUF_INC_SIZE - 1 )
30
+ / ANDROID_VPRINTF_BUF_INC_SIZE)
31
+ * ANDROID_VPRINTF_BUF_INC_SIZE);
32
+ buf = (char *) ALLOC (size * sizeof (char ));
33
+ }
34
+ else {
35
+ size_t free_size = dsbufp->size - dsbufp->str_len ;
36
+
37
+ if (need <= free_size)
38
+ return dsbufp;
39
+
40
+ size = need - free_size + ANDROID_VPRINTF_BUF_INC_SIZE;
41
+ size = (((size + ANDROID_VPRINTF_BUF_INC_SIZE - 1 )
42
+ / ANDROID_VPRINTF_BUF_INC_SIZE)
43
+ * ANDROID_VPRINTF_BUF_INC_SIZE);
44
+ size += dsbufp->size ;
45
+ buf = (char *) REALLOC ((void *) dsbufp->str ,
46
+ size * sizeof (char ));
47
+ }
48
+ if (!buf)
49
+ return NULL ;
50
+ if (buf != dsbufp->str )
51
+ dsbufp->str = buf;
52
+ dsbufp->size = size;
53
+ return dsbufp;
54
+ }
55
+
56
+ static int android_stdout_vprintf (char *format, va_list arg_list) {
57
+ int res,i;
58
+ erts_dsprintf_buf_t dsbuf = ERTS_DSPRINTF_BUF_INITER (grow_android_vprintf_buf);
59
+ res = ref_erts_vdsprintf (&dsbuf, format, arg_list);
60
+ if (res >= 0 ) {
61
+ char *tmp = (char *)ALLOC ((dsbuf.str_len + 1 )*sizeof (char ));
62
+ for (i=0 ;i<dsbuf.str_len ;++i) {
63
+ tmp[i] = dsbuf.str [i];
64
+ }
65
+ tmp[dsbuf.str_len ] = NULL ;
66
+ LOGV (tmp);
67
+ FREE (tmp);
68
+ }
69
+ if (dsbuf.str )
70
+ FREE ((void *) dsbuf.str );
71
+ return res;
72
+ }
73
+
74
+ static int android_stderr_vprintf (char *format, va_list arg_list) {
75
+ int res,i;
76
+ erts_dsprintf_buf_t dsbuf = ERTS_DSPRINTF_BUF_INITER (grow_android_vprintf_buf);
77
+ res = ref_erts_vdsprintf (&dsbuf, format, arg_list);
78
+ if (res >= 0 ) {
79
+ char *tmp = (char *)ALLOC ((dsbuf.str_len + 1 )*sizeof (char ));
80
+ for (i=0 ;i<dsbuf.str_len ;++i) {
81
+ tmp[i] = dsbuf.str [i];
82
+ }
83
+ tmp[dsbuf.str_len ] = NULL ;
84
+ LOGE (tmp);
85
+ FREE (tmp);
86
+ }
87
+ if (dsbuf.str )
88
+ FREE ((void *) dsbuf.str );
89
+ return res;
90
+ }
91
+
13
92
JavaVM *jvm;
14
93
jclass ErlangThread;
15
94
jmethodID ErlMessageMethod;
@@ -20,6 +99,8 @@ JNIEXPORT void JNICALL Java_com_couchbase_android_ErlangThread_start_1erlang
20
99
int i, argc;
21
100
char ** argv;
22
101
void (*erl_start)(int , char **) = NULL ;
102
+ int (**erts_printf_stdout_func)(char *, va_list) = NULL ;
103
+ int (**erts_printf_stderr_func)(char *, va_list) = NULL ;
23
104
24
105
const char *sopath = env->GetStringUTFChars (j_sopath, &iscopy);
25
106
const char *bindir = env->GetStringUTFChars (j_bindir, &iscopy);
@@ -35,6 +116,31 @@ JNIEXPORT void JNICALL Java_com_couchbase_android_ErlangThread_start_1erlang
35
116
LOGE (" Failed to find erl_start: %s" , dlerror ());
36
117
goto cleanup;
37
118
}
119
+
120
+ *(void **)(&erts_printf_stdout_func) = dlsym (handle, " erts_printf_stdout_func" );
121
+ if (!erts_printf_stdout_func) {
122
+ LOGE (" Failed to find erts_printf_stdout_func: %s" , dlerror ());
123
+ goto cleanup;
124
+ }
125
+ else {
126
+ *erts_printf_stdout_func = android_stdout_vprintf;
127
+ }
128
+
129
+ *(void **)(&erts_printf_stderr_func) = dlsym (handle, " erts_printf_stderr_func" );
130
+ if (!erts_printf_stderr_func) {
131
+ LOGE (" Failed to find erts_printf_stderr_func: %s" , dlerror ());
132
+ goto cleanup;
133
+ }
134
+ else {
135
+ *erts_printf_stderr_func = android_stderr_vprintf;
136
+ }
137
+
138
+ *(void **)(&ref_erts_vdsprintf) = dlsym (handle, " erts_vdsprintf" );
139
+ if (!erts_vdsprintf) {
140
+ LOGE (" Failed to find erts_vdsprintf: %s" , dlerror ());
141
+ goto cleanup;
142
+ }
143
+
38
144
argc = env->GetArrayLength (j_args);
39
145
argv = (char **) malloc (sizeof (char *) * argc);
40
146
0 commit comments