xref: /aosp_15_r20/external/oj-libjdwp/src/share/back/transport.c (revision e82f7db8c62aed3c168547abe4f9f4aeceaebfc7)
1*e82f7db8SAndroid Build Coastguard Worker /*
2*e82f7db8SAndroid Build Coastguard Worker  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3*e82f7db8SAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*e82f7db8SAndroid Build Coastguard Worker  *
5*e82f7db8SAndroid Build Coastguard Worker  * This code is free software; you can redistribute it and/or modify it
6*e82f7db8SAndroid Build Coastguard Worker  * under the terms of the GNU General Public License version 2 only, as
7*e82f7db8SAndroid Build Coastguard Worker  * published by the Free Software Foundation.  Oracle designates this
8*e82f7db8SAndroid Build Coastguard Worker  * particular file as subject to the "Classpath" exception as provided
9*e82f7db8SAndroid Build Coastguard Worker  * by Oracle in the LICENSE file that accompanied this code.
10*e82f7db8SAndroid Build Coastguard Worker  *
11*e82f7db8SAndroid Build Coastguard Worker  * This code is distributed in the hope that it will be useful, but WITHOUT
12*e82f7db8SAndroid Build Coastguard Worker  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e82f7db8SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*e82f7db8SAndroid Build Coastguard Worker  * version 2 for more details (a copy is included in the LICENSE file that
15*e82f7db8SAndroid Build Coastguard Worker  * accompanied this code).
16*e82f7db8SAndroid Build Coastguard Worker  *
17*e82f7db8SAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License version
18*e82f7db8SAndroid Build Coastguard Worker  * 2 along with this work; if not, write to the Free Software Foundation,
19*e82f7db8SAndroid Build Coastguard Worker  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20*e82f7db8SAndroid Build Coastguard Worker  *
21*e82f7db8SAndroid Build Coastguard Worker  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22*e82f7db8SAndroid Build Coastguard Worker  * or visit www.oracle.com if you need additional information or have any
23*e82f7db8SAndroid Build Coastguard Worker  * questions.
24*e82f7db8SAndroid Build Coastguard Worker  */
25*e82f7db8SAndroid Build Coastguard Worker 
26*e82f7db8SAndroid Build Coastguard Worker #include "util.h"
27*e82f7db8SAndroid Build Coastguard Worker #include "transport.h"
28*e82f7db8SAndroid Build Coastguard Worker #include "debugLoop.h"
29*e82f7db8SAndroid Build Coastguard Worker #include "sys.h"
30*e82f7db8SAndroid Build Coastguard Worker 
31*e82f7db8SAndroid Build Coastguard Worker static jdwpTransportEnv *transport;
32*e82f7db8SAndroid Build Coastguard Worker static jrawMonitorID listenerLock;
33*e82f7db8SAndroid Build Coastguard Worker static jrawMonitorID sendLock;
34*e82f7db8SAndroid Build Coastguard Worker 
35*e82f7db8SAndroid Build Coastguard Worker /*
36*e82f7db8SAndroid Build Coastguard Worker  * data structure used for passing transport info from thread to thread
37*e82f7db8SAndroid Build Coastguard Worker  */
38*e82f7db8SAndroid Build Coastguard Worker typedef struct TransportInfo {
39*e82f7db8SAndroid Build Coastguard Worker     char *name;
40*e82f7db8SAndroid Build Coastguard Worker     jdwpTransportEnv *transport;
41*e82f7db8SAndroid Build Coastguard Worker     char *address;
42*e82f7db8SAndroid Build Coastguard Worker     long timeout;
43*e82f7db8SAndroid Build Coastguard Worker } TransportInfo;
44*e82f7db8SAndroid Build Coastguard Worker 
45*e82f7db8SAndroid Build Coastguard Worker static struct jdwpTransportCallback callback = {jvmtiAllocate, jvmtiDeallocate};
46*e82f7db8SAndroid Build Coastguard Worker 
47*e82f7db8SAndroid Build Coastguard Worker /*
48*e82f7db8SAndroid Build Coastguard Worker  * Print the last transport error
49*e82f7db8SAndroid Build Coastguard Worker  */
50*e82f7db8SAndroid Build Coastguard Worker static void
printLastError(jdwpTransportEnv * t,jdwpTransportError err)51*e82f7db8SAndroid Build Coastguard Worker printLastError(jdwpTransportEnv *t, jdwpTransportError err)
52*e82f7db8SAndroid Build Coastguard Worker {
53*e82f7db8SAndroid Build Coastguard Worker     char  *msg;
54*e82f7db8SAndroid Build Coastguard Worker     jbyte *utf8msg;
55*e82f7db8SAndroid Build Coastguard Worker     jdwpTransportError rv;
56*e82f7db8SAndroid Build Coastguard Worker 
57*e82f7db8SAndroid Build Coastguard Worker     msg     = NULL;
58*e82f7db8SAndroid Build Coastguard Worker     utf8msg = NULL;
59*e82f7db8SAndroid Build Coastguard Worker     rv = (*t)->GetLastError(t, &msg); /* This is a platform encoded string */
60*e82f7db8SAndroid Build Coastguard Worker     if ( msg != NULL ) {
61*e82f7db8SAndroid Build Coastguard Worker         int len;
62*e82f7db8SAndroid Build Coastguard Worker         int maxlen;
63*e82f7db8SAndroid Build Coastguard Worker 
64*e82f7db8SAndroid Build Coastguard Worker         /* Convert this string to UTF8 */
65*e82f7db8SAndroid Build Coastguard Worker         len = (int)strlen(msg);
66*e82f7db8SAndroid Build Coastguard Worker         maxlen = len+len/2+2; /* Should allow for plenty of room */
67*e82f7db8SAndroid Build Coastguard Worker         utf8msg = (jbyte*)jvmtiAllocate(maxlen+1);
68*e82f7db8SAndroid Build Coastguard Worker         (void)(gdata->npt->utf8FromPlatform)(gdata->npt->utf,
69*e82f7db8SAndroid Build Coastguard Worker             msg, len, utf8msg, maxlen);
70*e82f7db8SAndroid Build Coastguard Worker         utf8msg[maxlen] = 0;
71*e82f7db8SAndroid Build Coastguard Worker     }
72*e82f7db8SAndroid Build Coastguard Worker     if (rv == JDWPTRANSPORT_ERROR_NONE) {
73*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("transport error %d: %s",err, utf8msg));
74*e82f7db8SAndroid Build Coastguard Worker     } else if ( msg!=NULL ) {
75*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("transport error %d: %s",err, utf8msg));
76*e82f7db8SAndroid Build Coastguard Worker     } else {
77*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("transport error %d: %s",err, "UNKNOWN"));
78*e82f7db8SAndroid Build Coastguard Worker     }
79*e82f7db8SAndroid Build Coastguard Worker     jvmtiDeallocate(msg);
80*e82f7db8SAndroid Build Coastguard Worker     jvmtiDeallocate(utf8msg);
81*e82f7db8SAndroid Build Coastguard Worker }
82*e82f7db8SAndroid Build Coastguard Worker 
83*e82f7db8SAndroid Build Coastguard Worker /* Find OnLoad symbol */
84*e82f7db8SAndroid Build Coastguard Worker static jdwpTransport_OnLoad_t
findTransportOnLoad(void * handle)85*e82f7db8SAndroid Build Coastguard Worker findTransportOnLoad(void *handle)
86*e82f7db8SAndroid Build Coastguard Worker {
87*e82f7db8SAndroid Build Coastguard Worker     jdwpTransport_OnLoad_t onLoad;
88*e82f7db8SAndroid Build Coastguard Worker 
89*e82f7db8SAndroid Build Coastguard Worker     onLoad = (jdwpTransport_OnLoad_t)NULL;
90*e82f7db8SAndroid Build Coastguard Worker     if (handle == NULL) {
91*e82f7db8SAndroid Build Coastguard Worker         return onLoad;
92*e82f7db8SAndroid Build Coastguard Worker     }
93*e82f7db8SAndroid Build Coastguard Worker     onLoad = (jdwpTransport_OnLoad_t)
94*e82f7db8SAndroid Build Coastguard Worker                  dbgsysFindLibraryEntry(handle, "jdwpTransport_OnLoad");
95*e82f7db8SAndroid Build Coastguard Worker     return onLoad;
96*e82f7db8SAndroid Build Coastguard Worker }
97*e82f7db8SAndroid Build Coastguard Worker 
98*e82f7db8SAndroid Build Coastguard Worker /* Load transport library (directory=="" means do system search) */
99*e82f7db8SAndroid Build Coastguard Worker static void *
loadTransportLibrary(const char * libdir,const char * name)100*e82f7db8SAndroid Build Coastguard Worker loadTransportLibrary(const char *libdir, const char *name)
101*e82f7db8SAndroid Build Coastguard Worker {
102*e82f7db8SAndroid Build Coastguard Worker     void *handle;
103*e82f7db8SAndroid Build Coastguard Worker     char libname[MAXPATHLEN+2];
104*e82f7db8SAndroid Build Coastguard Worker     char buf[MAXPATHLEN*2+100];
105*e82f7db8SAndroid Build Coastguard Worker     const char *plibdir;
106*e82f7db8SAndroid Build Coastguard Worker 
107*e82f7db8SAndroid Build Coastguard Worker     /* Convert libdir from UTF-8 to platform encoding */
108*e82f7db8SAndroid Build Coastguard Worker     plibdir = NULL;
109*e82f7db8SAndroid Build Coastguard Worker     if ( libdir != NULL ) {
110*e82f7db8SAndroid Build Coastguard Worker         int  len;
111*e82f7db8SAndroid Build Coastguard Worker 
112*e82f7db8SAndroid Build Coastguard Worker         len = (int)strlen(libdir);
113*e82f7db8SAndroid Build Coastguard Worker         (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
114*e82f7db8SAndroid Build Coastguard Worker             (jbyte*)libdir, len, buf, (int)sizeof(buf));
115*e82f7db8SAndroid Build Coastguard Worker         plibdir = buf;
116*e82f7db8SAndroid Build Coastguard Worker     }
117*e82f7db8SAndroid Build Coastguard Worker 
118*e82f7db8SAndroid Build Coastguard Worker     /* Construct library name (simple name or full path) */
119*e82f7db8SAndroid Build Coastguard Worker     dbgsysBuildLibName(libname, sizeof(libname), plibdir, name);
120*e82f7db8SAndroid Build Coastguard Worker     if (strlen(libname) == 0) {
121*e82f7db8SAndroid Build Coastguard Worker         return NULL;
122*e82f7db8SAndroid Build Coastguard Worker     }
123*e82f7db8SAndroid Build Coastguard Worker 
124*e82f7db8SAndroid Build Coastguard Worker     /* dlopen (unix) / LoadLibrary (windows) the transport library */
125*e82f7db8SAndroid Build Coastguard Worker     handle = dbgsysLoadLibrary(libname, buf, sizeof(buf));
126*e82f7db8SAndroid Build Coastguard Worker     return handle;
127*e82f7db8SAndroid Build Coastguard Worker }
128*e82f7db8SAndroid Build Coastguard Worker 
129*e82f7db8SAndroid Build Coastguard Worker /*
130*e82f7db8SAndroid Build Coastguard Worker  * loadTransport() is adapted from loadJVMHelperLib() in
131*e82f7db8SAndroid Build Coastguard Worker  * JDK 1.2 javai.c v1.61
132*e82f7db8SAndroid Build Coastguard Worker  */
133*e82f7db8SAndroid Build Coastguard Worker static jdwpError
loadTransport(const char * name,jdwpTransportEnv ** transportPtr)134*e82f7db8SAndroid Build Coastguard Worker loadTransport(const char *name, jdwpTransportEnv **transportPtr)
135*e82f7db8SAndroid Build Coastguard Worker {
136*e82f7db8SAndroid Build Coastguard Worker     JNIEnv                 *env;
137*e82f7db8SAndroid Build Coastguard Worker     jdwpTransport_OnLoad_t  onLoad;
138*e82f7db8SAndroid Build Coastguard Worker     void                   *handle;
139*e82f7db8SAndroid Build Coastguard Worker     const char             *libdir;
140*e82f7db8SAndroid Build Coastguard Worker 
141*e82f7db8SAndroid Build Coastguard Worker     /* Make sure library name is not empty */
142*e82f7db8SAndroid Build Coastguard Worker     if (name == NULL) {
143*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("library name is empty"));
144*e82f7db8SAndroid Build Coastguard Worker         return JDWP_ERROR(TRANSPORT_LOAD);
145*e82f7db8SAndroid Build Coastguard Worker     }
146*e82f7db8SAndroid Build Coastguard Worker 
147*e82f7db8SAndroid Build Coastguard Worker     /* First, look in sun.boot.library.path. This should find the standard
148*e82f7db8SAndroid Build Coastguard Worker      *  dt_socket and dt_shmem transport libraries, or any library
149*e82f7db8SAndroid Build Coastguard Worker      *  that was delivered with the J2SE.
150*e82f7db8SAndroid Build Coastguard Worker      *  Note: Since 6819213 fixed, Java property sun.boot.library.path can
151*e82f7db8SAndroid Build Coastguard Worker      *  contain multiple paths. Dll_dir is the first entry and
152*e82f7db8SAndroid Build Coastguard Worker      *  -Dsun.boot.library.path entries are appended.
153*e82f7db8SAndroid Build Coastguard Worker      */
154*e82f7db8SAndroid Build Coastguard Worker     libdir = gdata->property_sun_boot_library_path;
155*e82f7db8SAndroid Build Coastguard Worker     if (libdir == NULL) {
156*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("Java property sun.boot.library.path is not set"));
157*e82f7db8SAndroid Build Coastguard Worker         return JDWP_ERROR(TRANSPORT_LOAD);
158*e82f7db8SAndroid Build Coastguard Worker     }
159*e82f7db8SAndroid Build Coastguard Worker     handle = loadTransportLibrary(libdir, name);
160*e82f7db8SAndroid Build Coastguard Worker     if (handle == NULL) {
161*e82f7db8SAndroid Build Coastguard Worker         /* Second, look along the path used by the native dlopen/LoadLibrary
162*e82f7db8SAndroid Build Coastguard Worker          *  functions. This should effectively try and load the simple
163*e82f7db8SAndroid Build Coastguard Worker          *  library name, which will cause the default system library
164*e82f7db8SAndroid Build Coastguard Worker          *  search technique to happen.
165*e82f7db8SAndroid Build Coastguard Worker          *  We should only reach here if the transport library wasn't found
166*e82f7db8SAndroid Build Coastguard Worker          *  in the J2SE directory, e.g. it's a custom transport library
167*e82f7db8SAndroid Build Coastguard Worker          *  not installed in the J2SE like dt_socket and dt_shmem is.
168*e82f7db8SAndroid Build Coastguard Worker          *
169*e82f7db8SAndroid Build Coastguard Worker          *  Note: Why not use java.library.path? Several reasons:
170*e82f7db8SAndroid Build Coastguard Worker          *        a) This matches existing agentlib search
171*e82f7db8SAndroid Build Coastguard Worker          *        b) These are technically not JNI libraries
172*e82f7db8SAndroid Build Coastguard Worker          */
173*e82f7db8SAndroid Build Coastguard Worker         handle = loadTransportLibrary("", name);
174*e82f7db8SAndroid Build Coastguard Worker     }
175*e82f7db8SAndroid Build Coastguard Worker 
176*e82f7db8SAndroid Build Coastguard Worker     /* See if a library was found with this name */
177*e82f7db8SAndroid Build Coastguard Worker     if (handle == NULL) {
178*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("transport library not found: %s", name));
179*e82f7db8SAndroid Build Coastguard Worker         return JDWP_ERROR(TRANSPORT_LOAD);
180*e82f7db8SAndroid Build Coastguard Worker     }
181*e82f7db8SAndroid Build Coastguard Worker 
182*e82f7db8SAndroid Build Coastguard Worker     /* Find the onLoad address */
183*e82f7db8SAndroid Build Coastguard Worker     onLoad = findTransportOnLoad(handle);
184*e82f7db8SAndroid Build Coastguard Worker     if (onLoad == NULL) {
185*e82f7db8SAndroid Build Coastguard Worker         ERROR_MESSAGE(("transport library missing onLoad entry: %s", name));
186*e82f7db8SAndroid Build Coastguard Worker         return JDWP_ERROR(TRANSPORT_LOAD);
187*e82f7db8SAndroid Build Coastguard Worker     }
188*e82f7db8SAndroid Build Coastguard Worker 
189*e82f7db8SAndroid Build Coastguard Worker     /* Get transport interface */
190*e82f7db8SAndroid Build Coastguard Worker     env = getEnv();
191*e82f7db8SAndroid Build Coastguard Worker     if ( env != NULL ) {
192*e82f7db8SAndroid Build Coastguard Worker         jdwpTransportEnv *t;
193*e82f7db8SAndroid Build Coastguard Worker         JavaVM           *jvm;
194*e82f7db8SAndroid Build Coastguard Worker         jint              ver;
195*e82f7db8SAndroid Build Coastguard Worker 
196*e82f7db8SAndroid Build Coastguard Worker         JNI_FUNC_PTR(env,GetJavaVM)(env, &jvm);
197*e82f7db8SAndroid Build Coastguard Worker         ver = (*onLoad)(jvm, &callback, JDWPTRANSPORT_VERSION_1_0, &t);
198*e82f7db8SAndroid Build Coastguard Worker         if (ver != JNI_OK) {
199*e82f7db8SAndroid Build Coastguard Worker             switch (ver) {
200*e82f7db8SAndroid Build Coastguard Worker                 case JNI_ENOMEM :
201*e82f7db8SAndroid Build Coastguard Worker                     ERROR_MESSAGE(("insufficient memory to complete initialization"));
202*e82f7db8SAndroid Build Coastguard Worker                     break;
203*e82f7db8SAndroid Build Coastguard Worker 
204*e82f7db8SAndroid Build Coastguard Worker                 case JNI_EVERSION :
205*e82f7db8SAndroid Build Coastguard Worker                     ERROR_MESSAGE(("transport doesn't recognize version %x",
206*e82f7db8SAndroid Build Coastguard Worker                         JDWPTRANSPORT_VERSION_1_0));
207*e82f7db8SAndroid Build Coastguard Worker                     break;
208*e82f7db8SAndroid Build Coastguard Worker 
209*e82f7db8SAndroid Build Coastguard Worker                 case JNI_EEXIST :
210*e82f7db8SAndroid Build Coastguard Worker                     ERROR_MESSAGE(("transport doesn't support multiple environments"));
211*e82f7db8SAndroid Build Coastguard Worker                     break;
212*e82f7db8SAndroid Build Coastguard Worker 
213*e82f7db8SAndroid Build Coastguard Worker                 default:
214*e82f7db8SAndroid Build Coastguard Worker                     ERROR_MESSAGE(("unrecognized error %d from transport", ver));
215*e82f7db8SAndroid Build Coastguard Worker                     break;
216*e82f7db8SAndroid Build Coastguard Worker             }
217*e82f7db8SAndroid Build Coastguard Worker 
218*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(TRANSPORT_INIT);
219*e82f7db8SAndroid Build Coastguard Worker         }
220*e82f7db8SAndroid Build Coastguard Worker         *transportPtr = t;
221*e82f7db8SAndroid Build Coastguard Worker     } else {
222*e82f7db8SAndroid Build Coastguard Worker         return JDWP_ERROR(TRANSPORT_LOAD);
223*e82f7db8SAndroid Build Coastguard Worker     }
224*e82f7db8SAndroid Build Coastguard Worker 
225*e82f7db8SAndroid Build Coastguard Worker     return JDWP_ERROR(NONE);
226*e82f7db8SAndroid Build Coastguard Worker }
227*e82f7db8SAndroid Build Coastguard Worker 
228*e82f7db8SAndroid Build Coastguard Worker static void
connectionInitiated(jdwpTransportEnv * t)229*e82f7db8SAndroid Build Coastguard Worker connectionInitiated(jdwpTransportEnv *t)
230*e82f7db8SAndroid Build Coastguard Worker {
231*e82f7db8SAndroid Build Coastguard Worker     jint isValid = JNI_FALSE;
232*e82f7db8SAndroid Build Coastguard Worker 
233*e82f7db8SAndroid Build Coastguard Worker     debugMonitorEnter(listenerLock);
234*e82f7db8SAndroid Build Coastguard Worker 
235*e82f7db8SAndroid Build Coastguard Worker     /*
236*e82f7db8SAndroid Build Coastguard Worker      * Don't allow a connection until initialization is complete
237*e82f7db8SAndroid Build Coastguard Worker      */
238*e82f7db8SAndroid Build Coastguard Worker     debugInit_waitInitComplete();
239*e82f7db8SAndroid Build Coastguard Worker 
240*e82f7db8SAndroid Build Coastguard Worker     /* Are we the first transport to get a connection? */
241*e82f7db8SAndroid Build Coastguard Worker 
242*e82f7db8SAndroid Build Coastguard Worker     if (transport == NULL) {
243*e82f7db8SAndroid Build Coastguard Worker         transport = t;
244*e82f7db8SAndroid Build Coastguard Worker         isValid = JNI_TRUE;
245*e82f7db8SAndroid Build Coastguard Worker     } else {
246*e82f7db8SAndroid Build Coastguard Worker         if (transport == t) {
247*e82f7db8SAndroid Build Coastguard Worker             /* connected with the same transport as before */
248*e82f7db8SAndroid Build Coastguard Worker             isValid = JNI_TRUE;
249*e82f7db8SAndroid Build Coastguard Worker         } else {
250*e82f7db8SAndroid Build Coastguard Worker             /*
251*e82f7db8SAndroid Build Coastguard Worker              * Another transport got a connection - multiple transports
252*e82f7db8SAndroid Build Coastguard Worker              * not fully supported yet so shouldn't get here.
253*e82f7db8SAndroid Build Coastguard Worker              */
254*e82f7db8SAndroid Build Coastguard Worker             (*t)->Close(t);
255*e82f7db8SAndroid Build Coastguard Worker             JDI_ASSERT(JNI_FALSE);
256*e82f7db8SAndroid Build Coastguard Worker         }
257*e82f7db8SAndroid Build Coastguard Worker     }
258*e82f7db8SAndroid Build Coastguard Worker 
259*e82f7db8SAndroid Build Coastguard Worker     if (isValid) {
260*e82f7db8SAndroid Build Coastguard Worker         debugMonitorNotifyAll(listenerLock);
261*e82f7db8SAndroid Build Coastguard Worker     }
262*e82f7db8SAndroid Build Coastguard Worker 
263*e82f7db8SAndroid Build Coastguard Worker     debugMonitorExit(listenerLock);
264*e82f7db8SAndroid Build Coastguard Worker 
265*e82f7db8SAndroid Build Coastguard Worker     if (isValid) {
266*e82f7db8SAndroid Build Coastguard Worker         debugLoop_run();
267*e82f7db8SAndroid Build Coastguard Worker     }
268*e82f7db8SAndroid Build Coastguard Worker 
269*e82f7db8SAndroid Build Coastguard Worker }
270*e82f7db8SAndroid Build Coastguard Worker 
271*e82f7db8SAndroid Build Coastguard Worker /*
272*e82f7db8SAndroid Build Coastguard Worker  * Set the transport property (sun.jdwp.listenerAddress) to the
273*e82f7db8SAndroid Build Coastguard Worker  * specified value.
274*e82f7db8SAndroid Build Coastguard Worker  */
275*e82f7db8SAndroid Build Coastguard Worker static void
setTransportProperty(JNIEnv * env,char * value)276*e82f7db8SAndroid Build Coastguard Worker setTransportProperty(JNIEnv* env, char* value) {
277*e82f7db8SAndroid Build Coastguard Worker     char* prop_value = (value == NULL) ? "" : value;
278*e82f7db8SAndroid Build Coastguard Worker     setAgentPropertyValue(env, "sun.jdwp.listenerAddress", prop_value);
279*e82f7db8SAndroid Build Coastguard Worker }
280*e82f7db8SAndroid Build Coastguard Worker 
281*e82f7db8SAndroid Build Coastguard Worker void
transport_waitForConnection(void)282*e82f7db8SAndroid Build Coastguard Worker transport_waitForConnection(void)
283*e82f7db8SAndroid Build Coastguard Worker {
284*e82f7db8SAndroid Build Coastguard Worker     /*
285*e82f7db8SAndroid Build Coastguard Worker      * If the VM is suspended on debugger initialization, we wait
286*e82f7db8SAndroid Build Coastguard Worker      * for a connection before continuing. This ensures that all
287*e82f7db8SAndroid Build Coastguard Worker      * events are delivered to the debugger. (We might as well do this
288*e82f7db8SAndroid Build Coastguard Worker      * this since the VM won't continue until a remote debugger attaches
289*e82f7db8SAndroid Build Coastguard Worker      * and resumes it.) If not suspending on initialization, we must
290*e82f7db8SAndroid Build Coastguard Worker      * just drop any packets (i.e. events) so that the VM can continue
291*e82f7db8SAndroid Build Coastguard Worker      * to run. The debugger may not attach until much later.
292*e82f7db8SAndroid Build Coastguard Worker      */
293*e82f7db8SAndroid Build Coastguard Worker     if (debugInit_suspendOnInit()) {
294*e82f7db8SAndroid Build Coastguard Worker         debugMonitorEnter(listenerLock);
295*e82f7db8SAndroid Build Coastguard Worker         while (transport == NULL) {
296*e82f7db8SAndroid Build Coastguard Worker             debugMonitorWait(listenerLock);
297*e82f7db8SAndroid Build Coastguard Worker         }
298*e82f7db8SAndroid Build Coastguard Worker         debugMonitorExit(listenerLock);
299*e82f7db8SAndroid Build Coastguard Worker     }
300*e82f7db8SAndroid Build Coastguard Worker }
301*e82f7db8SAndroid Build Coastguard Worker 
302*e82f7db8SAndroid Build Coastguard Worker static void JNICALL
acceptThread(jvmtiEnv * jvmti_env,JNIEnv * jni_env,void * arg)303*e82f7db8SAndroid Build Coastguard Worker acceptThread(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg)
304*e82f7db8SAndroid Build Coastguard Worker {
305*e82f7db8SAndroid Build Coastguard Worker     TransportInfo *info;
306*e82f7db8SAndroid Build Coastguard Worker     jdwpTransportEnv *t;
307*e82f7db8SAndroid Build Coastguard Worker     jdwpTransportError rc;
308*e82f7db8SAndroid Build Coastguard Worker 
309*e82f7db8SAndroid Build Coastguard Worker     LOG_MISC(("Begin accept thread"));
310*e82f7db8SAndroid Build Coastguard Worker 
311*e82f7db8SAndroid Build Coastguard Worker     info = (TransportInfo*)(void*)arg;
312*e82f7db8SAndroid Build Coastguard Worker     t = info->transport;
313*e82f7db8SAndroid Build Coastguard Worker 
314*e82f7db8SAndroid Build Coastguard Worker     rc = (*t)->Accept(t, info->timeout, 0);
315*e82f7db8SAndroid Build Coastguard Worker 
316*e82f7db8SAndroid Build Coastguard Worker     /* System property no longer needed */
317*e82f7db8SAndroid Build Coastguard Worker     setTransportProperty(jni_env, NULL);
318*e82f7db8SAndroid Build Coastguard Worker 
319*e82f7db8SAndroid Build Coastguard Worker     if (rc != JDWPTRANSPORT_ERROR_NONE) {
320*e82f7db8SAndroid Build Coastguard Worker         /*
321*e82f7db8SAndroid Build Coastguard Worker          * If accept fails it probably means a timeout, or another fatal error
322*e82f7db8SAndroid Build Coastguard Worker          * We thus exit the VM after stopping the listener.
323*e82f7db8SAndroid Build Coastguard Worker          */
324*e82f7db8SAndroid Build Coastguard Worker         printLastError(t, rc);
325*e82f7db8SAndroid Build Coastguard Worker         (*t)->StopListening(t);
326*e82f7db8SAndroid Build Coastguard Worker         EXIT_ERROR(JVMTI_ERROR_NONE, "could not connect, timeout or fatal error");
327*e82f7db8SAndroid Build Coastguard Worker     } else {
328*e82f7db8SAndroid Build Coastguard Worker         (*t)->StopListening(t);
329*e82f7db8SAndroid Build Coastguard Worker         connectionInitiated(t);
330*e82f7db8SAndroid Build Coastguard Worker     }
331*e82f7db8SAndroid Build Coastguard Worker 
332*e82f7db8SAndroid Build Coastguard Worker     LOG_MISC(("End accept thread"));
333*e82f7db8SAndroid Build Coastguard Worker }
334*e82f7db8SAndroid Build Coastguard Worker 
335*e82f7db8SAndroid Build Coastguard Worker static void JNICALL
attachThread(jvmtiEnv * jvmti_env,JNIEnv * jni_env,void * arg)336*e82f7db8SAndroid Build Coastguard Worker attachThread(jvmtiEnv* jvmti_env, JNIEnv* jni_env, void* arg)
337*e82f7db8SAndroid Build Coastguard Worker {
338*e82f7db8SAndroid Build Coastguard Worker     LOG_MISC(("Begin attach thread"));
339*e82f7db8SAndroid Build Coastguard Worker     connectionInitiated((jdwpTransportEnv *)(void*)arg);
340*e82f7db8SAndroid Build Coastguard Worker     LOG_MISC(("End attach thread"));
341*e82f7db8SAndroid Build Coastguard Worker }
342*e82f7db8SAndroid Build Coastguard Worker 
343*e82f7db8SAndroid Build Coastguard Worker void
transport_initialize(void)344*e82f7db8SAndroid Build Coastguard Worker transport_initialize(void)
345*e82f7db8SAndroid Build Coastguard Worker {
346*e82f7db8SAndroid Build Coastguard Worker     transport = NULL;
347*e82f7db8SAndroid Build Coastguard Worker     listenerLock = debugMonitorCreate("JDWP Transport Listener Monitor");
348*e82f7db8SAndroid Build Coastguard Worker     sendLock = debugMonitorCreate("JDWP Transport Send Monitor");
349*e82f7db8SAndroid Build Coastguard Worker }
350*e82f7db8SAndroid Build Coastguard Worker 
351*e82f7db8SAndroid Build Coastguard Worker void
transport_reset(void)352*e82f7db8SAndroid Build Coastguard Worker transport_reset(void)
353*e82f7db8SAndroid Build Coastguard Worker {
354*e82f7db8SAndroid Build Coastguard Worker     /*
355*e82f7db8SAndroid Build Coastguard Worker      * Reset the transport by closing any listener (will silently fail
356*e82f7db8SAndroid Build Coastguard Worker      * with JDWPTRANSPORT_ERROR_ILLEGAL_STATE if not listening), and
357*e82f7db8SAndroid Build Coastguard Worker      * closing any connection (will also fail silently if not
358*e82f7db8SAndroid Build Coastguard Worker      * connected).
359*e82f7db8SAndroid Build Coastguard Worker      *
360*e82f7db8SAndroid Build Coastguard Worker      * Note: There's an assumption here that we don't yet support
361*e82f7db8SAndroid Build Coastguard Worker      * multiple transports. When we do then we need a clear transition
362*e82f7db8SAndroid Build Coastguard Worker      * from the current transport to the new transport.
363*e82f7db8SAndroid Build Coastguard Worker      */
364*e82f7db8SAndroid Build Coastguard Worker     if (transport != NULL) {
365*e82f7db8SAndroid Build Coastguard Worker         setTransportProperty(getEnv(), NULL);
366*e82f7db8SAndroid Build Coastguard Worker         (*transport)->StopListening(transport);
367*e82f7db8SAndroid Build Coastguard Worker         (*transport)->Close(transport);
368*e82f7db8SAndroid Build Coastguard Worker     }
369*e82f7db8SAndroid Build Coastguard Worker }
370*e82f7db8SAndroid Build Coastguard Worker 
371*e82f7db8SAndroid Build Coastguard Worker static jdwpError
launch(char * command,char * name,char * address)372*e82f7db8SAndroid Build Coastguard Worker launch(char *command, char *name, char *address)
373*e82f7db8SAndroid Build Coastguard Worker {
374*e82f7db8SAndroid Build Coastguard Worker     jint rc;
375*e82f7db8SAndroid Build Coastguard Worker     char *buf;
376*e82f7db8SAndroid Build Coastguard Worker     char *commandLine;
377*e82f7db8SAndroid Build Coastguard Worker     int  len;
378*e82f7db8SAndroid Build Coastguard Worker 
379*e82f7db8SAndroid Build Coastguard Worker     /* Construct complete command line (all in UTF-8) */
380*e82f7db8SAndroid Build Coastguard Worker     commandLine = jvmtiAllocate((int)strlen(command) +
381*e82f7db8SAndroid Build Coastguard Worker                                  (int)strlen(name) +
382*e82f7db8SAndroid Build Coastguard Worker                                  (int)strlen(address) + 3);
383*e82f7db8SAndroid Build Coastguard Worker     if (commandLine == NULL) {
384*e82f7db8SAndroid Build Coastguard Worker         return JDWP_ERROR(OUT_OF_MEMORY);
385*e82f7db8SAndroid Build Coastguard Worker     }
386*e82f7db8SAndroid Build Coastguard Worker     (void)strcpy(commandLine, command);
387*e82f7db8SAndroid Build Coastguard Worker     (void)strcat(commandLine, " ");
388*e82f7db8SAndroid Build Coastguard Worker     (void)strcat(commandLine, name);
389*e82f7db8SAndroid Build Coastguard Worker     (void)strcat(commandLine, " ");
390*e82f7db8SAndroid Build Coastguard Worker     (void)strcat(commandLine, address);
391*e82f7db8SAndroid Build Coastguard Worker 
392*e82f7db8SAndroid Build Coastguard Worker     /* Convert commandLine from UTF-8 to platform encoding */
393*e82f7db8SAndroid Build Coastguard Worker     len = (int)strlen(commandLine);
394*e82f7db8SAndroid Build Coastguard Worker     buf = jvmtiAllocate(len*3+3);
395*e82f7db8SAndroid Build Coastguard Worker     (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
396*e82f7db8SAndroid Build Coastguard Worker         (jbyte*)commandLine, len, buf, len*3+3);
397*e82f7db8SAndroid Build Coastguard Worker 
398*e82f7db8SAndroid Build Coastguard Worker     /* Exec commandLine */
399*e82f7db8SAndroid Build Coastguard Worker     rc = dbgsysExec(buf);
400*e82f7db8SAndroid Build Coastguard Worker 
401*e82f7db8SAndroid Build Coastguard Worker     /* Free up buffers */
402*e82f7db8SAndroid Build Coastguard Worker     jvmtiDeallocate(buf);
403*e82f7db8SAndroid Build Coastguard Worker     jvmtiDeallocate(commandLine);
404*e82f7db8SAndroid Build Coastguard Worker 
405*e82f7db8SAndroid Build Coastguard Worker     /* And non-zero exit status means we had an error */
406*e82f7db8SAndroid Build Coastguard Worker     if (rc != SYS_OK) {
407*e82f7db8SAndroid Build Coastguard Worker         return JDWP_ERROR(TRANSPORT_INIT);
408*e82f7db8SAndroid Build Coastguard Worker     }
409*e82f7db8SAndroid Build Coastguard Worker     return JDWP_ERROR(NONE);
410*e82f7db8SAndroid Build Coastguard Worker }
411*e82f7db8SAndroid Build Coastguard Worker 
412*e82f7db8SAndroid Build Coastguard Worker jdwpError
transport_startTransport(jboolean isServer,char * name,char * address,long timeout)413*e82f7db8SAndroid Build Coastguard Worker transport_startTransport(jboolean isServer, char *name, char *address,
414*e82f7db8SAndroid Build Coastguard Worker                          long timeout)
415*e82f7db8SAndroid Build Coastguard Worker {
416*e82f7db8SAndroid Build Coastguard Worker     jvmtiStartFunction func;
417*e82f7db8SAndroid Build Coastguard Worker     jdwpTransportEnv *trans;
418*e82f7db8SAndroid Build Coastguard Worker     char threadName[MAXPATHLEN + 100];
419*e82f7db8SAndroid Build Coastguard Worker     jint err;
420*e82f7db8SAndroid Build Coastguard Worker     jdwpError serror;
421*e82f7db8SAndroid Build Coastguard Worker 
422*e82f7db8SAndroid Build Coastguard Worker     /*
423*e82f7db8SAndroid Build Coastguard Worker      * If the transport is already loaded then use it
424*e82f7db8SAndroid Build Coastguard Worker      * Note: We're assuming here that we don't support multiple
425*e82f7db8SAndroid Build Coastguard Worker      * transports - when we do then we need to handle the case
426*e82f7db8SAndroid Build Coastguard Worker      * where the transport library only supports a single environment.
427*e82f7db8SAndroid Build Coastguard Worker      * That probably means we have a bag a transport environments
428*e82f7db8SAndroid Build Coastguard Worker      * to correspond to the transports bag.
429*e82f7db8SAndroid Build Coastguard Worker      */
430*e82f7db8SAndroid Build Coastguard Worker     if (transport != NULL) {
431*e82f7db8SAndroid Build Coastguard Worker         trans = transport;
432*e82f7db8SAndroid Build Coastguard Worker     } else {
433*e82f7db8SAndroid Build Coastguard Worker         serror = loadTransport(name, &trans);
434*e82f7db8SAndroid Build Coastguard Worker         if (serror != JDWP_ERROR(NONE)) {
435*e82f7db8SAndroid Build Coastguard Worker             return serror;
436*e82f7db8SAndroid Build Coastguard Worker         }
437*e82f7db8SAndroid Build Coastguard Worker     }
438*e82f7db8SAndroid Build Coastguard Worker 
439*e82f7db8SAndroid Build Coastguard Worker     if (isServer) {
440*e82f7db8SAndroid Build Coastguard Worker 
441*e82f7db8SAndroid Build Coastguard Worker         char *retAddress;
442*e82f7db8SAndroid Build Coastguard Worker         char *launchCommand;
443*e82f7db8SAndroid Build Coastguard Worker         TransportInfo *info;
444*e82f7db8SAndroid Build Coastguard Worker         jvmtiError error;
445*e82f7db8SAndroid Build Coastguard Worker         int len;
446*e82f7db8SAndroid Build Coastguard Worker         char* prop_value;
447*e82f7db8SAndroid Build Coastguard Worker 
448*e82f7db8SAndroid Build Coastguard Worker         info = jvmtiAllocate(sizeof(*info));
449*e82f7db8SAndroid Build Coastguard Worker         if (info == NULL) {
450*e82f7db8SAndroid Build Coastguard Worker             return JDWP_ERROR(OUT_OF_MEMORY);
451*e82f7db8SAndroid Build Coastguard Worker         }
452*e82f7db8SAndroid Build Coastguard Worker         info->name = jvmtiAllocate((int)strlen(name)+1);
453*e82f7db8SAndroid Build Coastguard Worker         (void)strcpy(info->name, name);
454*e82f7db8SAndroid Build Coastguard Worker         info->address = NULL;
455*e82f7db8SAndroid Build Coastguard Worker         info->timeout = timeout;
456*e82f7db8SAndroid Build Coastguard Worker         if (info->name == NULL) {
457*e82f7db8SAndroid Build Coastguard Worker             serror = JDWP_ERROR(OUT_OF_MEMORY);
458*e82f7db8SAndroid Build Coastguard Worker             goto handleError;
459*e82f7db8SAndroid Build Coastguard Worker         }
460*e82f7db8SAndroid Build Coastguard Worker         if (address != NULL) {
461*e82f7db8SAndroid Build Coastguard Worker             info->address = jvmtiAllocate((int)strlen(address)+1);
462*e82f7db8SAndroid Build Coastguard Worker             (void)strcpy(info->address, address);
463*e82f7db8SAndroid Build Coastguard Worker             if (info->address == NULL) {
464*e82f7db8SAndroid Build Coastguard Worker                 serror = JDWP_ERROR(OUT_OF_MEMORY);
465*e82f7db8SAndroid Build Coastguard Worker                 goto handleError;
466*e82f7db8SAndroid Build Coastguard Worker             }
467*e82f7db8SAndroid Build Coastguard Worker         }
468*e82f7db8SAndroid Build Coastguard Worker 
469*e82f7db8SAndroid Build Coastguard Worker         info->transport = trans;
470*e82f7db8SAndroid Build Coastguard Worker 
471*e82f7db8SAndroid Build Coastguard Worker         err = (*trans)->StartListening(trans, address, &retAddress);
472*e82f7db8SAndroid Build Coastguard Worker         if (err != JDWPTRANSPORT_ERROR_NONE) {
473*e82f7db8SAndroid Build Coastguard Worker             printLastError(trans, err);
474*e82f7db8SAndroid Build Coastguard Worker             serror = JDWP_ERROR(TRANSPORT_INIT);
475*e82f7db8SAndroid Build Coastguard Worker             goto handleError;
476*e82f7db8SAndroid Build Coastguard Worker         }
477*e82f7db8SAndroid Build Coastguard Worker 
478*e82f7db8SAndroid Build Coastguard Worker         /*
479*e82f7db8SAndroid Build Coastguard Worker          * Record listener address in a system property
480*e82f7db8SAndroid Build Coastguard Worker          */
481*e82f7db8SAndroid Build Coastguard Worker         len = (int)strlen(name) + (int)strlen(retAddress) + 2; /* ':' and '\0' */
482*e82f7db8SAndroid Build Coastguard Worker         prop_value = (char*)jvmtiAllocate(len);
483*e82f7db8SAndroid Build Coastguard Worker         strcpy(prop_value, name);
484*e82f7db8SAndroid Build Coastguard Worker         strcat(prop_value, ":");
485*e82f7db8SAndroid Build Coastguard Worker         strcat(prop_value, retAddress);
486*e82f7db8SAndroid Build Coastguard Worker         setTransportProperty(getEnv(), prop_value);
487*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(prop_value);
488*e82f7db8SAndroid Build Coastguard Worker 
489*e82f7db8SAndroid Build Coastguard Worker 
490*e82f7db8SAndroid Build Coastguard Worker         (void)strcpy(threadName, "JDWP Transport Listener: ");
491*e82f7db8SAndroid Build Coastguard Worker         (void)strcat(threadName, name);
492*e82f7db8SAndroid Build Coastguard Worker 
493*e82f7db8SAndroid Build Coastguard Worker         func = &acceptThread;
494*e82f7db8SAndroid Build Coastguard Worker         error = spawnNewThread(func, (void*)info, threadName);
495*e82f7db8SAndroid Build Coastguard Worker         if (error != JVMTI_ERROR_NONE) {
496*e82f7db8SAndroid Build Coastguard Worker             serror = map2jdwpError(error);
497*e82f7db8SAndroid Build Coastguard Worker             goto handleError;
498*e82f7db8SAndroid Build Coastguard Worker         }
499*e82f7db8SAndroid Build Coastguard Worker 
500*e82f7db8SAndroid Build Coastguard Worker         launchCommand = debugInit_launchOnInit();
501*e82f7db8SAndroid Build Coastguard Worker         if (launchCommand != NULL) {
502*e82f7db8SAndroid Build Coastguard Worker             serror = launch(launchCommand, name, retAddress);
503*e82f7db8SAndroid Build Coastguard Worker             if (serror != JDWP_ERROR(NONE)) {
504*e82f7db8SAndroid Build Coastguard Worker                 goto handleError;
505*e82f7db8SAndroid Build Coastguard Worker             }
506*e82f7db8SAndroid Build Coastguard Worker         } else {
507*e82f7db8SAndroid Build Coastguard Worker             if ( ! gdata->quiet ) {
508*e82f7db8SAndroid Build Coastguard Worker                 TTY_MESSAGE(("Listening for transport %s at address: %s",
509*e82f7db8SAndroid Build Coastguard Worker                     name, retAddress));
510*e82f7db8SAndroid Build Coastguard Worker             }
511*e82f7db8SAndroid Build Coastguard Worker         }
512*e82f7db8SAndroid Build Coastguard Worker         return JDWP_ERROR(NONE);
513*e82f7db8SAndroid Build Coastguard Worker 
514*e82f7db8SAndroid Build Coastguard Worker handleError:
515*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(info->name);
516*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(info->address);
517*e82f7db8SAndroid Build Coastguard Worker         jvmtiDeallocate(info);
518*e82f7db8SAndroid Build Coastguard Worker     } else {
519*e82f7db8SAndroid Build Coastguard Worker         /*
520*e82f7db8SAndroid Build Coastguard Worker          * Note that we don't attempt to do a launch here. Launching
521*e82f7db8SAndroid Build Coastguard Worker          * is currently supported only in server mode.
522*e82f7db8SAndroid Build Coastguard Worker          */
523*e82f7db8SAndroid Build Coastguard Worker 
524*e82f7db8SAndroid Build Coastguard Worker         /*
525*e82f7db8SAndroid Build Coastguard Worker          * If we're connecting to another process, there shouldn't be
526*e82f7db8SAndroid Build Coastguard Worker          * any concurrent listens, so its ok if we block here in this
527*e82f7db8SAndroid Build Coastguard Worker          * thread, waiting for the attach to finish.
528*e82f7db8SAndroid Build Coastguard Worker          */
529*e82f7db8SAndroid Build Coastguard Worker          err = (*trans)->Attach(trans, address, timeout, 0);
530*e82f7db8SAndroid Build Coastguard Worker          if (err != JDWPTRANSPORT_ERROR_NONE) {
531*e82f7db8SAndroid Build Coastguard Worker              printLastError(trans, err);
532*e82f7db8SAndroid Build Coastguard Worker              serror = JDWP_ERROR(TRANSPORT_INIT);
533*e82f7db8SAndroid Build Coastguard Worker              return serror;
534*e82f7db8SAndroid Build Coastguard Worker          }
535*e82f7db8SAndroid Build Coastguard Worker 
536*e82f7db8SAndroid Build Coastguard Worker          /*
537*e82f7db8SAndroid Build Coastguard Worker           * Start the transport loop in a separate thread
538*e82f7db8SAndroid Build Coastguard Worker           */
539*e82f7db8SAndroid Build Coastguard Worker          (void)strcpy(threadName, "JDWP Transport Listener: ");
540*e82f7db8SAndroid Build Coastguard Worker          (void)strcat(threadName, name);
541*e82f7db8SAndroid Build Coastguard Worker 
542*e82f7db8SAndroid Build Coastguard Worker          func = &attachThread;
543*e82f7db8SAndroid Build Coastguard Worker          err = spawnNewThread(func, (void*)trans, threadName);
544*e82f7db8SAndroid Build Coastguard Worker          serror = map2jdwpError(err);
545*e82f7db8SAndroid Build Coastguard Worker     }
546*e82f7db8SAndroid Build Coastguard Worker     return serror;
547*e82f7db8SAndroid Build Coastguard Worker }
548*e82f7db8SAndroid Build Coastguard Worker 
549*e82f7db8SAndroid Build Coastguard Worker void
transport_close(void)550*e82f7db8SAndroid Build Coastguard Worker transport_close(void)
551*e82f7db8SAndroid Build Coastguard Worker {
552*e82f7db8SAndroid Build Coastguard Worker     if ( transport != NULL ) {
553*e82f7db8SAndroid Build Coastguard Worker         (*transport)->Close(transport);
554*e82f7db8SAndroid Build Coastguard Worker     }
555*e82f7db8SAndroid Build Coastguard Worker }
556*e82f7db8SAndroid Build Coastguard Worker 
557*e82f7db8SAndroid Build Coastguard Worker jboolean
transport_is_open(void)558*e82f7db8SAndroid Build Coastguard Worker transport_is_open(void)
559*e82f7db8SAndroid Build Coastguard Worker {
560*e82f7db8SAndroid Build Coastguard Worker     jboolean is_open = JNI_FALSE;
561*e82f7db8SAndroid Build Coastguard Worker 
562*e82f7db8SAndroid Build Coastguard Worker     if ( transport != NULL ) {
563*e82f7db8SAndroid Build Coastguard Worker         is_open = (*transport)->IsOpen(transport);
564*e82f7db8SAndroid Build Coastguard Worker     }
565*e82f7db8SAndroid Build Coastguard Worker     return is_open;
566*e82f7db8SAndroid Build Coastguard Worker }
567*e82f7db8SAndroid Build Coastguard Worker 
568*e82f7db8SAndroid Build Coastguard Worker jint
transport_sendPacket(jdwpPacket * packet)569*e82f7db8SAndroid Build Coastguard Worker transport_sendPacket(jdwpPacket *packet)
570*e82f7db8SAndroid Build Coastguard Worker {
571*e82f7db8SAndroid Build Coastguard Worker     jdwpTransportError err = JDWPTRANSPORT_ERROR_NONE;
572*e82f7db8SAndroid Build Coastguard Worker     jint rc = 0;
573*e82f7db8SAndroid Build Coastguard Worker 
574*e82f7db8SAndroid Build Coastguard Worker     if (transport != NULL) {
575*e82f7db8SAndroid Build Coastguard Worker         if ( (*transport)->IsOpen(transport) ) {
576*e82f7db8SAndroid Build Coastguard Worker             debugMonitorEnter(sendLock);
577*e82f7db8SAndroid Build Coastguard Worker             err = (*transport)->WritePacket(transport, packet);
578*e82f7db8SAndroid Build Coastguard Worker             debugMonitorExit(sendLock);
579*e82f7db8SAndroid Build Coastguard Worker         }
580*e82f7db8SAndroid Build Coastguard Worker         if (err != JDWPTRANSPORT_ERROR_NONE) {
581*e82f7db8SAndroid Build Coastguard Worker             if ((*transport)->IsOpen(transport)) {
582*e82f7db8SAndroid Build Coastguard Worker                 printLastError(transport, err);
583*e82f7db8SAndroid Build Coastguard Worker             }
584*e82f7db8SAndroid Build Coastguard Worker 
585*e82f7db8SAndroid Build Coastguard Worker             /*
586*e82f7db8SAndroid Build Coastguard Worker              * The users of transport_sendPacket except 0 for
587*e82f7db8SAndroid Build Coastguard Worker              * success; non-0 otherwise.
588*e82f7db8SAndroid Build Coastguard Worker              */
589*e82f7db8SAndroid Build Coastguard Worker             rc = (jint)-1;
590*e82f7db8SAndroid Build Coastguard Worker         }
591*e82f7db8SAndroid Build Coastguard Worker 
592*e82f7db8SAndroid Build Coastguard Worker     } /* else, bit bucket */
593*e82f7db8SAndroid Build Coastguard Worker 
594*e82f7db8SAndroid Build Coastguard Worker     return rc;
595*e82f7db8SAndroid Build Coastguard Worker }
596*e82f7db8SAndroid Build Coastguard Worker 
597*e82f7db8SAndroid Build Coastguard Worker jint
transport_receivePacket(jdwpPacket * packet)598*e82f7db8SAndroid Build Coastguard Worker transport_receivePacket(jdwpPacket *packet)
599*e82f7db8SAndroid Build Coastguard Worker {
600*e82f7db8SAndroid Build Coastguard Worker     jdwpTransportError err;
601*e82f7db8SAndroid Build Coastguard Worker 
602*e82f7db8SAndroid Build Coastguard Worker     err = (*transport)->ReadPacket(transport, packet);
603*e82f7db8SAndroid Build Coastguard Worker     if (err != JDWPTRANSPORT_ERROR_NONE) {
604*e82f7db8SAndroid Build Coastguard Worker         /*
605*e82f7db8SAndroid Build Coastguard Worker          * If transport has been closed return EOF
606*e82f7db8SAndroid Build Coastguard Worker          */
607*e82f7db8SAndroid Build Coastguard Worker         if (!(*transport)->IsOpen(transport)) {
608*e82f7db8SAndroid Build Coastguard Worker             packet->type.cmd.len = 0;
609*e82f7db8SAndroid Build Coastguard Worker             return 0;
610*e82f7db8SAndroid Build Coastguard Worker         }
611*e82f7db8SAndroid Build Coastguard Worker 
612*e82f7db8SAndroid Build Coastguard Worker         printLastError(transport, err);
613*e82f7db8SAndroid Build Coastguard Worker 
614*e82f7db8SAndroid Build Coastguard Worker         /*
615*e82f7db8SAndroid Build Coastguard Worker          * Users of transport_receivePacket expect 0 for success,
616*e82f7db8SAndroid Build Coastguard Worker          * non-0 otherwise.
617*e82f7db8SAndroid Build Coastguard Worker          */
618*e82f7db8SAndroid Build Coastguard Worker         return (jint)-1;
619*e82f7db8SAndroid Build Coastguard Worker     }
620*e82f7db8SAndroid Build Coastguard Worker     return 0;
621*e82f7db8SAndroid Build Coastguard Worker }
622