1fb3fb4f3Stomee /*
2fb3fb4f3Stomee * CDDL HEADER START
3fb3fb4f3Stomee *
4fb3fb4f3Stomee * The contents of this file are subject to the terms of the
5fb3fb4f3Stomee * Common Development and Distribution License (the "License").
6fb3fb4f3Stomee * You may not use this file except in compliance with the License.
7fb3fb4f3Stomee *
8fb3fb4f3Stomee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fb3fb4f3Stomee * or http://www.opensolaris.org/os/licensing.
10fb3fb4f3Stomee * See the License for the specific language governing permissions
11fb3fb4f3Stomee * and limitations under the License.
12fb3fb4f3Stomee *
13fb3fb4f3Stomee * When distributing Covered Code, include this CDDL HEADER in each
14fb3fb4f3Stomee * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fb3fb4f3Stomee * If applicable, add the following below this CDDL HEADER, with the
16fb3fb4f3Stomee * fields enclosed by brackets "[]" replaced with your own identifying
17fb3fb4f3Stomee * information: Portions Copyright [yyyy] [name of copyright owner]
18fb3fb4f3Stomee *
19fb3fb4f3Stomee * CDDL HEADER END
20fb3fb4f3Stomee */
21fb3fb4f3Stomee
22fb3fb4f3Stomee /*
23*e77b06d2Stomee * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24fb3fb4f3Stomee * Use is subject to license terms.
25fb3fb4f3Stomee */
26fb3fb4f3Stomee
27fb3fb4f3Stomee #pragma ident "%Z%%M% %I% %E% SMI"
28fb3fb4f3Stomee
29fb3fb4f3Stomee #include <stdlib.h>
30fb3fb4f3Stomee #include <stddef.h>
31fb3fb4f3Stomee #include <sys/types.h>
32fb3fb4f3Stomee #include <pthread.h>
33fb3fb4f3Stomee #include <string.h>
34fb3fb4f3Stomee #include <dtj_util.h>
35fb3fb4f3Stomee
36fb3fb4f3Stomee /*
37fb3fb4f3Stomee * dtj_util.c separates functionality that is generally useful from
38fb3fb4f3Stomee * that which is specific to the Java DTrace API. If moved to a separate
39fb3fb4f3Stomee * library, this functionality could be shared by other JNI wrappers.
40fb3fb4f3Stomee */
41fb3fb4f3Stomee
42fb3fb4f3Stomee boolean_t g_dtj_util_debug = B_FALSE;
43fb3fb4f3Stomee static boolean_t g_dtj_load_common = B_FALSE;
44fb3fb4f3Stomee
45fb3fb4f3Stomee /* NativeException */
46fb3fb4f3Stomee jclass g_nx_jc = 0;
47fb3fb4f3Stomee jmethodID g_nxinit_jm = 0;
48fb3fb4f3Stomee
49fb3fb4f3Stomee /* java.io.Serializable */
50fb3fb4f3Stomee jclass g_serial_jc = 0;
51fb3fb4f3Stomee
52fb3fb4f3Stomee /* java.lang.Number */
53fb3fb4f3Stomee jclass g_number_jc = 0;
54fb3fb4f3Stomee jmethodID g_shortval_jm = 0;
55fb3fb4f3Stomee jmethodID g_intval_jm = 0;
56fb3fb4f3Stomee jmethodID g_longval_jm = 0;
57fb3fb4f3Stomee
58fb3fb4f3Stomee /* java.lang.Byte */
59fb3fb4f3Stomee jclass g_byte_jc = 0;
60fb3fb4f3Stomee jmethodID g_byteinit_jm = 0;
61fb3fb4f3Stomee
62fb3fb4f3Stomee /* java.lang.Character */
63fb3fb4f3Stomee jclass g_char_jc = 0;
64fb3fb4f3Stomee jmethodID g_charinit_jm = 0;
65fb3fb4f3Stomee jmethodID g_charval_jm = 0;
66fb3fb4f3Stomee
67fb3fb4f3Stomee /* java.lang.Short */
68fb3fb4f3Stomee jclass g_short_jc = 0;
69fb3fb4f3Stomee jmethodID g_shortinit_jm = 0;
70fb3fb4f3Stomee
71fb3fb4f3Stomee /* java.lang.Integer */
72fb3fb4f3Stomee jclass g_int_jc = 0;
73fb3fb4f3Stomee jmethodID g_intinit_jm = 0;
74fb3fb4f3Stomee
75fb3fb4f3Stomee /* java.lang.Long */
76fb3fb4f3Stomee jclass g_long_jc = 0;
77fb3fb4f3Stomee jmethodID g_longinit_jm = 0;
78fb3fb4f3Stomee
79*e77b06d2Stomee /* java.math.BigInteger */
80*e77b06d2Stomee jclass g_bigint_jc = 0;
81*e77b06d2Stomee jmethodID g_bigint_val_jsm = 0;
82*e77b06d2Stomee jmethodID g_bigint_div_jm = 0;
83*e77b06d2Stomee jmethodID g_bigint_shl_jm = 0;
84*e77b06d2Stomee jmethodID g_bigint_or_jm = 0;
85*e77b06d2Stomee jmethodID g_bigint_setbit_jm = 0;
86*e77b06d2Stomee
87fb3fb4f3Stomee /* java.lang.String */
88fb3fb4f3Stomee jclass g_string_jc = 0;
89fb3fb4f3Stomee jmethodID g_strinit_bytes_jm = 0;
90fb3fb4f3Stomee jmethodID g_strbytes_jm = 0;
91fb3fb4f3Stomee jmethodID g_trim_jm = 0;
92fb3fb4f3Stomee
934ae67516Stomee /* java.lang.StringBuilder */
94fb3fb4f3Stomee jclass g_buf_jc = 0;
95fb3fb4f3Stomee jmethodID g_bufinit_jm = 0;
96fb3fb4f3Stomee jmethodID g_buf_append_char_jm = 0;
97fb3fb4f3Stomee jmethodID g_buf_append_int_jm = 0;
98fb3fb4f3Stomee jmethodID g_buf_append_long_jm = 0;
99fb3fb4f3Stomee jmethodID g_buf_append_str_jm = 0;
100fb3fb4f3Stomee jmethodID g_buf_append_obj_jm = 0;
101fb3fb4f3Stomee jmethodID g_buflen_jm = 0;
102fb3fb4f3Stomee jmethodID g_bufsetlen_jm = 0;
103fb3fb4f3Stomee
104fb3fb4f3Stomee /* java.lang.Object */
105fb3fb4f3Stomee jclass g_object_jc = 0;
106fb3fb4f3Stomee jmethodID g_tostring_jm = 0;
107fb3fb4f3Stomee jmethodID g_equals_jm = 0;
108fb3fb4f3Stomee
109fb3fb4f3Stomee /* java.lang.Enum */
110fb3fb4f3Stomee jclass g_enum_jc = 0;
111fb3fb4f3Stomee jmethodID g_enumname_jm = 0;
112fb3fb4f3Stomee
113fb3fb4f3Stomee /* List */
114fb3fb4f3Stomee jclass g_list_jc = 0;
115fb3fb4f3Stomee jmethodID g_listclear_jm = 0;
116fb3fb4f3Stomee jmethodID g_listadd_jm = 0;
117fb3fb4f3Stomee jmethodID g_listget_jm = 0;
118fb3fb4f3Stomee jmethodID g_listsize_jm = 0;
119fb3fb4f3Stomee
120fb3fb4f3Stomee /* Global list pools */
121fb3fb4f3Stomee static uu_list_pool_t *g_pointer_pool = NULL;
122fb3fb4f3Stomee static uu_list_pool_t *g_string_pool = NULL;
123fb3fb4f3Stomee
124fb3fb4f3Stomee static dtj_status_t dtj_get_jni_classes(JNIEnv *, uu_list_t *, uu_list_pool_t *,
125fb3fb4f3Stomee uu_list_pool_t *, uu_list_pool_t *, const dtj_table_entry_t *);
126fb3fb4f3Stomee static dtj_status_t dtj_cache_jni_methods(JNIEnv *, dtj_java_class_t *);
127fb3fb4f3Stomee static dtj_status_t dtj_cache_jni_fields(JNIEnv *, dtj_java_class_t *);
128fb3fb4f3Stomee
129fb3fb4f3Stomee /* Constructors */
130fb3fb4f3Stomee static dtj_java_class_t *dtj_java_class_create(JNIEnv *, jclass *, char *,
131fb3fb4f3Stomee uu_list_pool_t *, uu_list_pool_t *, uu_list_pool_t *);
132fb3fb4f3Stomee static dtj_java_method_t *dtj_java_method_create(JNIEnv *, jmethodID *, char *,
133fb3fb4f3Stomee char *, uu_list_pool_t *);
134fb3fb4f3Stomee static dtj_java_method_t *dtj_java_static_method_create(JNIEnv *, jmethodID *,
135fb3fb4f3Stomee char *, char *, uu_list_pool_t *);
136fb3fb4f3Stomee static dtj_java_field_t *dtj_java_field_create(JNIEnv *, jfieldID *, char *,
137fb3fb4f3Stomee char *, uu_list_pool_t *);
138fb3fb4f3Stomee static dtj_java_field_t *dtj_java_static_field_create(JNIEnv *, jfieldID *,
139fb3fb4f3Stomee char *, char *, uu_list_pool_t *);
140fb3fb4f3Stomee
141fb3fb4f3Stomee /* Destructors */
142fb3fb4f3Stomee static void dtj_java_class_destroy(void *, void *);
143fb3fb4f3Stomee static void dtj_java_method_destroy(void *, void *);
144fb3fb4f3Stomee static void dtj_java_field_destroy(void *, void *);
145fb3fb4f3Stomee
146fb3fb4f3Stomee /* Comparison functions, uu_compare_fn_t signature */
147fb3fb4f3Stomee static int dtj_java_class_cmp(const void *, const void *, void *);
148fb3fb4f3Stomee static int dtj_java_method_cmp(const void *, const void *, void *);
149fb3fb4f3Stomee static int dtj_java_field_cmp(const void *, const void *, void *);
150fb3fb4f3Stomee
151fb3fb4f3Stomee /* Java Throwable */
152fb3fb4f3Stomee static void dtj_throw(JNIEnv *, jclass, const char *, va_list *);
153fb3fb4f3Stomee
154fb3fb4f3Stomee /* Support for uu_list_t wrappers */
155fb3fb4f3Stomee static boolean_t dtj_check_pointer_pool(void);
156fb3fb4f3Stomee static boolean_t dtj_check_string_pool(void);
157fb3fb4f3Stomee
158fb3fb4f3Stomee dtj_status_t
dtj_load_common(JNIEnv * jenv)159fb3fb4f3Stomee dtj_load_common(JNIEnv *jenv)
160fb3fb4f3Stomee {
161fb3fb4f3Stomee dtj_status_t status;
162fb3fb4f3Stomee
163fb3fb4f3Stomee static const dtj_table_entry_t table[] = {
164fb3fb4f3Stomee /* NativeException */
165fb3fb4f3Stomee { JCLASS, &g_nx_jc,
166fb3fb4f3Stomee "org/opensolaris/os/dtrace/NativeException" },
167fb3fb4f3Stomee { JMETHOD, &g_nxinit_jm, CONSTRUCTOR,
168fb3fb4f3Stomee "(Ljava/lang/String;ILjava/lang/Throwable;)V" },
169fb3fb4f3Stomee
170fb3fb4f3Stomee /* java.io.Serializable */
171fb3fb4f3Stomee { JCLASS, &g_serial_jc, "java/io/Serializable" },
172fb3fb4f3Stomee
173fb3fb4f3Stomee /* java.lang.Number */
174fb3fb4f3Stomee { JCLASS, &g_number_jc, "java/lang/Number" },
175fb3fb4f3Stomee { JMETHOD, &g_shortval_jm, "shortValue", "()S" },
176fb3fb4f3Stomee { JMETHOD, &g_intval_jm, "intValue", "()I" },
177fb3fb4f3Stomee { JMETHOD, &g_longval_jm, "longValue", "()J" },
178fb3fb4f3Stomee
179fb3fb4f3Stomee /* java.lang.Byte */
180fb3fb4f3Stomee { JCLASS, &g_byte_jc, "java/lang/Byte" },
181fb3fb4f3Stomee { JMETHOD, &g_byteinit_jm, CONSTRUCTOR, "(B)V" },
182fb3fb4f3Stomee
183fb3fb4f3Stomee /* java.lang.Character */
184fb3fb4f3Stomee { JCLASS, &g_char_jc, "java/lang/Character" },
185fb3fb4f3Stomee { JMETHOD, &g_charinit_jm, CONSTRUCTOR, "(C)V" },
186fb3fb4f3Stomee { JMETHOD, &g_charval_jm, "charValue", "()C" },
187fb3fb4f3Stomee
188fb3fb4f3Stomee /* java.lang.Short */
189fb3fb4f3Stomee { JCLASS, &g_short_jc, "java/lang/Short" },
190fb3fb4f3Stomee { JMETHOD, &g_shortinit_jm, CONSTRUCTOR, "(S)V" },
191fb3fb4f3Stomee
192fb3fb4f3Stomee /* java.lang.Integer */
193fb3fb4f3Stomee { JCLASS, &g_int_jc, "java/lang/Integer" },
194fb3fb4f3Stomee { JMETHOD, &g_intinit_jm, CONSTRUCTOR, "(I)V" },
195fb3fb4f3Stomee
196fb3fb4f3Stomee /* java.lang.Long */
197fb3fb4f3Stomee { JCLASS, &g_long_jc, "java/lang/Long" },
198fb3fb4f3Stomee { JMETHOD, &g_longinit_jm, CONSTRUCTOR, "(J)V" },
199fb3fb4f3Stomee
200*e77b06d2Stomee /* java.math.BigInteger */
201*e77b06d2Stomee { JCLASS, &g_bigint_jc, "java/math/BigInteger" },
202*e77b06d2Stomee { JMETHOD_STATIC, &g_bigint_val_jsm, "valueOf",
203*e77b06d2Stomee "(J)Ljava/math/BigInteger;" },
204*e77b06d2Stomee { JMETHOD, &g_bigint_div_jm, "divide",
205*e77b06d2Stomee "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" },
206*e77b06d2Stomee { JMETHOD, &g_bigint_shl_jm, "shiftLeft",
207*e77b06d2Stomee "(I)Ljava/math/BigInteger;" },
208*e77b06d2Stomee { JMETHOD, &g_bigint_or_jm, "or",
209*e77b06d2Stomee "(Ljava/math/BigInteger;)Ljava/math/BigInteger;" },
210*e77b06d2Stomee { JMETHOD, &g_bigint_setbit_jm, "setBit",
211*e77b06d2Stomee "(I)Ljava/math/BigInteger;" },
212*e77b06d2Stomee
213fb3fb4f3Stomee /* java.lang.String */
214fb3fb4f3Stomee { JCLASS, &g_string_jc, "java/lang/String" },
215fb3fb4f3Stomee { JMETHOD, &g_strinit_bytes_jm, CONSTRUCTOR, "([B)V" },
216fb3fb4f3Stomee { JMETHOD, &g_strbytes_jm, "getBytes", "()[B" },
217fb3fb4f3Stomee { JMETHOD, &g_trim_jm, "trim", "()Ljava/lang/String;" },
218fb3fb4f3Stomee
2194ae67516Stomee /* java.lang.StringBuilder */
2204ae67516Stomee { JCLASS, &g_buf_jc, "java/lang/StringBuilder" },
221fb3fb4f3Stomee { JMETHOD, &g_bufinit_jm, CONSTRUCTOR, "()V" },
222fb3fb4f3Stomee { JMETHOD, &g_buf_append_char_jm, "append",
2234ae67516Stomee "(C)Ljava/lang/StringBuilder;" },
224fb3fb4f3Stomee { JMETHOD, &g_buf_append_int_jm, "append",
2254ae67516Stomee "(I)Ljava/lang/StringBuilder;" },
226fb3fb4f3Stomee { JMETHOD, &g_buf_append_long_jm, "append",
2274ae67516Stomee "(J)Ljava/lang/StringBuilder;" },
228fb3fb4f3Stomee { JMETHOD, &g_buf_append_str_jm, "append",
2294ae67516Stomee "(Ljava/lang/String;)Ljava/lang/StringBuilder;" },
230fb3fb4f3Stomee { JMETHOD, &g_buf_append_obj_jm, "append",
2314ae67516Stomee "(Ljava/lang/Object;)Ljava/lang/StringBuilder;" },
232fb3fb4f3Stomee { JMETHOD, &g_buflen_jm, "length", "()I" },
233fb3fb4f3Stomee { JMETHOD, &g_bufsetlen_jm, "setLength", "(I)V" },
234fb3fb4f3Stomee
235fb3fb4f3Stomee /* java.lang.Object */
236fb3fb4f3Stomee { JCLASS, &g_object_jc, "java/lang/Object" },
237fb3fb4f3Stomee { JMETHOD, &g_tostring_jm, "toString",
238fb3fb4f3Stomee "()Ljava/lang/String;" },
239fb3fb4f3Stomee { JMETHOD, &g_equals_jm, "equals",
240fb3fb4f3Stomee "(Ljava/lang/Object;)Z" },
241fb3fb4f3Stomee
242fb3fb4f3Stomee /* java.lang.Enum */
243fb3fb4f3Stomee { JCLASS, &g_enum_jc, "java/lang/Enum" },
244fb3fb4f3Stomee { JMETHOD, &g_enumname_jm, "name",
245fb3fb4f3Stomee "()Ljava/lang/String;" },
246fb3fb4f3Stomee
247fb3fb4f3Stomee /* List */
248fb3fb4f3Stomee { JCLASS, &g_list_jc, "java/util/List" },
249fb3fb4f3Stomee { JMETHOD, &g_listclear_jm, "clear", "()V" },
250fb3fb4f3Stomee { JMETHOD, &g_listadd_jm, "add", "(Ljava/lang/Object;)Z" },
251fb3fb4f3Stomee { JMETHOD, &g_listget_jm, "get", "(I)Ljava/lang/Object;" },
252fb3fb4f3Stomee { JMETHOD, &g_listsize_jm, "size", "()I" },
253fb3fb4f3Stomee
254fb3fb4f3Stomee { DTJ_TYPE_END }
255fb3fb4f3Stomee };
256fb3fb4f3Stomee
257fb3fb4f3Stomee status = dtj_cache_jni_classes(jenv, table);
258fb3fb4f3Stomee if (status == DTJ_OK) {
259fb3fb4f3Stomee g_dtj_load_common = B_TRUE;
260fb3fb4f3Stomee }
261fb3fb4f3Stomee return (status);
262fb3fb4f3Stomee }
263fb3fb4f3Stomee
264fb3fb4f3Stomee static int
265fb3fb4f3Stomee /* ARGSUSED */
dtj_java_class_cmp(const void * v1,const void * v2,void * arg)266fb3fb4f3Stomee dtj_java_class_cmp(const void * v1, const void * v2, void *arg)
267fb3fb4f3Stomee {
268fb3fb4f3Stomee const dtj_java_class_t *c1 = v1;
269fb3fb4f3Stomee const dtj_java_class_t *c2 = v2;
270fb3fb4f3Stomee return (strcmp(c1->djc_name, c2->djc_name));
271fb3fb4f3Stomee }
272fb3fb4f3Stomee
273fb3fb4f3Stomee static int
274fb3fb4f3Stomee /* ARGSUSED */
dtj_java_method_cmp(const void * v1,const void * v2,void * arg)275fb3fb4f3Stomee dtj_java_method_cmp(const void *v1, const void *v2, void *arg)
276fb3fb4f3Stomee {
277fb3fb4f3Stomee int cmp;
278fb3fb4f3Stomee const dtj_java_method_t *m1 = v1;
279fb3fb4f3Stomee const dtj_java_method_t *m2 = v2;
280fb3fb4f3Stomee cmp = strcmp(m1->djm_name, m2->djm_name);
281fb3fb4f3Stomee if (cmp == 0) {
282fb3fb4f3Stomee cmp = strcmp(m1->djm_signature, m2->djm_signature);
283fb3fb4f3Stomee }
284fb3fb4f3Stomee return (cmp);
285fb3fb4f3Stomee }
286fb3fb4f3Stomee
287fb3fb4f3Stomee static int
288fb3fb4f3Stomee /* ARGSUSED */
dtj_java_field_cmp(const void * v1,const void * v2,void * arg)289fb3fb4f3Stomee dtj_java_field_cmp(const void *v1, const void *v2, void *arg)
290fb3fb4f3Stomee {
291fb3fb4f3Stomee const dtj_java_field_t *f1 = v1;
292fb3fb4f3Stomee const dtj_java_field_t *f2 = v2;
293fb3fb4f3Stomee return (strcmp(f1->djf_name, f2->djf_name));
294fb3fb4f3Stomee }
295fb3fb4f3Stomee
296fb3fb4f3Stomee static dtj_java_class_t *
dtj_java_class_create(JNIEnv * jenv,jclass * jc,char * name,uu_list_pool_t * classpool,uu_list_pool_t * methodpool,uu_list_pool_t * fieldpool)297fb3fb4f3Stomee dtj_java_class_create(JNIEnv *jenv, jclass *jc, char *name,
298fb3fb4f3Stomee uu_list_pool_t *classpool, uu_list_pool_t *methodpool,
299fb3fb4f3Stomee uu_list_pool_t *fieldpool)
300fb3fb4f3Stomee {
301fb3fb4f3Stomee dtj_java_class_t *c = uu_zalloc(sizeof (dtj_java_class_t));
302fb3fb4f3Stomee if (c) {
303fb3fb4f3Stomee uu_list_node_init(c, &c->djc_node, classpool);
304fb3fb4f3Stomee c->djc_ptr = jc;
305fb3fb4f3Stomee c->djc_name = name;
306fb3fb4f3Stomee c->djc_methods = uu_list_create(methodpool, NULL,
307fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
308fb3fb4f3Stomee if (!c->djc_methods) {
309fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
310fb3fb4f3Stomee "Failed method list creation");
311fb3fb4f3Stomee uu_list_node_fini(c, &c->djc_node, classpool);
312fb3fb4f3Stomee free(c);
313fb3fb4f3Stomee c = NULL;
314fb3fb4f3Stomee }
315fb3fb4f3Stomee c->djc_fields = uu_list_create(fieldpool, NULL,
316fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
317fb3fb4f3Stomee if (!c->djc_fields) {
318fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
319fb3fb4f3Stomee "Failed field list creation");
320fb3fb4f3Stomee uu_list_destroy(c->djc_methods);
321fb3fb4f3Stomee c->djc_methods = NULL;
322fb3fb4f3Stomee uu_list_node_fini(c, &c->djc_node, classpool);
323fb3fb4f3Stomee free(c);
324fb3fb4f3Stomee c = NULL;
325fb3fb4f3Stomee }
326fb3fb4f3Stomee } else {
327fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
328fb3fb4f3Stomee "Failed to allocate class description");
329fb3fb4f3Stomee }
330fb3fb4f3Stomee return (c);
331fb3fb4f3Stomee }
332fb3fb4f3Stomee
333fb3fb4f3Stomee static dtj_java_method_t *
dtj_java_method_create(JNIEnv * jenv,jmethodID * jm,char * name,char * signature,uu_list_pool_t * methodpool)334fb3fb4f3Stomee dtj_java_method_create(JNIEnv *jenv, jmethodID *jm, char *name, char *signature,
335fb3fb4f3Stomee uu_list_pool_t *methodpool)
336fb3fb4f3Stomee {
337fb3fb4f3Stomee dtj_java_method_t *m = uu_zalloc(sizeof (dtj_java_method_t));
338fb3fb4f3Stomee if (m) {
339fb3fb4f3Stomee uu_list_node_init(m, &m->djm_node, methodpool);
340fb3fb4f3Stomee m->djm_ptr = jm;
341fb3fb4f3Stomee m->djm_name = name;
342fb3fb4f3Stomee m->djm_signature = signature;
343fb3fb4f3Stomee m->djm_static = B_FALSE;
344fb3fb4f3Stomee } else {
345fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
346fb3fb4f3Stomee "Failed to allocate method description");
347fb3fb4f3Stomee }
348fb3fb4f3Stomee return (m);
349fb3fb4f3Stomee }
350fb3fb4f3Stomee
351fb3fb4f3Stomee static dtj_java_method_t *
dtj_java_static_method_create(JNIEnv * jenv,jmethodID * jm,char * name,char * signature,uu_list_pool_t * methodpool)352fb3fb4f3Stomee dtj_java_static_method_create(JNIEnv *jenv, jmethodID *jm, char *name,
353fb3fb4f3Stomee char *signature, uu_list_pool_t *methodpool)
354fb3fb4f3Stomee {
355fb3fb4f3Stomee dtj_java_method_t *m = dtj_java_method_create(jenv, jm, name, signature,
356fb3fb4f3Stomee methodpool);
357fb3fb4f3Stomee if (m) {
358fb3fb4f3Stomee m->djm_static = B_TRUE;
359fb3fb4f3Stomee }
360fb3fb4f3Stomee return (m);
361fb3fb4f3Stomee }
362fb3fb4f3Stomee
363fb3fb4f3Stomee static dtj_java_field_t *
dtj_java_field_create(JNIEnv * jenv,jfieldID * jf,char * name,char * type,uu_list_pool_t * fieldpool)364fb3fb4f3Stomee dtj_java_field_create(JNIEnv *jenv, jfieldID *jf, char *name, char *type,
365fb3fb4f3Stomee uu_list_pool_t *fieldpool)
366fb3fb4f3Stomee {
367fb3fb4f3Stomee dtj_java_field_t *f = uu_zalloc(sizeof (dtj_java_field_t));
368fb3fb4f3Stomee if (f) {
369fb3fb4f3Stomee uu_list_node_init(f, &f->djf_node, fieldpool);
370fb3fb4f3Stomee f->djf_ptr = jf;
371fb3fb4f3Stomee f->djf_name = name;
372fb3fb4f3Stomee f->djf_type = type;
373fb3fb4f3Stomee f->djf_static = B_FALSE;
374fb3fb4f3Stomee } else {
375fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
376fb3fb4f3Stomee "Failed to allocate field description");
377fb3fb4f3Stomee }
378fb3fb4f3Stomee return (f);
379fb3fb4f3Stomee }
380fb3fb4f3Stomee
381fb3fb4f3Stomee static dtj_java_field_t *
dtj_java_static_field_create(JNIEnv * jenv,jfieldID * jf,char * name,char * type,uu_list_pool_t * fieldpool)382fb3fb4f3Stomee dtj_java_static_field_create(JNIEnv *jenv, jfieldID *jf, char *name, char *type,
383fb3fb4f3Stomee uu_list_pool_t *fieldpool)
384fb3fb4f3Stomee {
385fb3fb4f3Stomee dtj_java_field_t *f = dtj_java_field_create(jenv, jf, name, type,
386fb3fb4f3Stomee fieldpool);
387fb3fb4f3Stomee if (f) {
388fb3fb4f3Stomee f->djf_static = B_TRUE;
389fb3fb4f3Stomee }
390fb3fb4f3Stomee return (f);
391fb3fb4f3Stomee }
392fb3fb4f3Stomee
393fb3fb4f3Stomee static void
394fb3fb4f3Stomee /* ARGSUSED */
dtj_java_class_destroy(void * v,void * arg)395fb3fb4f3Stomee dtj_java_class_destroy(void *v, void *arg)
396fb3fb4f3Stomee {
397fb3fb4f3Stomee if (v) {
398fb3fb4f3Stomee dtj_java_class_t *c = v;
399fb3fb4f3Stomee c->djc_ptr = NULL; /* do not free user-defined storage */
400fb3fb4f3Stomee c->djc_name = NULL; /* string literal */
401fb3fb4f3Stomee dtj_list_destroy(c->djc_methods, dtj_java_method_destroy, NULL);
402fb3fb4f3Stomee dtj_list_destroy(c->djc_fields, dtj_java_field_destroy, NULL);
403fb3fb4f3Stomee c->djc_methods = NULL;
404fb3fb4f3Stomee c->djc_fields = NULL;
405fb3fb4f3Stomee uu_free(v);
406fb3fb4f3Stomee }
407fb3fb4f3Stomee }
408fb3fb4f3Stomee
409fb3fb4f3Stomee static void
410fb3fb4f3Stomee /* ARGSUSED */
dtj_java_method_destroy(void * v,void * arg)411fb3fb4f3Stomee dtj_java_method_destroy(void *v, void *arg)
412fb3fb4f3Stomee {
413fb3fb4f3Stomee if (v) {
414fb3fb4f3Stomee dtj_java_method_t *m = v;
415fb3fb4f3Stomee m->djm_ptr = NULL; /* do not free user-defined space */
416fb3fb4f3Stomee m->djm_name = NULL; /* string literal */
417fb3fb4f3Stomee m->djm_signature = NULL; /* string literal */
418fb3fb4f3Stomee uu_free(v);
419fb3fb4f3Stomee }
420fb3fb4f3Stomee }
421fb3fb4f3Stomee
422fb3fb4f3Stomee static void
423fb3fb4f3Stomee /* ARGSUSED */
dtj_java_field_destroy(void * v,void * arg)424fb3fb4f3Stomee dtj_java_field_destroy(void *v, void *arg)
425fb3fb4f3Stomee {
426fb3fb4f3Stomee if (v) {
427fb3fb4f3Stomee dtj_java_field_t *f = v;
428fb3fb4f3Stomee f->djf_ptr = NULL; /* do not free user-defined space */
429fb3fb4f3Stomee f->djf_name = NULL; /* string literal */
430fb3fb4f3Stomee f->djf_type = NULL; /* string literal */
431fb3fb4f3Stomee uu_free(f);
432fb3fb4f3Stomee }
433fb3fb4f3Stomee }
434fb3fb4f3Stomee
435fb3fb4f3Stomee dtj_status_t
dtj_cache_jni_classes(JNIEnv * jenv,const dtj_table_entry_t * table)436fb3fb4f3Stomee dtj_cache_jni_classes(JNIEnv *jenv, const dtj_table_entry_t *table)
437fb3fb4f3Stomee {
438fb3fb4f3Stomee dtj_java_class_t *class;
439fb3fb4f3Stomee uu_list_pool_t *classpool;
440fb3fb4f3Stomee uu_list_pool_t *methodpool;
441fb3fb4f3Stomee uu_list_pool_t *fieldpool;
442fb3fb4f3Stomee uu_list_t *classes;
443fb3fb4f3Stomee uu_list_walk_t *itr;
444fb3fb4f3Stomee jclass jc;
445fb3fb4f3Stomee jclass gjc;
446fb3fb4f3Stomee dtj_status_t status;
447fb3fb4f3Stomee
448fb3fb4f3Stomee classpool = uu_list_pool_create("classpool",
449fb3fb4f3Stomee sizeof (dtj_java_class_t),
450fb3fb4f3Stomee offsetof(dtj_java_class_t, djc_node), dtj_java_class_cmp,
451fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
452fb3fb4f3Stomee if (!classpool) {
453fb3fb4f3Stomee dtj_throw_out_of_memory(jenv, "failed class pool creation");
454fb3fb4f3Stomee return (DTJ_ERR);
455fb3fb4f3Stomee }
456fb3fb4f3Stomee methodpool = uu_list_pool_create("methodpool",
457fb3fb4f3Stomee sizeof (dtj_java_method_t),
458fb3fb4f3Stomee offsetof(dtj_java_method_t, djm_node), dtj_java_method_cmp,
459fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
460fb3fb4f3Stomee if (!methodpool) {
461fb3fb4f3Stomee dtj_throw_out_of_memory(jenv, "failed method pool creation");
462fb3fb4f3Stomee return (DTJ_ERR);
463fb3fb4f3Stomee }
464fb3fb4f3Stomee fieldpool = uu_list_pool_create("fieldpool",
465fb3fb4f3Stomee sizeof (dtj_java_field_t),
466fb3fb4f3Stomee offsetof(dtj_java_field_t, djf_node), dtj_java_field_cmp,
467fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
468fb3fb4f3Stomee if (!fieldpool) {
469fb3fb4f3Stomee dtj_throw_out_of_memory(jenv, "failed field pool creation");
470fb3fb4f3Stomee return (DTJ_ERR);
471fb3fb4f3Stomee }
472fb3fb4f3Stomee
473fb3fb4f3Stomee classes = uu_list_create(classpool, NULL,
474fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
475fb3fb4f3Stomee if (!classes) {
476fb3fb4f3Stomee dtj_throw_out_of_memory(jenv, "failed class list creation");
477fb3fb4f3Stomee return (DTJ_ERR);
478fb3fb4f3Stomee }
479fb3fb4f3Stomee
480fb3fb4f3Stomee status = dtj_get_jni_classes(jenv, classes, classpool, methodpool,
481fb3fb4f3Stomee fieldpool, table);
482fb3fb4f3Stomee if (status != DTJ_OK) {
483fb3fb4f3Stomee /* java error pending */
484fb3fb4f3Stomee return (status);
485fb3fb4f3Stomee }
486fb3fb4f3Stomee
487fb3fb4f3Stomee itr = uu_list_walk_start(classes, 0);
488fb3fb4f3Stomee while ((class = uu_list_walk_next(itr)) != NULL) {
489fb3fb4f3Stomee jc = (*jenv)->FindClass(jenv, class->djc_name);
490fb3fb4f3Stomee if (!jc) {
491fb3fb4f3Stomee /* NoClassDefFoundError pending */
492fb3fb4f3Stomee return (DTJ_ERR);
493fb3fb4f3Stomee }
494fb3fb4f3Stomee gjc = (*jenv)->NewGlobalRef(jenv, jc);
495fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
496fb3fb4f3Stomee if (!gjc) {
497fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
498fb3fb4f3Stomee "Failed to create global class reference");
499fb3fb4f3Stomee return (DTJ_ERR);
500fb3fb4f3Stomee }
501fb3fb4f3Stomee *(class->djc_ptr) = gjc;
502fb3fb4f3Stomee status = dtj_cache_jni_methods(jenv, class);
503fb3fb4f3Stomee if (status != DTJ_OK) {
504fb3fb4f3Stomee /* java error pending */
505fb3fb4f3Stomee return (status);
506fb3fb4f3Stomee }
507fb3fb4f3Stomee status = dtj_cache_jni_fields(jenv, class);
508fb3fb4f3Stomee if (status != DTJ_OK) {
509fb3fb4f3Stomee /* java error pending */
510fb3fb4f3Stomee return (status);
511fb3fb4f3Stomee }
512fb3fb4f3Stomee }
513fb3fb4f3Stomee uu_list_walk_end(itr);
514fb3fb4f3Stomee dtj_list_destroy(classes, dtj_java_class_destroy, NULL);
515fb3fb4f3Stomee uu_list_pool_destroy(classpool);
516fb3fb4f3Stomee uu_list_pool_destroy(methodpool);
517fb3fb4f3Stomee uu_list_pool_destroy(fieldpool);
518fb3fb4f3Stomee return (DTJ_OK);
519fb3fb4f3Stomee }
520fb3fb4f3Stomee
521fb3fb4f3Stomee /*
522fb3fb4f3Stomee * Converts JNI table entry desriptions into java_class_t descriptors.
523fb3fb4f3Stomee */
524fb3fb4f3Stomee static dtj_status_t
dtj_get_jni_classes(JNIEnv * jenv,uu_list_t * classes,uu_list_pool_t * classpool,uu_list_pool_t * methodpool,uu_list_pool_t * fieldpool,const dtj_table_entry_t * table)525fb3fb4f3Stomee dtj_get_jni_classes(JNIEnv *jenv, uu_list_t *classes,
526fb3fb4f3Stomee uu_list_pool_t *classpool, uu_list_pool_t *methodpool,
527fb3fb4f3Stomee uu_list_pool_t *fieldpool, const dtj_table_entry_t *table)
528fb3fb4f3Stomee {
529fb3fb4f3Stomee int i;
530fb3fb4f3Stomee dtj_java_class_t *c = NULL;
531fb3fb4f3Stomee dtj_java_method_t *m;
532fb3fb4f3Stomee dtj_java_field_t *f;
533fb3fb4f3Stomee
534fb3fb4f3Stomee for (i = 0; table[i].djte_type != DTJ_TYPE_END; ++i) {
535fb3fb4f3Stomee /*
536fb3fb4f3Stomee * Class not added until all of its method and field information
537fb3fb4f3Stomee * is attached, so we defer adding a class until the next
538fb3fb4f3Stomee * element with type JCLASS.
539fb3fb4f3Stomee */
540fb3fb4f3Stomee switch (table[i].djte_type) {
541fb3fb4f3Stomee case JCLASS:
542fb3fb4f3Stomee if (c) {
543fb3fb4f3Stomee /* previous class */
544fb3fb4f3Stomee if (!dtj_list_add(classes, c)) {
545fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
546fb3fb4f3Stomee "Failed to add class description");
547fb3fb4f3Stomee /*
548fb3fb4f3Stomee * In response to an error return value,
549fb3fb4f3Stomee * the caller will delete the class
550fb3fb4f3Stomee * descriptions list with any
551fb3fb4f3Stomee * descriptions created so far.
552fb3fb4f3Stomee */
553fb3fb4f3Stomee return (DTJ_ERR);
554fb3fb4f3Stomee }
555fb3fb4f3Stomee }
556fb3fb4f3Stomee c = dtj_java_class_create(jenv,
557fb3fb4f3Stomee (jclass *)table[i].djte_addr, table[i].djte_name,
558fb3fb4f3Stomee classpool, methodpool, fieldpool);
559fb3fb4f3Stomee if (!c) {
560fb3fb4f3Stomee /* OutOfMemoryError pending */
561fb3fb4f3Stomee return (DTJ_ERR);
562fb3fb4f3Stomee }
563fb3fb4f3Stomee break;
564fb3fb4f3Stomee case JMETHOD:
565fb3fb4f3Stomee if (!c) {
566fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
567fb3fb4f3Stomee "method description not preceded "
568fb3fb4f3Stomee "by class description");
569fb3fb4f3Stomee return (DTJ_ERR);
570fb3fb4f3Stomee }
571fb3fb4f3Stomee m = dtj_java_method_create(jenv,
572fb3fb4f3Stomee (jmethodID *)table[i].djte_addr,
573fb3fb4f3Stomee table[i].djte_name, table[i].djte_desc,
574fb3fb4f3Stomee methodpool);
575fb3fb4f3Stomee if (!m) {
576fb3fb4f3Stomee /* OutOfMemoryError pending */
577fb3fb4f3Stomee return (DTJ_ERR);
578fb3fb4f3Stomee }
579fb3fb4f3Stomee if (!dtj_list_add(c->djc_methods, m)) {
580fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
581fb3fb4f3Stomee "Failed to add method description");
582fb3fb4f3Stomee return (DTJ_ERR);
583fb3fb4f3Stomee }
584fb3fb4f3Stomee break;
585fb3fb4f3Stomee case JMETHOD_STATIC:
586fb3fb4f3Stomee if (!c) {
587fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
588fb3fb4f3Stomee "static method description not preceded "
589fb3fb4f3Stomee "by class description");
590fb3fb4f3Stomee return (DTJ_ERR);
591fb3fb4f3Stomee }
592fb3fb4f3Stomee m = dtj_java_static_method_create(jenv,
593fb3fb4f3Stomee (jmethodID *)table[i].djte_addr,
594fb3fb4f3Stomee table[i].djte_name, table[i].djte_desc,
595fb3fb4f3Stomee methodpool);
596fb3fb4f3Stomee if (!m) {
597fb3fb4f3Stomee /* OutOfMemoryError pending */
598fb3fb4f3Stomee return (DTJ_ERR);
599fb3fb4f3Stomee }
600fb3fb4f3Stomee if (!dtj_list_add(c->djc_methods, m)) {
601fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
602fb3fb4f3Stomee "Failed to add static method description");
603fb3fb4f3Stomee return (DTJ_ERR);
604fb3fb4f3Stomee }
605fb3fb4f3Stomee break;
606fb3fb4f3Stomee case JFIELD:
607fb3fb4f3Stomee if (!c) {
608fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
609fb3fb4f3Stomee "field description not preceded "
610fb3fb4f3Stomee "by class description");
611fb3fb4f3Stomee return (DTJ_ERR);
612fb3fb4f3Stomee }
613fb3fb4f3Stomee f = dtj_java_field_create(jenv,
614fb3fb4f3Stomee (jfieldID *)table[i].djte_addr,
615fb3fb4f3Stomee table[i].djte_name, table[i].djte_desc,
616fb3fb4f3Stomee fieldpool);
617fb3fb4f3Stomee if (!f) {
618fb3fb4f3Stomee /* OutOfMemoryError pending */
619fb3fb4f3Stomee return (DTJ_ERR);
620fb3fb4f3Stomee }
621fb3fb4f3Stomee if (!dtj_list_add(c->djc_fields, f)) {
622fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
623fb3fb4f3Stomee "Failed to add field description");
624fb3fb4f3Stomee return (DTJ_ERR);
625fb3fb4f3Stomee }
626fb3fb4f3Stomee break;
627fb3fb4f3Stomee case JFIELD_STATIC:
628fb3fb4f3Stomee if (!c) {
629fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
630fb3fb4f3Stomee "static field description not preceded "
631fb3fb4f3Stomee "by class description");
632fb3fb4f3Stomee return (DTJ_ERR);
633fb3fb4f3Stomee }
634fb3fb4f3Stomee f = dtj_java_static_field_create(jenv,
635fb3fb4f3Stomee (jfieldID *)table[i].djte_addr,
636fb3fb4f3Stomee table[i].djte_name, table[i].djte_desc,
637fb3fb4f3Stomee fieldpool);
638fb3fb4f3Stomee if (!f) {
639fb3fb4f3Stomee /* OutOfMemoryError pending */
640fb3fb4f3Stomee return (DTJ_ERR);
641fb3fb4f3Stomee }
642fb3fb4f3Stomee if (!dtj_list_add(c->djc_fields, f)) {
643fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
644fb3fb4f3Stomee "Failed to add static field description");
645fb3fb4f3Stomee return (DTJ_ERR);
646fb3fb4f3Stomee }
647fb3fb4f3Stomee break;
648fb3fb4f3Stomee default:
649fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
650fb3fb4f3Stomee "Unexpected jni_type_e: %d", table[i].djte_type);
651fb3fb4f3Stomee return (DTJ_ERR);
652fb3fb4f3Stomee }
653fb3fb4f3Stomee }
654fb3fb4f3Stomee if (c) {
655fb3fb4f3Stomee /* last class */
656fb3fb4f3Stomee if (!dtj_list_add(classes, c)) {
657fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
658fb3fb4f3Stomee "Failed to add class description");
659fb3fb4f3Stomee return (DTJ_ERR);
660fb3fb4f3Stomee }
661fb3fb4f3Stomee }
662fb3fb4f3Stomee
663fb3fb4f3Stomee return (DTJ_OK);
664fb3fb4f3Stomee }
665fb3fb4f3Stomee
666fb3fb4f3Stomee static dtj_status_t
dtj_cache_jni_methods(JNIEnv * jenv,dtj_java_class_t * c)667fb3fb4f3Stomee dtj_cache_jni_methods(JNIEnv *jenv, dtj_java_class_t *c)
668fb3fb4f3Stomee {
669fb3fb4f3Stomee dtj_java_method_t *method;
670fb3fb4f3Stomee jmethodID jm;
671fb3fb4f3Stomee uu_list_walk_t *itr;
672fb3fb4f3Stomee itr = uu_list_walk_start(c->djc_methods, 0);
673fb3fb4f3Stomee while ((method = uu_list_walk_next(itr)) != NULL) {
674fb3fb4f3Stomee if (method->djm_static) {
675fb3fb4f3Stomee jm = (*jenv)->GetStaticMethodID(jenv, *(c->djc_ptr),
676fb3fb4f3Stomee method->djm_name, method->djm_signature);
677fb3fb4f3Stomee } else {
678fb3fb4f3Stomee jm = (*jenv)->GetMethodID(jenv, *(c->djc_ptr),
679fb3fb4f3Stomee method->djm_name, method->djm_signature);
680fb3fb4f3Stomee }
681fb3fb4f3Stomee if (jm == 0) {
682fb3fb4f3Stomee /*
683fb3fb4f3Stomee * The pending NoSuchMethodError gives only the
684fb3fb4f3Stomee * method name, which is not so helpful for
685fb3fb4f3Stomee * overloaded methods and methods such as <init>
686fb3fb4f3Stomee * that have the same name in multiple classes.
687fb3fb4f3Stomee * Clear the pending error and throw one that
688fb3fb4f3Stomee * includes the class name and the method
689fb3fb4f3Stomee * signature.
690fb3fb4f3Stomee */
691fb3fb4f3Stomee jclass jc;
692fb3fb4f3Stomee char msg[DTJ_MSG_SIZE];
693fb3fb4f3Stomee (*jenv)->ExceptionClear(jenv);
694fb3fb4f3Stomee (void) snprintf(msg, sizeof (msg), "%s %s %s",
695fb3fb4f3Stomee c->djc_name, method->djm_name,
696fb3fb4f3Stomee method->djm_signature);
697fb3fb4f3Stomee
698fb3fb4f3Stomee jc = (*jenv)->FindClass(jenv,
699fb3fb4f3Stomee "java/lang/NoSuchMethodError");
700fb3fb4f3Stomee (*jenv)->ThrowNew(jenv, jc, msg);
701fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
702fb3fb4f3Stomee return (DTJ_ERR);
703fb3fb4f3Stomee }
704fb3fb4f3Stomee *(method->djm_ptr) = jm;
705fb3fb4f3Stomee }
706fb3fb4f3Stomee uu_list_walk_end(itr);
707fb3fb4f3Stomee return (DTJ_OK);
708fb3fb4f3Stomee }
709fb3fb4f3Stomee
710fb3fb4f3Stomee static dtj_status_t
dtj_cache_jni_fields(JNIEnv * jenv,dtj_java_class_t * c)711fb3fb4f3Stomee dtj_cache_jni_fields(JNIEnv *jenv, dtj_java_class_t *c)
712fb3fb4f3Stomee {
713fb3fb4f3Stomee dtj_java_field_t *field;
714fb3fb4f3Stomee jfieldID jf;
715fb3fb4f3Stomee uu_list_walk_t *itr;
716fb3fb4f3Stomee itr = uu_list_walk_start(c->djc_fields, 0);
717fb3fb4f3Stomee while ((field = uu_list_walk_next(itr)) != NULL) {
718fb3fb4f3Stomee if (field->djf_static) {
719fb3fb4f3Stomee jf = (*jenv)->GetStaticFieldID(jenv, *(c->djc_ptr),
720fb3fb4f3Stomee field->djf_name, field->djf_type);
721fb3fb4f3Stomee } else {
722fb3fb4f3Stomee jf = (*jenv)->GetFieldID(jenv, *(c->djc_ptr),
723fb3fb4f3Stomee field->djf_name, field->djf_type);
724fb3fb4f3Stomee }
725fb3fb4f3Stomee if (jf == 0) {
726fb3fb4f3Stomee jclass jc;
727fb3fb4f3Stomee char msg[DTJ_MSG_SIZE];
728fb3fb4f3Stomee (*jenv)->ExceptionClear(jenv);
729fb3fb4f3Stomee (void) snprintf(msg, sizeof (msg),
730fb3fb4f3Stomee "%s.%s signature: %s", c->djc_name,
731fb3fb4f3Stomee field->djf_name, field->djf_type);
732fb3fb4f3Stomee
733fb3fb4f3Stomee jc = (*jenv)->FindClass(jenv,
734fb3fb4f3Stomee "java/lang/NoSuchFieldError");
735fb3fb4f3Stomee (*jenv)->ThrowNew(jenv, jc, msg);
736fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
737fb3fb4f3Stomee return (DTJ_ERR);
738fb3fb4f3Stomee }
739fb3fb4f3Stomee *(field->djf_ptr) = jf;
740fb3fb4f3Stomee }
741fb3fb4f3Stomee uu_list_walk_end(itr);
742fb3fb4f3Stomee return (DTJ_OK);
743fb3fb4f3Stomee }
744fb3fb4f3Stomee
745fb3fb4f3Stomee
746fb3fb4f3Stomee /* Common utilities */
747fb3fb4f3Stomee
748fb3fb4f3Stomee static void
dtj_throw(JNIEnv * jenv,jclass jc,const char * fmt,va_list * ap)749fb3fb4f3Stomee dtj_throw(JNIEnv *jenv, jclass jc, const char *fmt, va_list *ap)
750fb3fb4f3Stomee {
751fb3fb4f3Stomee char msg[DTJ_MSG_SIZE];
752fb3fb4f3Stomee (void) vsnprintf(msg, sizeof (msg), fmt, *ap);
753fb3fb4f3Stomee (*jenv)->ThrowNew(jenv, jc, msg);
754fb3fb4f3Stomee }
755fb3fb4f3Stomee
756fb3fb4f3Stomee void
dtj_throw_out_of_memory(JNIEnv * jenv,const char * fmt,...)757fb3fb4f3Stomee dtj_throw_out_of_memory(JNIEnv *jenv, const char *fmt, ...)
758fb3fb4f3Stomee {
759fb3fb4f3Stomee va_list ap;
760fb3fb4f3Stomee jclass jc;
761fb3fb4f3Stomee /*
762fb3fb4f3Stomee * JNI documentation unclear whether NewGlobalRef() can throw
763fb3fb4f3Stomee * OutOfMemoryError, so we'll make this function safe in case
764fb3fb4f3Stomee * OutOfMemoryError has already been thrown
765fb3fb4f3Stomee */
766fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
767fb3fb4f3Stomee return;
768fb3fb4f3Stomee }
769fb3fb4f3Stomee jc = (*jenv)->FindClass(jenv,
770fb3fb4f3Stomee "java/lang/OutOfMemoryError");
771fb3fb4f3Stomee va_start(ap, fmt);
772fb3fb4f3Stomee dtj_throw(jenv, jc, fmt, &ap);
773fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
774fb3fb4f3Stomee va_end(ap);
775fb3fb4f3Stomee }
776fb3fb4f3Stomee
777fb3fb4f3Stomee void
dtj_throw_null_pointer(JNIEnv * jenv,const char * fmt,...)778fb3fb4f3Stomee dtj_throw_null_pointer(JNIEnv *jenv, const char *fmt, ...)
779fb3fb4f3Stomee {
780fb3fb4f3Stomee va_list ap;
781fb3fb4f3Stomee jclass jc = (*jenv)->FindClass(jenv,
782fb3fb4f3Stomee "java/lang/NullPointerException");
783fb3fb4f3Stomee va_start(ap, fmt);
784fb3fb4f3Stomee dtj_throw(jenv, jc, fmt, &ap);
785fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
786fb3fb4f3Stomee va_end(ap);
787fb3fb4f3Stomee }
788fb3fb4f3Stomee
789fb3fb4f3Stomee void
dtj_throw_illegal_state(JNIEnv * jenv,const char * fmt,...)790fb3fb4f3Stomee dtj_throw_illegal_state(JNIEnv *jenv, const char *fmt, ...)
791fb3fb4f3Stomee {
792fb3fb4f3Stomee va_list ap;
793fb3fb4f3Stomee jclass jc = (*jenv)->FindClass(jenv,
794fb3fb4f3Stomee "java/lang/IllegalStateException");
795fb3fb4f3Stomee va_start(ap, fmt);
796fb3fb4f3Stomee dtj_throw(jenv, jc, fmt, &ap);
797fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
798fb3fb4f3Stomee va_end(ap);
799fb3fb4f3Stomee }
800fb3fb4f3Stomee
801fb3fb4f3Stomee void
dtj_throw_illegal_argument(JNIEnv * jenv,const char * fmt,...)802fb3fb4f3Stomee dtj_throw_illegal_argument(JNIEnv *jenv, const char *fmt, ...)
803fb3fb4f3Stomee {
804fb3fb4f3Stomee va_list ap;
805fb3fb4f3Stomee jclass jc = (*jenv)->FindClass(jenv,
806fb3fb4f3Stomee "java/lang/IllegalArgumentException");
807fb3fb4f3Stomee va_start(ap, fmt);
808fb3fb4f3Stomee dtj_throw(jenv, jc, fmt, &ap);
809fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
810fb3fb4f3Stomee va_end(ap);
811fb3fb4f3Stomee }
812fb3fb4f3Stomee
813fb3fb4f3Stomee void
dtj_throw_no_such_element(JNIEnv * jenv,const char * fmt,...)814fb3fb4f3Stomee dtj_throw_no_such_element(JNIEnv *jenv, const char *fmt, ...)
815fb3fb4f3Stomee {
816fb3fb4f3Stomee va_list ap;
817fb3fb4f3Stomee jclass jc = (*jenv)->FindClass(jenv,
818fb3fb4f3Stomee "java/util/NoSuchElementException");
819fb3fb4f3Stomee va_start(ap, fmt);
820fb3fb4f3Stomee dtj_throw(jenv, jc, fmt, &ap);
821fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
822fb3fb4f3Stomee va_end(ap);
823fb3fb4f3Stomee }
824fb3fb4f3Stomee
825fb3fb4f3Stomee void
dtj_throw_class_cast(JNIEnv * jenv,const char * fmt,...)826fb3fb4f3Stomee dtj_throw_class_cast(JNIEnv *jenv, const char *fmt, ...)
827fb3fb4f3Stomee {
828fb3fb4f3Stomee va_list ap;
829fb3fb4f3Stomee jclass jc = (*jenv)->FindClass(jenv,
830fb3fb4f3Stomee "java/lang/ClassCastException");
831fb3fb4f3Stomee va_start(ap, fmt);
832fb3fb4f3Stomee dtj_throw(jenv, jc, fmt, &ap);
833fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
834fb3fb4f3Stomee va_end(ap);
835fb3fb4f3Stomee }
836fb3fb4f3Stomee
837fb3fb4f3Stomee void
dtj_throw_assertion(JNIEnv * jenv,const char * fmt,...)838fb3fb4f3Stomee dtj_throw_assertion(JNIEnv *jenv, const char *fmt, ...)
839fb3fb4f3Stomee {
840fb3fb4f3Stomee va_list ap;
841fb3fb4f3Stomee jclass jc = (*jenv)->FindClass(jenv,
842fb3fb4f3Stomee "java/lang/AssertionError");
843fb3fb4f3Stomee va_start(ap, fmt);
844fb3fb4f3Stomee dtj_throw(jenv, jc, fmt, &ap);
845fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
846fb3fb4f3Stomee va_end(ap);
847fb3fb4f3Stomee }
848fb3fb4f3Stomee
849fb3fb4f3Stomee void
dtj_throw_resource_limit(JNIEnv * jenv,const char * fmt,...)850fb3fb4f3Stomee dtj_throw_resource_limit(JNIEnv *jenv, const char *fmt, ...)
851fb3fb4f3Stomee {
852fb3fb4f3Stomee va_list ap;
853fb3fb4f3Stomee jclass jc = (*jenv)->FindClass(jenv,
854fb3fb4f3Stomee "org/opensolaris/os/dtrace/ResourceLimitException");
855fb3fb4f3Stomee va_start(ap, fmt);
856fb3fb4f3Stomee dtj_throw(jenv, jc, fmt, &ap);
857fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jc);
858fb3fb4f3Stomee va_end(ap);
859fb3fb4f3Stomee }
860fb3fb4f3Stomee
861fb3fb4f3Stomee void
dtj_wrap_exception(JNIEnv * jenv,const char * file,int line)862fb3fb4f3Stomee dtj_wrap_exception(JNIEnv *jenv, const char *file, int line)
863fb3fb4f3Stomee {
864fb3fb4f3Stomee jthrowable e = NULL;
865fb3fb4f3Stomee jthrowable nx = NULL;
866fb3fb4f3Stomee jstring jfile = NULL;
867fb3fb4f3Stomee
868fb3fb4f3Stomee e = (*jenv)->ExceptionOccurred(jenv);
869fb3fb4f3Stomee if (!e) {
870fb3fb4f3Stomee return;
871fb3fb4f3Stomee }
872fb3fb4f3Stomee
873fb3fb4f3Stomee if (!g_dtj_load_common) {
874fb3fb4f3Stomee return;
875fb3fb4f3Stomee }
876fb3fb4f3Stomee
877fb3fb4f3Stomee (*jenv)->ExceptionClear(jenv);
878fb3fb4f3Stomee
879fb3fb4f3Stomee /* Unsafe to test while exception pending */
880fb3fb4f3Stomee if ((*jenv)->IsInstanceOf(jenv, e, g_nx_jc)) {
881fb3fb4f3Stomee /* Already wrapped */
882fb3fb4f3Stomee (*jenv)->Throw(jenv, e);
883fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, e);
884fb3fb4f3Stomee return;
885fb3fb4f3Stomee }
886fb3fb4f3Stomee
887fb3fb4f3Stomee jfile = dtj_NewStringNative(jenv, file);
888fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
889fb3fb4f3Stomee /*
890fb3fb4f3Stomee * Only wrap the exception if possible, otherwise just throw the
891fb3fb4f3Stomee * original exception.
892fb3fb4f3Stomee */
893fb3fb4f3Stomee (*jenv)->ExceptionClear(jenv);
894fb3fb4f3Stomee (*jenv)->Throw(jenv, e);
895fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, e);
896fb3fb4f3Stomee return;
897fb3fb4f3Stomee }
898fb3fb4f3Stomee
899fb3fb4f3Stomee nx = (jthrowable)(*jenv)->NewObject(jenv, g_nx_jc, g_nxinit_jm,
900fb3fb4f3Stomee jfile, line, e);
901fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jfile);
902fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
903fb3fb4f3Stomee (*jenv)->ExceptionClear(jenv);
904fb3fb4f3Stomee (*jenv)->Throw(jenv, e);
905fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, e);
906fb3fb4f3Stomee return;
907fb3fb4f3Stomee }
908fb3fb4f3Stomee
909fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, e);
910fb3fb4f3Stomee (*jenv)->Throw(jenv, nx);
911fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, nx);
912fb3fb4f3Stomee }
913fb3fb4f3Stomee
914fb3fb4f3Stomee /*
915fb3fb4f3Stomee * Calls the given java object's toString() method and prints the value to
916fb3fb4f3Stomee * stdout. Useful for debugging. Guaranteed that no exception is pending when
917fb3fb4f3Stomee * this function returns.
918fb3fb4f3Stomee */
919fb3fb4f3Stomee void
dtj_print_object(JNIEnv * jenv,jobject jobj)920fb3fb4f3Stomee dtj_print_object(JNIEnv *jenv, jobject jobj)
921fb3fb4f3Stomee {
922fb3fb4f3Stomee jstring jstr;
923fb3fb4f3Stomee const char *cstr;
924fb3fb4f3Stomee
925fb3fb4f3Stomee if (!g_dtj_load_common) {
926fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
927fb3fb4f3Stomee "dtj_load_common() has not been called");
928fb3fb4f3Stomee (*jenv)->ExceptionDescribe(jenv); /* clears the exception */
929fb3fb4f3Stomee return;
930fb3fb4f3Stomee }
931fb3fb4f3Stomee
932fb3fb4f3Stomee if (!jobj) {
933fb3fb4f3Stomee (void) printf("null\n");
934fb3fb4f3Stomee return;
935fb3fb4f3Stomee }
936fb3fb4f3Stomee
937fb3fb4f3Stomee jstr = (*jenv)->CallObjectMethod(jenv, jobj, g_tostring_jm);
938fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
939fb3fb4f3Stomee (*jenv)->ExceptionDescribe(jenv); /* clears the exception */
940fb3fb4f3Stomee return;
941fb3fb4f3Stomee }
942fb3fb4f3Stomee cstr = (*jenv)->GetStringUTFChars(jenv, jstr, 0);
943fb3fb4f3Stomee if (cstr) {
944fb3fb4f3Stomee (void) printf("%s\n", cstr);
945fb3fb4f3Stomee } else {
946fb3fb4f3Stomee (*jenv)->ExceptionDescribe(jenv); /* clears the exception */
947fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jstr);
948fb3fb4f3Stomee return;
949fb3fb4f3Stomee }
950fb3fb4f3Stomee (*jenv)->ReleaseStringUTFChars(jenv, jstr, cstr);
951fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jstr);
952fb3fb4f3Stomee }
953fb3fb4f3Stomee
954*e77b06d2Stomee jobject
dtj_uint64(JNIEnv * jenv,uint64_t u)955*e77b06d2Stomee dtj_uint64(JNIEnv *jenv, uint64_t u)
956*e77b06d2Stomee {
957*e77b06d2Stomee int64_t i = (int64_t)u;
958*e77b06d2Stomee jobject val64;
959*e77b06d2Stomee
960*e77b06d2Stomee if (i >= 0) {
961*e77b06d2Stomee val64 = (*jenv)->CallStaticObjectMethod(jenv, g_bigint_jc,
962*e77b06d2Stomee g_bigint_val_jsm, u);
963*e77b06d2Stomee } else {
964*e77b06d2Stomee jobject tmp;
965*e77b06d2Stomee
966*e77b06d2Stomee u ^= ((uint64_t)0x1 << 63);
967*e77b06d2Stomee val64 = (*jenv)->CallStaticObjectMethod(jenv, g_bigint_jc,
968*e77b06d2Stomee g_bigint_val_jsm, u);
969*e77b06d2Stomee tmp = val64;
970*e77b06d2Stomee val64 = (*jenv)->CallObjectMethod(jenv, tmp,
971*e77b06d2Stomee g_bigint_setbit_jm, 63);
972*e77b06d2Stomee (*jenv)->DeleteLocalRef(jenv, tmp);
973*e77b06d2Stomee }
974*e77b06d2Stomee
975*e77b06d2Stomee return (val64);
976*e77b06d2Stomee }
977*e77b06d2Stomee
978*e77b06d2Stomee jobject
dtj_int128(JNIEnv * jenv,uint64_t high,uint64_t low)979*e77b06d2Stomee dtj_int128(JNIEnv *jenv, uint64_t high, uint64_t low)
980*e77b06d2Stomee {
981*e77b06d2Stomee jobject val128;
982*e77b06d2Stomee jobject low64;
983*e77b06d2Stomee jobject tmp;
984*e77b06d2Stomee
985*e77b06d2Stomee val128 = (*jenv)->CallStaticObjectMethod(jenv, g_bigint_jc,
986*e77b06d2Stomee g_bigint_val_jsm, high);
987*e77b06d2Stomee tmp = val128;
988*e77b06d2Stomee val128 = (*jenv)->CallObjectMethod(jenv, tmp, g_bigint_shl_jm, 64);
989*e77b06d2Stomee (*jenv)->DeleteLocalRef(jenv, tmp);
990*e77b06d2Stomee low64 = dtj_uint64(jenv, low);
991*e77b06d2Stomee tmp = val128;
992*e77b06d2Stomee val128 = (*jenv)->CallObjectMethod(jenv, tmp, g_bigint_or_jm, low64);
993*e77b06d2Stomee (*jenv)->DeleteLocalRef(jenv, tmp);
994*e77b06d2Stomee (*jenv)->DeleteLocalRef(jenv, low64);
995*e77b06d2Stomee
996*e77b06d2Stomee return (val128);
997*e77b06d2Stomee }
998*e77b06d2Stomee
999fb3fb4f3Stomee jstring
dtj_format_string(JNIEnv * jenv,const char * fmt,...)1000fb3fb4f3Stomee dtj_format_string(JNIEnv *jenv, const char *fmt, ...)
1001fb3fb4f3Stomee {
1002fb3fb4f3Stomee va_list ap;
1003fb3fb4f3Stomee char str[DTJ_MSG_SIZE];
1004fb3fb4f3Stomee
1005fb3fb4f3Stomee jstring jstr = NULL;
1006fb3fb4f3Stomee
1007fb3fb4f3Stomee va_start(ap, fmt);
1008fb3fb4f3Stomee (void) vsnprintf(str, sizeof (str), fmt, ap);
1009fb3fb4f3Stomee va_end(ap);
1010fb3fb4f3Stomee
1011fb3fb4f3Stomee jstr = dtj_NewStringNative(jenv, str);
1012fb3fb4f3Stomee /* return NULL if OutOfMemoryError pending */
1013fb3fb4f3Stomee return (jstr);
1014fb3fb4f3Stomee }
1015fb3fb4f3Stomee
1016fb3fb4f3Stomee jstring
dtj_NewStringNative(JNIEnv * jenv,const char * str)1017fb3fb4f3Stomee dtj_NewStringNative(JNIEnv *jenv, const char *str)
1018fb3fb4f3Stomee {
1019fb3fb4f3Stomee jstring result;
1020fb3fb4f3Stomee jbyteArray bytes = 0;
1021fb3fb4f3Stomee int len;
1022fb3fb4f3Stomee
1023fb3fb4f3Stomee if (!g_dtj_load_common) {
1024fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
1025fb3fb4f3Stomee "dtj_load_common() has not been called");
1026fb3fb4f3Stomee return (NULL);
1027fb3fb4f3Stomee }
1028fb3fb4f3Stomee
1029fb3fb4f3Stomee len = strlen(str);
1030fb3fb4f3Stomee
1031fb3fb4f3Stomee bytes = (*jenv)->NewByteArray(jenv, len);
1032fb3fb4f3Stomee if (!bytes) {
1033fb3fb4f3Stomee return (NULL); /* OutOfMemoryError pending */
1034fb3fb4f3Stomee }
1035fb3fb4f3Stomee (*jenv)->SetByteArrayRegion(jenv, bytes, 0, len,
1036fb3fb4f3Stomee (jbyte *)str);
1037fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
1038fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, bytes);
1039fb3fb4f3Stomee return (NULL); /* ArrayIndexOutOfBoundsException pending */
1040fb3fb4f3Stomee }
1041fb3fb4f3Stomee result = (*jenv)->NewObject(jenv, g_string_jc, g_strinit_bytes_jm,
1042fb3fb4f3Stomee bytes);
1043fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, bytes);
1044fb3fb4f3Stomee /* return NULL result if exception pending */
1045fb3fb4f3Stomee return (result);
1046fb3fb4f3Stomee }
1047fb3fb4f3Stomee
1048fb3fb4f3Stomee char *
dtj_GetStringNativeChars(JNIEnv * jenv,jstring jstr)1049fb3fb4f3Stomee dtj_GetStringNativeChars(JNIEnv *jenv, jstring jstr)
1050fb3fb4f3Stomee {
1051fb3fb4f3Stomee jbyteArray bytes = NULL;
1052fb3fb4f3Stomee
1053fb3fb4f3Stomee jint len;
1054fb3fb4f3Stomee char *result = NULL;
1055fb3fb4f3Stomee
1056fb3fb4f3Stomee if (!g_dtj_load_common) {
1057fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
1058fb3fb4f3Stomee "dtj_load_common() has not been called");
1059fb3fb4f3Stomee return (NULL);
1060fb3fb4f3Stomee }
1061fb3fb4f3Stomee
1062fb3fb4f3Stomee bytes = (*jenv)->CallObjectMethod(jenv, jstr, g_strbytes_jm);
1063fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
1064fb3fb4f3Stomee return (NULL); /* OutOfMemoryError pending */
1065fb3fb4f3Stomee }
1066fb3fb4f3Stomee /* Does not throw exceptions */
1067fb3fb4f3Stomee len = (*jenv)->GetArrayLength(jenv, bytes);
1068fb3fb4f3Stomee result = malloc(len + 1);
1069fb3fb4f3Stomee if (!result) {
1070fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, bytes);
1071fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
1072fb3fb4f3Stomee "could not allocate native chars");
1073fb3fb4f3Stomee return (NULL);
1074fb3fb4f3Stomee }
1075fb3fb4f3Stomee
1076fb3fb4f3Stomee /* Skip check for ArrayIndexOutOfBoundsException */
1077fb3fb4f3Stomee (*jenv)->GetByteArrayRegion(jenv, bytes, 0, len,
1078fb3fb4f3Stomee (jbyte *)result);
1079fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, bytes);
1080fb3fb4f3Stomee result[len] = '\0'; /* NUL-terminate */
1081fb3fb4f3Stomee
1082fb3fb4f3Stomee return (result);
1083fb3fb4f3Stomee }
1084fb3fb4f3Stomee
1085fb3fb4f3Stomee void
1086fb3fb4f3Stomee /* ARGSUSED */
dtj_ReleaseStringNativeChars(JNIEnv * jenv,jstring jstr,const char * str)1087fb3fb4f3Stomee dtj_ReleaseStringNativeChars(JNIEnv *jenv, jstring jstr, const char *str)
1088fb3fb4f3Stomee {
1089fb3fb4f3Stomee free((void *)str);
1090fb3fb4f3Stomee }
1091fb3fb4f3Stomee
1092fb3fb4f3Stomee char **
dtj_get_argv(JNIEnv * jenv,jobjectArray args,int * argc)1093fb3fb4f3Stomee dtj_get_argv(JNIEnv *jenv, jobjectArray args, int *argc)
1094fb3fb4f3Stomee {
1095fb3fb4f3Stomee char **argv = NULL; /* return value */
1096fb3fb4f3Stomee const char *str;
1097fb3fb4f3Stomee int i;
1098fb3fb4f3Stomee
1099fb3fb4f3Stomee jstring jstr = NULL;
1100fb3fb4f3Stomee
1101fb3fb4f3Stomee if (!g_dtj_load_common) {
1102fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
1103fb3fb4f3Stomee "dtj_load_common() has not been called");
1104fb3fb4f3Stomee return (NULL);
1105fb3fb4f3Stomee }
1106fb3fb4f3Stomee
1107fb3fb4f3Stomee *argc = (*jenv)->GetArrayLength(jenv, args);
1108fb3fb4f3Stomee /*
1109fb3fb4f3Stomee * Initialize all string pointers to NULL so that in case of an error
1110fb3fb4f3Stomee * filling in the array, free_argv() will not attempt to free the
1111fb3fb4f3Stomee * unallocated elements. Also NULL-terminate the string array for
1112fb3fb4f3Stomee * functions that expect terminating NULL rather than rely on argc.
1113fb3fb4f3Stomee */
1114fb3fb4f3Stomee argv = uu_zalloc((sizeof (char *)) * (*argc + 1));
1115fb3fb4f3Stomee if (!argv) {
1116fb3fb4f3Stomee dtj_throw_out_of_memory(jenv, "Failed to allocate args array");
1117fb3fb4f3Stomee return (NULL);
1118fb3fb4f3Stomee }
1119fb3fb4f3Stomee
1120fb3fb4f3Stomee for (i = 0; i < *argc; ++i) {
1121fb3fb4f3Stomee jstr = (*jenv)->GetObjectArrayElement(jenv, args, i);
1122fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
1123fb3fb4f3Stomee dtj_free_argv(argv);
1124fb3fb4f3Stomee return (NULL);
1125fb3fb4f3Stomee }
1126fb3fb4f3Stomee str = dtj_GetStringNativeChars(jenv, jstr);
1127fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
1128fb3fb4f3Stomee dtj_free_argv(argv);
1129fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jstr);
1130fb3fb4f3Stomee return (NULL);
1131fb3fb4f3Stomee }
1132fb3fb4f3Stomee argv[i] = malloc(strlen(str) + 1);
1133fb3fb4f3Stomee if (!argv[i]) {
1134fb3fb4f3Stomee dtj_throw_out_of_memory(jenv, "Failed to allocate arg");
1135fb3fb4f3Stomee dtj_free_argv(argv);
1136fb3fb4f3Stomee dtj_ReleaseStringNativeChars(jenv, jstr, str);
1137fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jstr);
1138fb3fb4f3Stomee return (NULL);
1139fb3fb4f3Stomee }
1140fb3fb4f3Stomee (void) strcpy(argv[i], str);
1141fb3fb4f3Stomee dtj_ReleaseStringNativeChars(jenv, jstr, str);
1142fb3fb4f3Stomee (*jenv)->DeleteLocalRef(jenv, jstr);
1143fb3fb4f3Stomee jstr = NULL;
1144fb3fb4f3Stomee }
1145fb3fb4f3Stomee
1146fb3fb4f3Stomee return (argv);
1147fb3fb4f3Stomee }
1148fb3fb4f3Stomee
1149fb3fb4f3Stomee char **
dtj_make_argv(JNIEnv * jenv,jstring command,int * argc)1150fb3fb4f3Stomee dtj_make_argv(JNIEnv *jenv, jstring command, int *argc)
1151fb3fb4f3Stomee {
1152fb3fb4f3Stomee const char *ws = "\f\n\r\t\v ";
1153fb3fb4f3Stomee char **argv = NULL; /* return value */
1154fb3fb4f3Stomee const char *cmd; /* native command string */
1155fb3fb4f3Stomee char *s; /* writable command */
1156fb3fb4f3Stomee char *tok; /* token */
1157fb3fb4f3Stomee int len;
1158fb3fb4f3Stomee
1159fb3fb4f3Stomee if (!g_dtj_load_common) {
1160fb3fb4f3Stomee dtj_throw_illegal_state(jenv,
1161fb3fb4f3Stomee "dtj_load_common() has not been called");
1162fb3fb4f3Stomee return (NULL);
1163fb3fb4f3Stomee }
1164fb3fb4f3Stomee
1165fb3fb4f3Stomee if (!command) {
1166fb3fb4f3Stomee dtj_throw_null_pointer(jenv, "command is null");
1167fb3fb4f3Stomee return (NULL);
1168fb3fb4f3Stomee } else if ((*jenv)->GetStringLength(jenv, command) == 0) {
1169fb3fb4f3Stomee dtj_throw_illegal_argument(jenv, "command is empty");
1170fb3fb4f3Stomee return (NULL);
1171fb3fb4f3Stomee }
1172fb3fb4f3Stomee
1173fb3fb4f3Stomee cmd = dtj_GetStringNativeChars(jenv, command);
1174fb3fb4f3Stomee if ((*jenv)->ExceptionCheck(jenv)) {
1175fb3fb4f3Stomee return (NULL);
1176fb3fb4f3Stomee }
1177fb3fb4f3Stomee len = strlen(cmd);
1178fb3fb4f3Stomee s = malloc(len + 1);
1179fb3fb4f3Stomee if (!s) {
1180fb3fb4f3Stomee dtj_throw_out_of_memory(jenv,
1181fb3fb4f3Stomee "failed to allocate command string");
1182fb3fb4f3Stomee dtj_ReleaseStringNativeChars(jenv, command, cmd);
1183fb3fb4f3Stomee return (NULL);
1184fb3fb4f3Stomee }
1185fb3fb4f3Stomee (void) strcpy(s, cmd);
1186fb3fb4f3Stomee /*
1187fb3fb4f3Stomee * Initialize all string pointers to NULL so that in case of an error
1188fb3fb4f3Stomee * filling in the array, free_argv() will not attempt to free the
1189fb3fb4f3Stomee * unallocated elements. Also NULL-terminate the string array for
1190fb3fb4f3Stomee * functions that expect terminating NULL rather than rely on argc.
1191fb3fb4f3Stomee * Allow for maximum length resulting from single-character tokens
1192fb3fb4f3Stomee * separated by single spaces.
1193fb3fb4f3Stomee */
1194fb3fb4f3Stomee argv = uu_zalloc(sizeof (char *) * (len / 2 + 1));
1195fb3fb4f3Stomee if (!argv) {
1196fb3fb4f3Stomee dtj_throw_out_of_memory(jenv, "failed to allocate args array");
1197fb3fb4f3Stomee free(s);
1198fb3fb4f3Stomee dtj_ReleaseStringNativeChars(jenv, command, cmd);
1199fb3fb4f3Stomee return (NULL);
1200fb3fb4f3Stomee }
1201fb3fb4f3Stomee
1202fb3fb4f3Stomee *argc = 0;
1203fb3fb4f3Stomee for (tok = strtok(s, ws); tok != NULL; tok = strtok(NULL, ws)) {
1204fb3fb4f3Stomee argv[*argc] = malloc(strlen(tok) + 1);
1205fb3fb4f3Stomee if (!argv[*argc]) {
1206fb3fb4f3Stomee dtj_throw_out_of_memory(jenv, "Failed to allocate arg");
1207fb3fb4f3Stomee dtj_free_argv(argv);
1208fb3fb4f3Stomee free(s);
1209fb3fb4f3Stomee dtj_ReleaseStringNativeChars(jenv, command, cmd);
1210fb3fb4f3Stomee return (NULL);
1211fb3fb4f3Stomee }
1212fb3fb4f3Stomee (void) strcpy(argv[(*argc)++], tok);
1213fb3fb4f3Stomee }
1214fb3fb4f3Stomee
1215fb3fb4f3Stomee if (*argc == 0) {
1216fb3fb4f3Stomee dtj_throw_illegal_argument(jenv, "command is blank");
1217fb3fb4f3Stomee dtj_free_argv(argv);
1218fb3fb4f3Stomee free(s);
1219fb3fb4f3Stomee dtj_ReleaseStringNativeChars(jenv, command, cmd);
1220fb3fb4f3Stomee return (NULL);
1221fb3fb4f3Stomee }
1222fb3fb4f3Stomee
1223fb3fb4f3Stomee free(s);
1224fb3fb4f3Stomee dtj_ReleaseStringNativeChars(jenv, command, cmd);
1225fb3fb4f3Stomee return (argv);
1226fb3fb4f3Stomee }
1227fb3fb4f3Stomee
1228fb3fb4f3Stomee void
dtj_free_argv(char ** argv)1229fb3fb4f3Stomee dtj_free_argv(char **argv)
1230fb3fb4f3Stomee {
1231fb3fb4f3Stomee if (argv) {
1232fb3fb4f3Stomee char **s = argv;
1233fb3fb4f3Stomee while (*s) {
1234fb3fb4f3Stomee free((void *)*s);
1235fb3fb4f3Stomee *s++ = NULL;
1236fb3fb4f3Stomee }
1237fb3fb4f3Stomee free((void *)argv);
1238fb3fb4f3Stomee }
1239fb3fb4f3Stomee }
1240fb3fb4f3Stomee
1241fb3fb4f3Stomee
1242fb3fb4f3Stomee /* Wrappers for uu_list_t */
1243fb3fb4f3Stomee
1244fb3fb4f3Stomee int
1245fb3fb4f3Stomee /* ARGSUSED */
dtj_pointer_list_entry_cmp(const void * v1,const void * v2,void * arg)1246fb3fb4f3Stomee dtj_pointer_list_entry_cmp(const void *v1, const void *v2, void *arg)
1247fb3fb4f3Stomee {
1248fb3fb4f3Stomee const dtj_pointer_list_entry_t *p1 = v1;
1249fb3fb4f3Stomee const dtj_pointer_list_entry_t *p2 = v2;
1250fb3fb4f3Stomee
1251fb3fb4f3Stomee /*
1252fb3fb4f3Stomee * It is not valid to compare pointers using the relational operators
1253fb3fb4f3Stomee * unless they point to elements in the same array.
1254fb3fb4f3Stomee */
125580ab886dSwesolows uint64_t x = (uintptr_t)p1->dple_ptr;
125680ab886dSwesolows uint64_t y = (uintptr_t)p2->dple_ptr;
1257fb3fb4f3Stomee int rc;
1258fb3fb4f3Stomee rc = ((x > y) ? 1 : ((x < y) ? -1 : 0));
1259fb3fb4f3Stomee return (rc);
1260fb3fb4f3Stomee }
1261fb3fb4f3Stomee
1262fb3fb4f3Stomee int
1263fb3fb4f3Stomee /* ARGSUSED */
dtj_string_list_entry_cmp(const void * v1,const void * v2,void * arg)1264fb3fb4f3Stomee dtj_string_list_entry_cmp(const void *v1, const void *v2, void *arg)
1265fb3fb4f3Stomee {
1266fb3fb4f3Stomee const dtj_string_list_entry_t *p1 = v1;
1267fb3fb4f3Stomee const dtj_string_list_entry_t *p2 = v2;
1268fb3fb4f3Stomee const char *s1 = p1->dsle_value;
1269fb3fb4f3Stomee const char *s2 = p2->dsle_value;
1270fb3fb4f3Stomee if (s1 == NULL) {
1271fb3fb4f3Stomee return (s2 == NULL ? 0 : -1);
1272fb3fb4f3Stomee }
1273fb3fb4f3Stomee if (s2 == NULL) {
1274fb3fb4f3Stomee return (1);
1275fb3fb4f3Stomee }
1276fb3fb4f3Stomee return (strcmp(s1, s2));
1277fb3fb4f3Stomee }
1278fb3fb4f3Stomee
1279fb3fb4f3Stomee static boolean_t
dtj_check_pointer_pool(void)1280fb3fb4f3Stomee dtj_check_pointer_pool(void)
1281fb3fb4f3Stomee {
1282fb3fb4f3Stomee if (g_pointer_pool == NULL) {
1283fb3fb4f3Stomee g_pointer_pool = uu_list_pool_create("g_pointer_pool",
1284fb3fb4f3Stomee sizeof (dtj_pointer_list_entry_t),
1285fb3fb4f3Stomee offsetof(dtj_pointer_list_entry_t, dple_node),
1286fb3fb4f3Stomee dtj_pointer_list_entry_cmp,
1287fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
1288fb3fb4f3Stomee if (g_pointer_pool == NULL) {
1289fb3fb4f3Stomee return (B_FALSE);
1290fb3fb4f3Stomee }
1291fb3fb4f3Stomee }
1292fb3fb4f3Stomee return (B_TRUE);
1293fb3fb4f3Stomee }
1294fb3fb4f3Stomee
1295fb3fb4f3Stomee uu_list_t *
dtj_pointer_list_create(void)1296fb3fb4f3Stomee dtj_pointer_list_create(void)
1297fb3fb4f3Stomee {
1298fb3fb4f3Stomee uu_list_t *list;
1299fb3fb4f3Stomee
1300fb3fb4f3Stomee if (!dtj_check_pointer_pool()) {
1301fb3fb4f3Stomee return (NULL);
1302fb3fb4f3Stomee }
1303fb3fb4f3Stomee
1304fb3fb4f3Stomee list = uu_list_create(g_pointer_pool, NULL,
1305fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
1306fb3fb4f3Stomee return (list);
1307fb3fb4f3Stomee }
1308fb3fb4f3Stomee
1309fb3fb4f3Stomee dtj_pointer_list_entry_t *
dtj_pointer_list_entry_create(void * p)1310fb3fb4f3Stomee dtj_pointer_list_entry_create(void *p)
1311fb3fb4f3Stomee {
1312fb3fb4f3Stomee dtj_pointer_list_entry_t *e;
1313fb3fb4f3Stomee
1314fb3fb4f3Stomee if (!dtj_check_pointer_pool()) {
1315fb3fb4f3Stomee return (NULL);
1316fb3fb4f3Stomee }
1317fb3fb4f3Stomee
1318fb3fb4f3Stomee e = uu_zalloc(sizeof (dtj_pointer_list_entry_t));
1319fb3fb4f3Stomee if (e) {
1320fb3fb4f3Stomee uu_list_node_init(e, &e->dple_node, g_pointer_pool);
1321fb3fb4f3Stomee e->dple_ptr = p;
1322fb3fb4f3Stomee }
1323fb3fb4f3Stomee return (e);
1324fb3fb4f3Stomee }
1325fb3fb4f3Stomee
1326fb3fb4f3Stomee static boolean_t
dtj_check_string_pool(void)1327fb3fb4f3Stomee dtj_check_string_pool(void)
1328fb3fb4f3Stomee {
1329fb3fb4f3Stomee if (g_string_pool == NULL) {
1330fb3fb4f3Stomee g_string_pool = uu_list_pool_create("g_string_pool",
1331fb3fb4f3Stomee sizeof (dtj_string_list_entry_t),
1332fb3fb4f3Stomee offsetof(dtj_string_list_entry_t, dsle_node),
1333fb3fb4f3Stomee dtj_string_list_entry_cmp,
1334fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_POOL_DEBUG : 0));
1335fb3fb4f3Stomee if (g_string_pool == NULL) {
1336fb3fb4f3Stomee return (B_FALSE);
1337fb3fb4f3Stomee }
1338fb3fb4f3Stomee }
1339fb3fb4f3Stomee return (B_TRUE);
1340fb3fb4f3Stomee }
1341fb3fb4f3Stomee
1342fb3fb4f3Stomee uu_list_t *
dtj_string_list_create(void)1343fb3fb4f3Stomee dtj_string_list_create(void)
1344fb3fb4f3Stomee {
1345fb3fb4f3Stomee uu_list_t *list;
1346fb3fb4f3Stomee
1347fb3fb4f3Stomee if (!dtj_check_string_pool()) {
1348fb3fb4f3Stomee return (NULL);
1349fb3fb4f3Stomee }
1350fb3fb4f3Stomee
1351fb3fb4f3Stomee list = uu_list_create(g_string_pool, NULL,
1352fb3fb4f3Stomee (g_dtj_util_debug ? UU_LIST_DEBUG : 0));
1353fb3fb4f3Stomee return (list);
1354fb3fb4f3Stomee }
1355fb3fb4f3Stomee
1356fb3fb4f3Stomee dtj_string_list_entry_t *
dtj_string_list_entry_create(const char * s)1357fb3fb4f3Stomee dtj_string_list_entry_create(const char *s)
1358fb3fb4f3Stomee {
1359fb3fb4f3Stomee dtj_string_list_entry_t *e;
1360fb3fb4f3Stomee
1361fb3fb4f3Stomee if (!dtj_check_string_pool()) {
1362fb3fb4f3Stomee return (NULL);
1363fb3fb4f3Stomee }
1364fb3fb4f3Stomee
1365fb3fb4f3Stomee e = uu_zalloc(sizeof (dtj_string_list_entry_t));
1366fb3fb4f3Stomee if (e) {
1367fb3fb4f3Stomee uu_list_node_init(e, &e->dsle_node, g_string_pool);
1368fb3fb4f3Stomee if (s) {
1369fb3fb4f3Stomee e->dsle_value = malloc(strlen(s) + 1);
1370fb3fb4f3Stomee if (e->dsle_value) {
1371fb3fb4f3Stomee (void) strcpy(e->dsle_value, s);
1372fb3fb4f3Stomee } else {
1373fb3fb4f3Stomee uu_list_node_fini(e, &e->dsle_node,
1374fb3fb4f3Stomee g_string_pool);
1375fb3fb4f3Stomee uu_free(e);
1376fb3fb4f3Stomee e = NULL;
1377fb3fb4f3Stomee }
1378fb3fb4f3Stomee }
1379fb3fb4f3Stomee }
1380fb3fb4f3Stomee return (e);
1381fb3fb4f3Stomee }
1382fb3fb4f3Stomee
1383fb3fb4f3Stomee void
dtj_pointer_list_entry_destroy(void * v,dtj_value_destroy_f * value_destroy,void * arg)1384fb3fb4f3Stomee dtj_pointer_list_entry_destroy(void *v,
1385fb3fb4f3Stomee dtj_value_destroy_f *value_destroy, void *arg)
1386fb3fb4f3Stomee {
1387fb3fb4f3Stomee if (v) {
1388fb3fb4f3Stomee dtj_pointer_list_entry_t *e = v;
1389fb3fb4f3Stomee if (value_destroy) {
1390fb3fb4f3Stomee value_destroy(e->dple_ptr, arg);
1391fb3fb4f3Stomee }
1392fb3fb4f3Stomee uu_list_node_fini(e, &e->dple_node, g_pointer_pool);
1393fb3fb4f3Stomee e->dple_ptr = NULL;
1394fb3fb4f3Stomee uu_free(v);
1395fb3fb4f3Stomee }
1396fb3fb4f3Stomee }
1397fb3fb4f3Stomee
1398fb3fb4f3Stomee void
1399fb3fb4f3Stomee /* ARGSUSED */
dtj_string_list_entry_destroy(void * v,void * arg)1400fb3fb4f3Stomee dtj_string_list_entry_destroy(void *v, void *arg)
1401fb3fb4f3Stomee {
1402fb3fb4f3Stomee if (v) {
1403fb3fb4f3Stomee dtj_string_list_entry_t *e = v;
1404fb3fb4f3Stomee free(e->dsle_value);
1405fb3fb4f3Stomee uu_list_node_fini(e, &e->dsle_node, g_string_pool);
1406fb3fb4f3Stomee e->dsle_value = NULL;
1407fb3fb4f3Stomee uu_free(v);
1408fb3fb4f3Stomee }
1409fb3fb4f3Stomee }
1410fb3fb4f3Stomee
1411fb3fb4f3Stomee void
dtj_list_clear(uu_list_t * list,dtj_value_destroy_f * value_destroy,void * arg)1412fb3fb4f3Stomee dtj_list_clear(uu_list_t *list, dtj_value_destroy_f *value_destroy,
1413fb3fb4f3Stomee void *arg)
1414fb3fb4f3Stomee {
1415fb3fb4f3Stomee void *cookie; /* needed for uu_list_teardown */
1416fb3fb4f3Stomee void *value;
1417fb3fb4f3Stomee
1418fb3fb4f3Stomee if (!list) {
1419fb3fb4f3Stomee return;
1420fb3fb4f3Stomee }
1421fb3fb4f3Stomee
1422fb3fb4f3Stomee cookie = NULL;
1423fb3fb4f3Stomee if (value_destroy) {
1424fb3fb4f3Stomee while ((value = uu_list_teardown(list, &cookie)) != NULL) {
1425fb3fb4f3Stomee value_destroy(value, arg);
1426fb3fb4f3Stomee }
1427fb3fb4f3Stomee } else {
1428fb3fb4f3Stomee while ((value = uu_list_teardown(list, &cookie)) != NULL) {
1429fb3fb4f3Stomee }
1430fb3fb4f3Stomee }
1431fb3fb4f3Stomee }
1432fb3fb4f3Stomee
1433fb3fb4f3Stomee void
dtj_list_destroy(uu_list_t * list,dtj_value_destroy_f * value_destroy,void * arg)1434fb3fb4f3Stomee dtj_list_destroy(uu_list_t *list,
1435fb3fb4f3Stomee dtj_value_destroy_f *value_destroy, void *arg)
1436fb3fb4f3Stomee {
1437fb3fb4f3Stomee dtj_list_clear(list, value_destroy, arg);
1438fb3fb4f3Stomee uu_list_destroy(list);
1439fb3fb4f3Stomee }
1440fb3fb4f3Stomee
1441fb3fb4f3Stomee void
dtj_pointer_list_clear(uu_list_t * list,dtj_value_destroy_f * value_destroy,void * arg)1442fb3fb4f3Stomee dtj_pointer_list_clear(uu_list_t *list,
1443fb3fb4f3Stomee dtj_value_destroy_f *value_destroy, void *arg)
1444fb3fb4f3Stomee {
1445fb3fb4f3Stomee void *cookie; /* needed for uu_list_teardown */
1446fb3fb4f3Stomee dtj_pointer_list_entry_t *e;
1447fb3fb4f3Stomee
1448fb3fb4f3Stomee if (!list) {
1449fb3fb4f3Stomee return;
1450fb3fb4f3Stomee }
1451fb3fb4f3Stomee
1452fb3fb4f3Stomee cookie = NULL;
1453fb3fb4f3Stomee while ((e = uu_list_teardown(list, &cookie)) != NULL) {
1454fb3fb4f3Stomee dtj_pointer_list_entry_destroy(e, value_destroy, arg);
1455fb3fb4f3Stomee }
1456fb3fb4f3Stomee }
1457fb3fb4f3Stomee
1458fb3fb4f3Stomee void
dtj_pointer_list_destroy(uu_list_t * list,dtj_value_destroy_f * value_destroy,void * arg)1459fb3fb4f3Stomee dtj_pointer_list_destroy(uu_list_t *list,
1460fb3fb4f3Stomee dtj_value_destroy_f *value_destroy, void *arg)
1461fb3fb4f3Stomee {
1462fb3fb4f3Stomee dtj_pointer_list_clear(list, value_destroy, arg);
1463fb3fb4f3Stomee uu_list_destroy(list);
1464fb3fb4f3Stomee }
1465fb3fb4f3Stomee
1466fb3fb4f3Stomee void
dtj_string_list_clear(uu_list_t * list)1467fb3fb4f3Stomee dtj_string_list_clear(uu_list_t *list)
1468fb3fb4f3Stomee {
1469fb3fb4f3Stomee dtj_list_clear(list, dtj_string_list_entry_destroy, NULL);
1470fb3fb4f3Stomee }
1471fb3fb4f3Stomee
1472fb3fb4f3Stomee void
dtj_string_list_destroy(uu_list_t * list)1473fb3fb4f3Stomee dtj_string_list_destroy(uu_list_t *list)
1474fb3fb4f3Stomee {
1475fb3fb4f3Stomee dtj_list_destroy(list, dtj_string_list_entry_destroy, NULL);
1476fb3fb4f3Stomee }
1477fb3fb4f3Stomee
1478fb3fb4f3Stomee boolean_t
dtj_list_empty(uu_list_t * list)1479fb3fb4f3Stomee dtj_list_empty(uu_list_t *list)
1480fb3fb4f3Stomee {
1481fb3fb4f3Stomee return (uu_list_numnodes(list) == 0);
1482fb3fb4f3Stomee }
1483fb3fb4f3Stomee
1484fb3fb4f3Stomee boolean_t
dtj_list_add(uu_list_t * list,void * value)1485fb3fb4f3Stomee dtj_list_add(uu_list_t *list, void *value)
1486fb3fb4f3Stomee {
1487fb3fb4f3Stomee return (uu_list_insert_before(list, NULL, value) == 0);
1488fb3fb4f3Stomee }
1489fb3fb4f3Stomee
1490fb3fb4f3Stomee boolean_t
dtj_pointer_list_add(uu_list_t * list,void * p)1491fb3fb4f3Stomee dtj_pointer_list_add(uu_list_t *list, void *p)
1492fb3fb4f3Stomee {
1493fb3fb4f3Stomee dtj_pointer_list_entry_t *e = dtj_pointer_list_entry_create(p);
1494fb3fb4f3Stomee if (!e) {
1495fb3fb4f3Stomee return (B_FALSE);
1496fb3fb4f3Stomee }
1497fb3fb4f3Stomee return (dtj_list_add(list, e));
1498fb3fb4f3Stomee }
1499fb3fb4f3Stomee
1500fb3fb4f3Stomee void *
dtj_pointer_list_walk_next(uu_list_walk_t * itr)1501fb3fb4f3Stomee dtj_pointer_list_walk_next(uu_list_walk_t *itr)
1502fb3fb4f3Stomee {
1503fb3fb4f3Stomee dtj_pointer_list_entry_t *e = uu_list_walk_next(itr);
1504fb3fb4f3Stomee if (!e) {
1505fb3fb4f3Stomee return (DTJ_INVALID_PTR);
1506fb3fb4f3Stomee }
1507fb3fb4f3Stomee return (e->dple_ptr);
1508fb3fb4f3Stomee }
1509fb3fb4f3Stomee
1510fb3fb4f3Stomee void *
dtj_pointer_list_first(uu_list_t * list)1511fb3fb4f3Stomee dtj_pointer_list_first(uu_list_t *list)
1512fb3fb4f3Stomee {
1513fb3fb4f3Stomee dtj_pointer_list_entry_t *e = uu_list_first(list);
1514fb3fb4f3Stomee if (!e) {
1515fb3fb4f3Stomee /* NULL is a valid value; use -1 for invalid */
1516fb3fb4f3Stomee return (DTJ_INVALID_PTR);
1517fb3fb4f3Stomee }
1518fb3fb4f3Stomee return (e->dple_ptr);
1519fb3fb4f3Stomee }
1520fb3fb4f3Stomee
1521fb3fb4f3Stomee void *
dtj_pointer_list_last(uu_list_t * list)1522fb3fb4f3Stomee dtj_pointer_list_last(uu_list_t *list)
1523fb3fb4f3Stomee {
1524fb3fb4f3Stomee dtj_pointer_list_entry_t *e = uu_list_last(list);
1525fb3fb4f3Stomee if (!e) {
1526fb3fb4f3Stomee /* NULL is a valid value; use -1 for invalid */
1527fb3fb4f3Stomee return (DTJ_INVALID_PTR);
1528fb3fb4f3Stomee }
1529fb3fb4f3Stomee return (e->dple_ptr);
1530fb3fb4f3Stomee }
1531fb3fb4f3Stomee
1532fb3fb4f3Stomee boolean_t
dtj_string_list_add(uu_list_t * list,const char * s)1533fb3fb4f3Stomee dtj_string_list_add(uu_list_t *list, const char *s)
1534fb3fb4f3Stomee {
1535fb3fb4f3Stomee dtj_string_list_entry_t *e = dtj_string_list_entry_create(s);
1536fb3fb4f3Stomee if (!e) {
1537fb3fb4f3Stomee return (B_FALSE);
1538fb3fb4f3Stomee }
1539fb3fb4f3Stomee return (dtj_list_add(list, e));
1540fb3fb4f3Stomee }
1541fb3fb4f3Stomee
1542fb3fb4f3Stomee const char *
dtj_string_list_walk_next(uu_list_walk_t * itr)1543fb3fb4f3Stomee dtj_string_list_walk_next(uu_list_walk_t *itr)
1544fb3fb4f3Stomee {
1545fb3fb4f3Stomee dtj_string_list_entry_t *e = uu_list_walk_next(itr);
1546fb3fb4f3Stomee if (!e) {
1547fb3fb4f3Stomee return (DTJ_INVALID_STR);
1548fb3fb4f3Stomee }
1549fb3fb4f3Stomee return (e->dsle_value);
1550fb3fb4f3Stomee }
1551fb3fb4f3Stomee
1552fb3fb4f3Stomee const char *
dtj_string_list_first(uu_list_t * list)1553fb3fb4f3Stomee dtj_string_list_first(uu_list_t *list)
1554fb3fb4f3Stomee {
1555fb3fb4f3Stomee dtj_string_list_entry_t *e = uu_list_first(list);
1556fb3fb4f3Stomee if (!e) {
1557fb3fb4f3Stomee /* NULL is a valid string value; use -1 for invalid */
1558fb3fb4f3Stomee return (DTJ_INVALID_STR);
1559fb3fb4f3Stomee }
1560fb3fb4f3Stomee return (e->dsle_value);
1561fb3fb4f3Stomee }
1562fb3fb4f3Stomee
1563fb3fb4f3Stomee const char *
dtj_string_list_last(uu_list_t * list)1564fb3fb4f3Stomee dtj_string_list_last(uu_list_t *list)
1565fb3fb4f3Stomee {
1566fb3fb4f3Stomee dtj_string_list_entry_t *e = uu_list_last(list);
1567fb3fb4f3Stomee if (!e) {
1568fb3fb4f3Stomee /* NULL is a valid string value; use -1 for invalid */
1569fb3fb4f3Stomee return (DTJ_INVALID_STR);
1570fb3fb4f3Stomee }
1571fb3fb4f3Stomee return (e->dsle_value);
1572fb3fb4f3Stomee }
1573