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 #ifndef _DTJ_UTIL_H 28fb3fb4f3Stomee #define _DTJ_UTIL_H 29fb3fb4f3Stomee 30fb3fb4f3Stomee #pragma ident "%Z%%M% %I% %E% SMI" 31fb3fb4f3Stomee 32fb3fb4f3Stomee #include <jni.h> 33fb3fb4f3Stomee #include <libuutil.h> 34fb3fb4f3Stomee 35fb3fb4f3Stomee #ifdef __cplusplus 36fb3fb4f3Stomee extern "C" { 37fb3fb4f3Stomee #endif 38fb3fb4f3Stomee 39fb3fb4f3Stomee /* 40fb3fb4f3Stomee * dtj_util.h separates functionality that is generally useful from 41fb3fb4f3Stomee * that which is specific to the Java DTrace API. If moved to a separate 42fb3fb4f3Stomee * library, this functionality could be shared by other JNI wrappers. 43fb3fb4f3Stomee */ 44fb3fb4f3Stomee 45fb3fb4f3Stomee #ifdef JNI_VERSION_1_4 46fb3fb4f3Stomee #define JNI_VERSION JNI_VERSION_1_4 47fb3fb4f3Stomee #else 48fb3fb4f3Stomee #define JNI_VERSION JNI_VERSION_1_2 49fb3fb4f3Stomee #endif 50fb3fb4f3Stomee 51fb3fb4f3Stomee #define CONSTRUCTOR "<init>" 52fb3fb4f3Stomee #define DTJ_MSG_SIZE 1024 53fb3fb4f3Stomee #define DTJ_INVALID_PTR ((void *)-1) 54fb3fb4f3Stomee #define DTJ_INVALID_STR ((const char *)-1) 55fb3fb4f3Stomee 56fb3fb4f3Stomee #define WRAP_EXCEPTION(JENV) dtj_wrap_exception((JENV), __FILE__, __LINE__) 57fb3fb4f3Stomee 58fb3fb4f3Stomee extern boolean_t g_dtj_util_debug; 59fb3fb4f3Stomee 60fb3fb4f3Stomee typedef enum dtj_status { 61fb3fb4f3Stomee DTJ_OK = JNI_OK, 62fb3fb4f3Stomee DTJ_ERR = JNI_ERR 63fb3fb4f3Stomee } dtj_status_t; 64fb3fb4f3Stomee 65fb3fb4f3Stomee typedef enum dtj_type { 66fb3fb4f3Stomee JCLASS, 67fb3fb4f3Stomee JMETHOD, 68fb3fb4f3Stomee JMETHOD_STATIC, 69fb3fb4f3Stomee JFIELD, 70fb3fb4f3Stomee JFIELD_STATIC, 71fb3fb4f3Stomee DTJ_TYPE_END = -1 72fb3fb4f3Stomee } dtj_type_t; 73fb3fb4f3Stomee 74fb3fb4f3Stomee /* 75fb3fb4f3Stomee * Convenient description format for java classes, methods, and fields. The 76fb3fb4f3Stomee * java_class_t, java_method_t, and java_field_t structures derived from these 77fb3fb4f3Stomee * descriptions are used to create a table of usable JNI jclass, jmethodID, and 78fb3fb4f3Stomee * jfieldID instances. 79fb3fb4f3Stomee */ 80fb3fb4f3Stomee typedef struct dtj_table_entry { 81fb3fb4f3Stomee dtj_type_t djte_type; /* JNI type */ 82fb3fb4f3Stomee void *djte_addr; /* jclass, jmethodID, or jfieldID address */ 83fb3fb4f3Stomee char *djte_name; /* symbol name declared in Java */ 84fb3fb4f3Stomee char *djte_desc; /* JNI descriptor (string format) */ 85fb3fb4f3Stomee } dtj_table_entry_t; 86fb3fb4f3Stomee 87fb3fb4f3Stomee typedef struct dtj_java_class { 88fb3fb4f3Stomee jclass *djc_ptr; /* address in user-defined structure */ 89fb3fb4f3Stomee char *djc_name; /* fully qualified '/' delimited class name */ 90fb3fb4f3Stomee uu_list_t *djc_methods; /* element type (java_method_t *) */ 91fb3fb4f3Stomee uu_list_t *djc_fields; /* element type (java_field_t *) */ 92fb3fb4f3Stomee uu_list_node_t djc_node; 93fb3fb4f3Stomee } dtj_java_class_t; 94fb3fb4f3Stomee 95fb3fb4f3Stomee typedef struct dtj_java_method { 96fb3fb4f3Stomee jmethodID *djm_ptr; /* address in user-defined structure */ 97fb3fb4f3Stomee char *djm_name; /* method name in java source file */ 98fb3fb4f3Stomee char *djm_signature; /* javap -s method signature string */ 99fb3fb4f3Stomee boolean_t djm_static; /* flag indicating static qualifier */ 100fb3fb4f3Stomee uu_list_node_t djm_node; 101fb3fb4f3Stomee } dtj_java_method_t; 102fb3fb4f3Stomee 103fb3fb4f3Stomee typedef struct dtj_java_field { 104fb3fb4f3Stomee jfieldID *djf_ptr; /* address in user-defined structure */ 105fb3fb4f3Stomee char *djf_name; /* field name in java source file */ 106fb3fb4f3Stomee char *djf_type; /* javap -s field type string */ 107fb3fb4f3Stomee boolean_t djf_static; /* flag indicating static qualifier */ 108fb3fb4f3Stomee uu_list_node_t djf_node; 109fb3fb4f3Stomee } dtj_java_field_t; 110fb3fb4f3Stomee 111fb3fb4f3Stomee /* 112fb3fb4f3Stomee * Table of cached jclass, jmethodID, and jfieldID values usable across multiple 113fb3fb4f3Stomee * native method calls and multiple threads. 114fb3fb4f3Stomee * 115fb3fb4f3Stomee * Suffix conventions: 116fb3fb4f3Stomee * jc java class 117fb3fb4f3Stomee * jm java method 118fb3fb4f3Stomee * jsm java static method 119fb3fb4f3Stomee * jf java field 120fb3fb4f3Stomee * jsf java static field 121fb3fb4f3Stomee */ 122fb3fb4f3Stomee 123fb3fb4f3Stomee /* NativeException */ 124fb3fb4f3Stomee extern jclass g_nx_jc; 125fb3fb4f3Stomee extern jmethodID g_nxinit_jm; 126fb3fb4f3Stomee 127fb3fb4f3Stomee /* java.io.Serializable */ 128fb3fb4f3Stomee extern jclass g_serial_jc; 129fb3fb4f3Stomee 130fb3fb4f3Stomee /* java.lang.Number */ 131fb3fb4f3Stomee extern jclass g_number_jc; 132fb3fb4f3Stomee extern jmethodID g_shortval_jm; 133fb3fb4f3Stomee extern jmethodID g_intval_jm; 134fb3fb4f3Stomee extern jmethodID g_longval_jm; 135fb3fb4f3Stomee 136fb3fb4f3Stomee /* java.lang.Byte */ 137fb3fb4f3Stomee extern jclass g_byte_jc; 138fb3fb4f3Stomee extern jmethodID g_byteinit_jm; 139fb3fb4f3Stomee 140fb3fb4f3Stomee /* java.lang.Character */ 141fb3fb4f3Stomee extern jclass g_char_jc; 142fb3fb4f3Stomee extern jmethodID g_charinit_jm; 143fb3fb4f3Stomee extern jmethodID g_charval_jm; 144fb3fb4f3Stomee 145fb3fb4f3Stomee /* java.lang.Short */ 146fb3fb4f3Stomee extern jclass g_short_jc; 147fb3fb4f3Stomee extern jmethodID g_shortinit_jm; 148fb3fb4f3Stomee 149fb3fb4f3Stomee /* java.lang.Integer */ 150fb3fb4f3Stomee extern jclass g_int_jc; 151fb3fb4f3Stomee extern jmethodID g_intinit_jm; 152fb3fb4f3Stomee 153fb3fb4f3Stomee /* java.lang.Long */ 154fb3fb4f3Stomee extern jclass g_long_jc; 155fb3fb4f3Stomee extern jmethodID g_longinit_jm; 156fb3fb4f3Stomee 157*e77b06d2Stomee /* java.math.BigInteger */ 158*e77b06d2Stomee extern jclass g_bigint_jc; 159*e77b06d2Stomee extern jmethodID g_bigint_val_jsm; 160*e77b06d2Stomee extern jmethodID g_bigint_div_jm; 161*e77b06d2Stomee extern jmethodID g_bigint_shl_jm; 162*e77b06d2Stomee extern jmethodID g_bigint_or_jm; 163*e77b06d2Stomee extern jmethodID g_bigint_setbit_jm; 164*e77b06d2Stomee 165fb3fb4f3Stomee /* java.lang.String */ 166fb3fb4f3Stomee extern jclass g_string_jc; 167fb3fb4f3Stomee extern jmethodID g_strinit_bytes_jm; 168fb3fb4f3Stomee extern jmethodID g_strbytes_jm; 169fb3fb4f3Stomee extern jmethodID g_trim_jm; 170fb3fb4f3Stomee 171fb3fb4f3Stomee /* java.lang.StringBuffer */ 172fb3fb4f3Stomee extern jclass g_buf_jc; 173fb3fb4f3Stomee extern jmethodID g_bufinit_jm; 174fb3fb4f3Stomee extern jmethodID g_buf_append_char_jm; 175fb3fb4f3Stomee extern jmethodID g_buf_append_int_jm; 176fb3fb4f3Stomee extern jmethodID g_buf_append_long_jm; 177fb3fb4f3Stomee extern jmethodID g_buf_append_str_jm; 178fb3fb4f3Stomee extern jmethodID g_buf_append_obj_jm; 179fb3fb4f3Stomee extern jmethodID g_buflen_jm; 180fb3fb4f3Stomee extern jmethodID g_bufsetlen_jm; 181fb3fb4f3Stomee 182fb3fb4f3Stomee /* java.lang.Object */ 183fb3fb4f3Stomee extern jclass g_object_jc; 184fb3fb4f3Stomee extern jmethodID g_tostring_jm; 185fb3fb4f3Stomee extern jmethodID g_equals_jm; 186fb3fb4f3Stomee 187fb3fb4f3Stomee /* java.lang.Enum */ 188fb3fb4f3Stomee extern jclass g_enum_jc; 189fb3fb4f3Stomee extern jmethodID g_enumname_jm; 190fb3fb4f3Stomee 191fb3fb4f3Stomee /* List */ 192fb3fb4f3Stomee extern jclass g_list_jc; 193fb3fb4f3Stomee extern jmethodID g_listclear_jm; 194fb3fb4f3Stomee extern jmethodID g_listadd_jm; 195fb3fb4f3Stomee extern jmethodID g_listget_jm; 196fb3fb4f3Stomee extern jmethodID g_listsize_jm; 197fb3fb4f3Stomee 198fb3fb4f3Stomee /* 199fb3fb4f3Stomee * Populates the common java class references and associated method and field 200fb3fb4f3Stomee * IDs declared in this file (above) using the dtj_cache_jni_classes() method. 201fb3fb4f3Stomee */ 202fb3fb4f3Stomee extern dtj_status_t dtj_load_common(JNIEnv *); 203fb3fb4f3Stomee 204fb3fb4f3Stomee /* 205fb3fb4f3Stomee * Populates the user-declared java class references and associated method and 206fb3fb4f3Stomee * field IDs described in the given table. Because the class references are 207fb3fb4f3Stomee * created as global JNI references, the method and field IDs remain valid 208fb3fb4f3Stomee * across multiple native method calls and across multiple threads. 209fb3fb4f3Stomee * 210fb3fb4f3Stomee * This function assumes that the given table of java class, method, and field 211fb3fb4f3Stomee * descriptions is terminated by an entry with DTJ_TYPE_END, and that the 212fb3fb4f3Stomee * method and field descriptions immediately follow the description of their 213fb3fb4f3Stomee * containing class. 214fb3fb4f3Stomee * 215fb3fb4f3Stomee * Throws NoClassDefFoundError, NoSuchMethodError, or NoSuchFieldError if any 216fb3fb4f3Stomee * dtj_table_entry_t in common_jni_table.c is incorrect. 217fb3fb4f3Stomee */ 218fb3fb4f3Stomee extern dtj_status_t dtj_cache_jni_classes(JNIEnv *, const dtj_table_entry_t *); 219fb3fb4f3Stomee 220fb3fb4f3Stomee /* Common utilities */ 221fb3fb4f3Stomee 222fb3fb4f3Stomee /* 223fb3fb4f3Stomee * The following functions each create a pending Java Error or Exception: 224fb3fb4f3Stomee * 225fb3fb4f3Stomee * OutOfMemoryError 226fb3fb4f3Stomee * NullPointerException 227fb3fb4f3Stomee * IllegalArgumentException 228fb3fb4f3Stomee * IllegalStateException 229fb3fb4f3Stomee * NoSuchElementException 230fb3fb4f3Stomee * ClassCastException 231fb3fb4f3Stomee * AssertionError 232*e77b06d2Stomee * org.opensolaris.os.dtrace.ResourceLimitException 233fb3fb4f3Stomee * 234fb3fb4f3Stomee * Control should be returned to Java immediately afterwards. 235fb3fb4f3Stomee */ 236fb3fb4f3Stomee extern void dtj_throw_out_of_memory(JNIEnv *, const char *, ...); 237fb3fb4f3Stomee extern void dtj_throw_null_pointer(JNIEnv *, const char *, ...); 238fb3fb4f3Stomee extern void dtj_throw_illegal_argument(JNIEnv *, const char *, ...); 239fb3fb4f3Stomee extern void dtj_throw_illegal_state(JNIEnv *, const char *, ...); 240fb3fb4f3Stomee extern void dtj_throw_no_such_element(JNIEnv *, const char *, ...); 241fb3fb4f3Stomee extern void dtj_throw_class_cast(JNIEnv *, const char *, ...); 242fb3fb4f3Stomee extern void dtj_throw_assertion(JNIEnv *, const char *, ...); 243fb3fb4f3Stomee extern void dtj_throw_resource_limit(JNIEnv *, const char *, ...); 244fb3fb4f3Stomee 245fb3fb4f3Stomee /* 246fb3fb4f3Stomee * Attaches native filename and line number to the currently pending java 247fb3fb4f3Stomee * exception, since that information is not present in the exception stack 248fb3fb4f3Stomee * trace. 249fb3fb4f3Stomee */ 250fb3fb4f3Stomee extern void dtj_wrap_exception(JNIEnv *, const char *, int); 251fb3fb4f3Stomee 252fb3fb4f3Stomee /* 253fb3fb4f3Stomee * Calls the toString() method of the given object and prints the value to 254fb3fb4f3Stomee * stdout (useful for debugging). If an exception is thrown in this function, 255fb3fb4f3Stomee * it is described on stdout and cleared. It's guaranteed that no exception is 256fb3fb4f3Stomee * pending when this function returns. 257fb3fb4f3Stomee */ 258fb3fb4f3Stomee extern void dtj_print_object(JNIEnv *jenv, jobject obj); 259fb3fb4f3Stomee 260fb3fb4f3Stomee /* 261*e77b06d2Stomee * Gets a java.math.BigInteger representing a 64-bit unsigned integer. 262*e77b06d2Stomee */ 263*e77b06d2Stomee extern jobject dtj_uint64(JNIEnv *jenv, uint64_t); 264*e77b06d2Stomee 265*e77b06d2Stomee /* 266*e77b06d2Stomee * Gets a java.math.BigInteger representing a 128-bit integer given as 64 high 267*e77b06d2Stomee * bits (1st arg) and 64 low bits (2nd arg). 268*e77b06d2Stomee */ 269*e77b06d2Stomee extern jobject dtj_int128(JNIEnv *jenv, uint64_t, uint64_t); 270*e77b06d2Stomee 271*e77b06d2Stomee /* 272fb3fb4f3Stomee * Gets a formatted String (local reference) from a format and a variable 273fb3fb4f3Stomee * argument list of placeholder values. Returns NULL if OutOfMemoryError is 274fb3fb4f3Stomee * thrown. 275fb3fb4f3Stomee */ 276fb3fb4f3Stomee extern jstring dtj_format_string(JNIEnv *jenv, const char *fmt, ...); 277fb3fb4f3Stomee 278fb3fb4f3Stomee /* 279fb3fb4f3Stomee * Internationalization support. These functions taken (not verbatim) from 280fb3fb4f3Stomee * Section 8.2 of The Java Native Interface by Sheng Liang, The Java Series. 281fb3fb4f3Stomee * Use these functions for locale-specific strings such as file names. 282fb3fb4f3Stomee */ 283fb3fb4f3Stomee extern jstring dtj_NewStringNative(JNIEnv *jenv, const char *str); 284fb3fb4f3Stomee extern char *dtj_GetStringNativeChars(JNIEnv *jenv, jstring jstr); 285fb3fb4f3Stomee extern void dtj_ReleaseStringNativeChars(JNIEnv *jenv, jstring jstr, 286fb3fb4f3Stomee const char *str); 287fb3fb4f3Stomee 288fb3fb4f3Stomee /* 289fb3fb4f3Stomee * Converts the args array of main(String[] args) in Java into a native 290fb3fb4f3Stomee * dynamically allocated array of strings. The returned array must be 291fb3fb4f3Stomee * deallocated by calling free_argv(). A java exception is pending if this 292fb3fb4f3Stomee * function returns NULL (in that case, any allocations made up to the point of 293fb3fb4f3Stomee * failure in get_argv() are automatically freed). 294fb3fb4f3Stomee * 295fb3fb4f3Stomee * Returns a NULL-terminated array that works with functions that expect a 296fb3fb4f3Stomee * terminating NULL rather than relying on an element count. The argc parameter 297fb3fb4f3Stomee * is also overwritten with the number of returned array elements (not including 298fb3fb4f3Stomee * the terminating NULL). 299fb3fb4f3Stomee */ 300fb3fb4f3Stomee extern char **dtj_get_argv(JNIEnv *jenv, jobjectArray args, int *argc); 301fb3fb4f3Stomee /* 302fb3fb4f3Stomee * Tokenizes a command string to create a native dynamically allocated array of 303fb3fb4f3Stomee * strings. The first element of the returned array is assumed to be the name 304fb3fb4f3Stomee * of the command, and subsequent elements are arguments to that command. 305fb3fb4f3Stomee * Otherwise behaves exactly like get_argv() above, including requiring a 306fb3fb4f3Stomee * subsequent call to free_argv() on the returned array. 307fb3fb4f3Stomee * Throws NullPointerException if cmd is NULL. 308fb3fb4f3Stomee * Throws IllegalArgumentException if cmd is empty. 309fb3fb4f3Stomee */ 310fb3fb4f3Stomee extern char **dtj_make_argv(JNIEnv *jenv, jstring cmd, int *argc); 311fb3fb4f3Stomee extern void dtj_free_argv(char **argv); 312fb3fb4f3Stomee 313fb3fb4f3Stomee 314fb3fb4f3Stomee /* Wrappers for uu_list_t */ 315fb3fb4f3Stomee 316fb3fb4f3Stomee /* 317fb3fb4f3Stomee * List element destructor. 318fb3fb4f3Stomee * params: node pointer, user arg (may be NULL) 319fb3fb4f3Stomee */ 320fb3fb4f3Stomee typedef void dtj_value_destroy_f(void *, void *); 321fb3fb4f3Stomee 322fb3fb4f3Stomee /* 323fb3fb4f3Stomee * uu_list_t generic entry type for pointers compared by pointer value, similar 324fb3fb4f3Stomee * to Java's default Object.equals() implementation (referenced objects are 325fb3fb4f3Stomee * equal only if they have the same address in memory). Used with 326fb3fb4f3Stomee * pointer_list_entry_cmp. 327fb3fb4f3Stomee */ 328fb3fb4f3Stomee typedef struct dtj_pointer_list_entry { 329fb3fb4f3Stomee void *dple_ptr; 330fb3fb4f3Stomee uu_list_node_t dple_node; 331fb3fb4f3Stomee } dtj_pointer_list_entry_t; 332fb3fb4f3Stomee 333fb3fb4f3Stomee typedef struct dtj_string_list_entry { 334fb3fb4f3Stomee char *dsle_value; 335fb3fb4f3Stomee uu_list_node_t dsle_node; 336fb3fb4f3Stomee } dtj_string_list_entry_t; 337fb3fb4f3Stomee 338fb3fb4f3Stomee /* Comparison functions, uu_compare_fn_t signature */ 339fb3fb4f3Stomee extern int dtj_pointer_list_entry_cmp(const void *, const void *, void *); 340fb3fb4f3Stomee extern int dtj_string_list_entry_cmp(const void *, const void *, void *); 341fb3fb4f3Stomee 342fb3fb4f3Stomee /* Constructors */ 343fb3fb4f3Stomee extern uu_list_t *dtj_pointer_list_create(void); 344fb3fb4f3Stomee extern dtj_pointer_list_entry_t *dtj_pointer_list_entry_create(void *); 345fb3fb4f3Stomee extern uu_list_t *dtj_string_list_create(void); 346fb3fb4f3Stomee extern dtj_string_list_entry_t *dtj_string_list_entry_create(const char *); 347fb3fb4f3Stomee 348fb3fb4f3Stomee /* Destructors */ 349fb3fb4f3Stomee extern void dtj_pointer_list_entry_destroy(void *, dtj_value_destroy_f *, 350fb3fb4f3Stomee void *); 351fb3fb4f3Stomee extern void dtj_string_list_entry_destroy(void *, void *); 352fb3fb4f3Stomee /* 353fb3fb4f3Stomee * Convenience function destroys a uu_list_t and its values. 354fb3fb4f3Stomee * 355fb3fb4f3Stomee * param list: list to be destroyed, call is a no-op if list is NULL 356fb3fb4f3Stomee * param value_destroy: optional destructor; if non-NULL, it is called on each 357fb3fb4f3Stomee * list value 358fb3fb4f3Stomee * param arg: user argument to the optional destructor 359fb3fb4f3Stomee */ 360fb3fb4f3Stomee extern void dtj_list_destroy(uu_list_t *, dtj_value_destroy_f *, void *); 361fb3fb4f3Stomee extern void dtj_pointer_list_destroy(uu_list_t *, dtj_value_destroy_f *, 362fb3fb4f3Stomee void *); 363fb3fb4f3Stomee extern void dtj_string_list_destroy(uu_list_t *); 364fb3fb4f3Stomee 365fb3fb4f3Stomee /* 366fb3fb4f3Stomee * Convenience functions clear a uu_list_t without destroying it. Destroys all 367fb3fb4f3Stomee * list elements and leaves the list empty. The *_list_destroy() functions 368fb3fb4f3Stomee * implicitly clear the list before destroying it. 369fb3fb4f3Stomee */ 370fb3fb4f3Stomee extern void dtj_list_clear(uu_list_t *, dtj_value_destroy_f *, void *); 371fb3fb4f3Stomee extern void dtj_pointer_list_clear(uu_list_t *, dtj_value_destroy_f *, 372fb3fb4f3Stomee void *); 373fb3fb4f3Stomee extern void dtj_string_list_clear(uu_list_t *); 374fb3fb4f3Stomee 375fb3fb4f3Stomee extern boolean_t dtj_list_empty(uu_list_t *); 376fb3fb4f3Stomee /* Return B_TRUE if successful, B_FALSE otherwise */ 377fb3fb4f3Stomee extern boolean_t dtj_list_add(uu_list_t *, void *); 378fb3fb4f3Stomee extern boolean_t dtj_pointer_list_add(uu_list_t *, void *); 379fb3fb4f3Stomee extern boolean_t dtj_string_list_add(uu_list_t *, const char *); 380fb3fb4f3Stomee /* Return INVALID_PTR if list is empty (NULL is a valid list element) */ 381fb3fb4f3Stomee extern void * dtj_pointer_list_first(uu_list_t *); 382fb3fb4f3Stomee extern void * dtj_pointer_list_last(uu_list_t *); 383fb3fb4f3Stomee /* Return INVALID_STR if list is empty (NULL is a valid list element) */ 384fb3fb4f3Stomee extern const char *dtj_string_list_first(uu_list_t *); 385fb3fb4f3Stomee extern const char *dtj_string_list_last(uu_list_t *); 386fb3fb4f3Stomee /* Return INVALID_PTR at end of list (NULL is a valid list element) */ 387fb3fb4f3Stomee extern void *dtj_pointer_list_walk_next(uu_list_walk_t *); 388fb3fb4f3Stomee /* Return INVALID_STR at end of list (NULL is a valid list element) */ 389fb3fb4f3Stomee extern const char *dtj_string_list_walk_next(uu_list_walk_t *); 390fb3fb4f3Stomee 391fb3fb4f3Stomee #ifdef __cplusplus 392fb3fb4f3Stomee } 393fb3fb4f3Stomee #endif 394fb3fb4f3Stomee 395fb3fb4f3Stomee #endif /* _DTJ_UTIL_H */ 396