VirtualBox

source: vbox/trunk/src/VBox/Debugger/DBGCIoProvIpc.cpp@ 94521

Last change on this file since 94521 was 93115, checked in by vboxsync, 2 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1/* $Id: DBGCIoProvIpc.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * DBGC - Debugger Console, IPC I/O provider.
4 */
5
6/*
7 * Copyright (C) 2020-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <VBox/dbg.h>
23#include <VBox/err.h>
24#include <VBox/log.h>
25
26#include <iprt/localipc.h>
27#include <iprt/mem.h>
28#include <iprt/assert.h>
29
30#include "DBGCIoProvInternal.h"
31
32
33/*********************************************************************************************************************************
34* Structures and Typedefs *
35*********************************************************************************************************************************/
36/**
37 * Debug console IPC connection data.
38 */
39typedef struct DBGCIPCCON
40{
41 /** The I/O callback table for the console. */
42 DBGCIO Io;
43 /** The socket of the connection. */
44 RTLOCALIPCSESSION hSession;
45 /** Connection status. */
46 bool fAlive;
47} DBGCIPCCON;
48/** Pointer to the instance data of the console IPC backend. */
49typedef DBGCIPCCON *PDBGCIPCCON;
50
51
52/*********************************************************************************************************************************
53* Internal Functions *
54*********************************************************************************************************************************/
55
56/**
57 * @interface_method_impl{DBGCIO,pfnDestroy}
58 */
59static DECLCALLBACK(void) dbgcIoProvIpcIoDestroy(PCDBGCIO pIo)
60{
61 PDBGCIPCCON pIpcCon = RT_FROM_MEMBER(pIo, DBGCIPCCON, Io);
62 RTLocalIpcSessionClose(pIpcCon->hSession);
63 pIpcCon->fAlive =false;
64 RTMemFree(pIpcCon);
65}
66
67
68/**
69 * @interface_method_impl{DBGCIO,pfnInput}
70 */
71static DECLCALLBACK(bool) dbgcIoProvIpcIoInput(PCDBGCIO pIo, uint32_t cMillies)
72{
73 PDBGCIPCCON pIpcCon = RT_FROM_MEMBER(pIo, DBGCIPCCON, Io);
74 if (!pIpcCon->fAlive)
75 return false;
76 int rc = RTLocalIpcSessionWaitForData(pIpcCon->hSession, cMillies);
77 if (RT_FAILURE(rc) && rc != VERR_TIMEOUT)
78 pIpcCon->fAlive = false;
79 return rc != VERR_TIMEOUT;
80}
81
82
83/**
84 * @interface_method_impl{DBGCIO,pfnRead}
85 */
86static DECLCALLBACK(int) dbgcIoProvIpcIoRead(PCDBGCIO pIo, void *pvBuf, size_t cbBuf, size_t *pcbRead)
87{
88 PDBGCIPCCON pIpcCon = RT_FROM_MEMBER(pIo, DBGCIPCCON, Io);
89 if (!pIpcCon->fAlive)
90 return VERR_INVALID_HANDLE;
91 int rc = RTLocalIpcSessionRead(pIpcCon->hSession, pvBuf, cbBuf, pcbRead);
92 if (RT_SUCCESS(rc) && pcbRead != NULL && *pcbRead == 0)
93 rc = VERR_NET_SHUTDOWN;
94 if (RT_FAILURE(rc))
95 pIpcCon->fAlive = false;
96 return rc;
97}
98
99
100/**
101 * @interface_method_impl{DBGCIO,pfnWrite}
102 */
103static DECLCALLBACK(int) dbgcIoProvIpcIoWrite(PCDBGCIO pIo, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
104{
105 PDBGCIPCCON pIpcCon = RT_FROM_MEMBER(pIo, DBGCIPCCON, Io);
106 if (!pIpcCon->fAlive)
107 return VERR_INVALID_HANDLE;
108
109 int rc = RTLocalIpcSessionWrite(pIpcCon->hSession, pvBuf, cbBuf);
110 if (RT_FAILURE(rc))
111 pIpcCon->fAlive = false;
112
113 if (pcbWritten)
114 *pcbWritten = cbBuf;
115
116 return rc;
117}
118
119
120/**
121 * @interface_method_impl{DBGCIO,pfnSetReady}
122 */
123static DECLCALLBACK(void) dbgcIoProvIpcIoSetReady(PCDBGCIO pIo, bool fReady)
124{
125 /* stub */
126 NOREF(pIo);
127 NOREF(fReady);
128}
129
130
131/**
132 * @interface_method_impl{DBGCIOPROVREG,pfnCreate}
133 */
134static DECLCALLBACK(int) dbgcIoProvIpcCreate(PDBGCIOPROV phDbgcIoProv, PCFGMNODE pCfg)
135{
136 /*
137 * Get the address configuration.
138 */
139 char szAddress[512];
140 int rc = CFGMR3QueryStringDef(pCfg, "Address", szAddress, sizeof(szAddress), "");
141 if (RT_FAILURE(rc))
142 {
143 LogRel(("Configuration error: Failed querying \"Address\" -> rc=%Rc\n", rc));
144 return rc;
145 }
146
147 /*
148 * Create the server.
149 */
150 RTLOCALIPCSERVER hIpcSrv;
151 rc = RTLocalIpcServerCreate(&hIpcSrv, szAddress, RTLOCALIPC_FLAGS_NATIVE_NAME);
152 if (RT_SUCCESS(rc))
153 {
154 LogFlow(("dbgcIoProvIpcCreate: Created server on \"%s\"\n", szAddress));
155 *phDbgcIoProv = (DBGCIOPROV)hIpcSrv;
156 return rc;
157 }
158
159 return rc;
160}
161
162
163/**
164 * @interface_method_impl{DBGCIOPROVREG,pfnDestroy}
165 */
166static DECLCALLBACK(void) dbgcIoProvIpcDestroy(DBGCIOPROV hDbgcIoProv)
167{
168 int rc = RTLocalIpcServerDestroy((RTLOCALIPCSERVER)hDbgcIoProv);
169 AssertRC(rc);
170}
171
172
173/**
174 * @interface_method_impl{DBGCIOPROVREG,pfnWaitForConnect}
175 */
176static DECLCALLBACK(int) dbgcIoProvIpcWaitForConnect(DBGCIOPROV hDbgcIoProv, RTMSINTERVAL cMsTimeout, PCDBGCIO *ppDbgcIo)
177{
178 RTLOCALIPCSERVER hIpcSrv = (RTLOCALIPCSERVER)hDbgcIoProv;
179 RT_NOREF(cMsTimeout);
180
181 RTLOCALIPCSESSION hSession = NIL_RTLOCALIPCSESSION;
182 int rc = RTLocalIpcServerListen(hIpcSrv, &hSession);
183 if (RT_SUCCESS(rc))
184 {
185 PDBGCIPCCON pIpcCon = (PDBGCIPCCON)RTMemAllocZ(sizeof(*pIpcCon));
186 if (RT_LIKELY(pIpcCon))
187 {
188 pIpcCon->Io.pfnDestroy = dbgcIoProvIpcIoDestroy;
189 pIpcCon->Io.pfnInput = dbgcIoProvIpcIoInput;
190 pIpcCon->Io.pfnRead = dbgcIoProvIpcIoRead;
191 pIpcCon->Io.pfnWrite = dbgcIoProvIpcIoWrite;
192 pIpcCon->Io.pfnSetReady = dbgcIoProvIpcIoSetReady;
193 pIpcCon->hSession = hSession;
194 pIpcCon->fAlive = true;
195 *ppDbgcIo = &pIpcCon->Io;
196 }
197 else
198 rc = VERR_NO_MEMORY;
199 }
200
201 return rc;
202}
203
204
205/**
206 * @interface_method_impl{DBGCIOPROVREG,pfnWaitInterrupt}
207 */
208static DECLCALLBACK(int) dbgcIoProvIpcWaitInterrupt(DBGCIOPROV hDbgcIoProv)
209{
210 return RTLocalIpcServerCancel((RTLOCALIPCSERVER)hDbgcIoProv);
211}
212
213
214/**
215 * TCP I/O provider registration record.
216 */
217const DBGCIOPROVREG g_DbgcIoProvIpc =
218{
219 /** pszName */
220 "ipc",
221 /** pszDesc */
222 "IPC I/O provider.",
223 /** pfnCreate */
224 dbgcIoProvIpcCreate,
225 /** pfnDestroy */
226 dbgcIoProvIpcDestroy,
227 /** pfnWaitForConnect */
228 dbgcIoProvIpcWaitForConnect,
229 /** pfnWaitInterrupt */
230 dbgcIoProvIpcWaitInterrupt
231};
232
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use