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(dbg_SUITE,nif_funcs,load,NULL,upgrade,unload)42 ERL_NIF_INIT(dbg_SUITE, nif_funcs, load, NULL, upgrade, unload)
43 
44 static ERL_NIF_TERM atom_trace;
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_trace = enif_make_atom(env, "trace");
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 
88     return atom_trace;
89 }
90 
trace(ErlNifEnv * env,int argc,const ERL_NIF_TERM argv[])91 static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
92 {
93     int state_arity;
94     ErlNifPid self, to;
95     ERL_NIF_TERM *tuple, msg;
96     ASSERT(argc == 5);
97 
98     tuple = enif_alloc(sizeof(ERL_NIF_TERM)*(argc+1));
99     memcpy(tuple+1,argv,sizeof(ERL_NIF_TERM)*argc);
100 
101     if (enif_self(env, &self)) {
102         tuple[0] = enif_make_pid(env, &self);
103     } else {
104         tuple[0] = enif_make_atom(env, "undefined");
105     }
106 
107     msg = enif_make_tuple_from_array(env, tuple, argc + 1);
108     enif_get_local_pid(env, argv[1], &to);
109     enif_send(env, &to, NULL, msg);
110     enif_free(tuple);
111 
112     return atom_ok;
113 }
114