1 /*
2 * %CopyrightBegin%
3 *
4 * Copyright Ericsson AB 2009-2016. All Rights Reserved.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * %CopyrightEnd%
19 */
20
21 #include <erl_nif.h>
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <limits.h>
27
28 /* NIF interface declarations */
29 static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info);
30 static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info);
31 static void unload(ErlNifEnv* env, void* priv_data);
32
33 /* The NIFs: */
34 static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
35 static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
36
37 static ErlNifFunc nif_funcs[] = {
38 {"enabled", 3, enabled},
39 {"trace", 5, trace}
40 };
41
ERL_NIF_INIT(tracer_test,nif_funcs,load,NULL,upgrade,unload)42 ERL_NIF_INIT(tracer_test, nif_funcs, load, NULL, upgrade, unload)
43
44 static ERL_NIF_TERM atom_discard;
45 static ERL_NIF_TERM atom_ok;
46
47 #define ASSERT(expr) assert(expr)
48
49 static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
50 {
51
52 atom_discard = enif_make_atom(env, "discard");
53 atom_ok = enif_make_atom(env, "ok");
54
55 *priv_data = NULL;
56
57 return 0;
58 }
59
unload(ErlNifEnv * env,void * priv_data)60 static void unload(ErlNifEnv* env, void* priv_data)
61 {
62
63 }
64
upgrade(ErlNifEnv * env,void ** priv_data,void ** old_priv_data,ERL_NIF_TERM load_info)65 static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data,
66 ERL_NIF_TERM load_info)
67 {
68 if (*old_priv_data != NULL) {
69 return -1; /* Don't know how to do that */
70 }
71 if (*priv_data != NULL) {
72 return -1; /* Don't know how to do that */
73 }
74 if (load(env, priv_data, load_info)) {
75 return -1;
76 }
77 return 0;
78 }
79
enabled(ErlNifEnv * env,int argc,const ERL_NIF_TERM argv[])80 static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
81 {
82 int state_arity;
83 const ERL_NIF_TERM *state_tuple;
84 ERL_NIF_TERM value;
85 ASSERT(argc == 3);
86
87 if (!enif_get_tuple(env, argv[1], &state_arity, &state_tuple))
88 return atom_discard;
89
90 if (enif_get_map_value(env, state_tuple[0], argv[0], &value)) {
91 return value;
92 } else {
93 return atom_discard;
94 }
95 }
96
trace(ErlNifEnv * env,int argc,const ERL_NIF_TERM argv[])97 static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
98 {
99 int state_arity;
100 ErlNifPid self, to;
101 ERL_NIF_TERM *tuple, msg;
102 const ERL_NIF_TERM *state_tuple;
103 ASSERT(argc == 5);
104
105 enif_get_tuple(env, argv[1], &state_arity, &state_tuple);
106
107 tuple = enif_alloc(sizeof(ERL_NIF_TERM)*(argc));
108 memcpy(tuple,argv,sizeof(ERL_NIF_TERM)*argc);
109
110 msg = enif_make_tuple_from_array(env, tuple, argc);
111 enif_get_local_pid(env, state_tuple[1], &to);
112 enif_send(env, &to, NULL, msg);
113 enif_free(tuple);
114
115 return atom_ok;
116 }
117