mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-03 15:15:25 +02:00
[226301][api][breaking] IShellService methods should throw SystemMessageException
This commit is contained in:
parent
9a28e0eb21
commit
9c8e811837
11 changed files with 176 additions and 145 deletions
|
@ -1,14 +1,15 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2007 PalmSource, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Copyright (c) 2006, 2008 PalmSource, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Ewa Matejska (PalmSource) - Adapted from LocalRunLaunchDelegate
|
||||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||
* Martin Oberhuber (Wind River) - [186773] split ISystemRegistryUI from ISystemRegistry
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
|
@ -55,19 +56,19 @@ import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IShell
|
|||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
||||
|
||||
|
||||
private final static String SHELL_SERVICE = "shell.service"; //$NON-NLS-1$
|
||||
private final static String FILE_SERVICE = "file.service"; //$NON-NLS-1$
|
||||
private final static String EXIT_CMD = "exit"; //$NON-NLS-1$
|
||||
private final static String CMD_DELIMITER = ";"; //$NON-NLS-1$
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch
|
||||
*/
|
||||
public void launch(ILaunchConfiguration config, String mode, ILaunch launch,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
|
||||
|
||||
IBinaryObject exeFile = null;
|
||||
IPath exePath = verifyProgramPath(config);
|
||||
ICProject project = verifyCProject(config);
|
||||
|
@ -77,9 +78,9 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
|||
|
||||
String arguments = getProgramArguments(config);
|
||||
String remoteExePath = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_PATH, ""); //$NON-NLS-1$
|
||||
|
||||
|
||||
if(mode.equals(ILaunchManager.DEBUG_MODE)){
|
||||
setDefaultSourceLocator(launch, config);
|
||||
setDefaultSourceLocator(launch, config);
|
||||
String debugMode = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE,
|
||||
ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN);
|
||||
if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) {
|
||||
|
@ -88,7 +89,7 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
|||
try {
|
||||
// Download the binary to the remote before debugging.
|
||||
remoteFileDownload(config, launch, exePath.toString(), remoteExePath);
|
||||
|
||||
|
||||
// Automatically start up the gdbserver. In the future this should be expanded to launch
|
||||
// an arbitrary remote damon.
|
||||
String gdbserver_port_number = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_GDBSERVER_PORT,
|
||||
|
@ -102,28 +103,28 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
|||
remoteShellProcess = remoteShellExec(config, gdbserver_command,
|
||||
command_arguments);
|
||||
DebugPlugin.newProcess(launch, remoteShellProcess, Messages.RemoteRunLaunchDelegate_RemoteShell);
|
||||
|
||||
|
||||
// Pre-set configuration constants for the GDBSERVERCDIDebugger to indicate how the gdbserver
|
||||
// was automatically started on the remote. GDBServerCDIDebugger uses these to figure out how
|
||||
// to connect to the remote gdbserver.
|
||||
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||
wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_REMOTE_TCP, true);
|
||||
wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_HOST, getRemoteHostname(config));
|
||||
wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_PORT,
|
||||
wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_HOST, getRemoteHostname(config));
|
||||
wc.setAttribute(IGDBServerMILaunchConfigurationConstants.ATTR_PORT,
|
||||
gdbserver_port_number);
|
||||
wc.doSave();
|
||||
|
||||
// Default to using the GDBServerCDIDebugger.
|
||||
GDBServerCDIDebugger2 debugger = new GDBServerCDIDebugger2();
|
||||
dsession = ((ICDIDebugger2)debugger).createSession(launch, exePath.toFile(),
|
||||
dsession = ((ICDIDebugger2)debugger).createSession(launch, exePath.toFile(),
|
||||
new SubProgressMonitor(monitor, 8));
|
||||
|
||||
boolean stopInMain = config
|
||||
.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false);
|
||||
String stopSymbol = null;
|
||||
if ( stopInMain )
|
||||
stopSymbol = launch.getLaunchConfiguration().getAttribute(
|
||||
ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL,
|
||||
stopSymbol = launch.getLaunchConfiguration().getAttribute(
|
||||
ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL,
|
||||
ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT );
|
||||
|
||||
ICDITarget[] targets = dsession.getTargets();
|
||||
|
@ -133,8 +134,8 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
|||
if (process != null) {
|
||||
iprocess = DebugPlugin.newProcess(launch, process,
|
||||
renderProcessLabel(exePath.toOSString()), getDefaultProcessMap());
|
||||
}
|
||||
CDIDebugModel.newDebugTarget(launch, project.getProject(), targets[i],
|
||||
}
|
||||
CDIDebugModel.newDebugTarget(launch, project.getProject(), targets[i],
|
||||
renderProcessLabel("gdbserver debugger"), //$NON-NLS-1$
|
||||
iprocess, exeFile, true, false, stopSymbol, true);
|
||||
}
|
||||
|
@ -164,21 +165,21 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
|||
remoteProcess.destroy();
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
IStatus status = new Status(IStatus.ERROR, getPluginID(),
|
||||
IStatus.OK, NLS.bind(Messages.RemoteRunLaunchDelegate_1, mode), null);
|
||||
throw new CoreException(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String spaceEscapify(String inputString) {
|
||||
if(inputString == null)
|
||||
return null;
|
||||
|
||||
|
||||
return inputString.replaceAll(" ", "\\\\ "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
|
||||
protected IHost getCurrentConnection(ILaunchConfiguration config) throws CoreException {
|
||||
String remoteConnection = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_REMOTE_CONNECTION, ""); //$NON-NLS-1$
|
||||
|
||||
|
@ -192,16 +193,16 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
|||
}
|
||||
return connections[i];
|
||||
}
|
||||
|
||||
|
||||
protected IService getConnectedRemoteService(ILaunchConfiguration config, String kindOfService)
|
||||
throws CoreException {
|
||||
|
||||
|
||||
// Check that the service requested is file or shell.
|
||||
if(!kindOfService.equals(SHELL_SERVICE) && !kindOfService.equals(FILE_SERVICE))
|
||||
abort(Messages.RemoteRunLaunchDelegate_3, null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
|
||||
|
||||
|
||||
IHost currentConnection = getCurrentConnection(config);
|
||||
|
||||
|
||||
ISubSystem[] subSystems = currentConnection.getSubSystems();
|
||||
int i = 0;
|
||||
for(i = 0; i < subSystems.length; i++) {
|
||||
|
@ -226,21 +227,21 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if(!subsystem.isConnected())
|
||||
abort(Messages.RemoteRunLaunchDelegate_5, null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
|
||||
|
||||
|
||||
if(kindOfService.equals(SHELL_SERVICE))
|
||||
return ((IShellServiceSubSystem) subsystem).getShellService();
|
||||
else
|
||||
return ((IFileServiceSubSystem) subsystem).getFileService();
|
||||
}
|
||||
|
||||
|
||||
protected Process remoteFileDownload(ILaunchConfiguration config, ILaunch launch,
|
||||
String localExePath, String remoteExePath) throws CoreException {
|
||||
|
||||
|
||||
boolean skipDownload = config.getAttribute(IRemoteConnectionConfigurationConstants.ATTR_SKIP_DOWNLOAD_TO_TARGET, false);
|
||||
|
||||
|
||||
if(skipDownload)
|
||||
// Nothing to do. Download is skipped.
|
||||
return null;
|
||||
|
@ -257,44 +258,43 @@ public class RemoteRunLaunchDelegate extends AbstractCLaunchDelegate {
|
|||
p.destroy();
|
||||
} catch (Exception e) {
|
||||
abort(Messages.RemoteRunLaunchDelegate_6, e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected String getRemoteHostname(ILaunchConfiguration config) throws CoreException {
|
||||
IHost currentConnection = getCurrentConnection(config);
|
||||
return currentConnection.getHostName();
|
||||
}
|
||||
|
||||
|
||||
protected Process remoteShellExec(ILaunchConfiguration config, String remoteCommandPath,
|
||||
String arguments) throws CoreException {
|
||||
// The exit command is called to force the remote shell to close after our command
|
||||
// The exit command is called to force the remote shell to close after our command
|
||||
// is executed. This is to prevent a running process at the end of the debug session.
|
||||
// See Bug 158786.
|
||||
String real_remote_command = arguments == null ? spaceEscapify(remoteCommandPath) :
|
||||
spaceEscapify(remoteCommandPath) + " " + arguments; //$NON-NLS-1$
|
||||
String remote_command = real_remote_command + CMD_DELIMITER + EXIT_CMD;
|
||||
|
||||
|
||||
IShellService shellService = (IShellService) getConnectedRemoteService(config, SHELL_SERVICE);
|
||||
|
||||
|
||||
// This is necessary because runCommand does not actually run the command right now.
|
||||
String env[] = new String[0];
|
||||
IHostShell hostShell = shellService.launchShell("", env,new NullProgressMonitor()); //$NON-NLS-1$
|
||||
hostShell.writeToShell(remote_command);
|
||||
|
||||
Process p = null;
|
||||
try {
|
||||
IHostShell hostShell = shellService.launchShell("", env, new NullProgressMonitor()); //$NON-NLS-1$
|
||||
hostShell.writeToShell(remote_command);
|
||||
p = new HostShellProcessAdapter(hostShell);
|
||||
} catch (Exception e) {
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
abort(Messages.RemoteRunLaunchDelegate_7, null, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
|
||||
abort(Messages.RemoteRunLaunchDelegate_7, e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
|
||||
}
|
||||
return p;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected String getPluginID() {
|
||||
return "org.eclipse.rse.internal.remotecdt"; //$NON-NLS-1$
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* David McKnight (IBM) - [196624] dstore miner IDs should be String constants rather than dynamic lookup
|
||||
* David McKnight (IBM) - [216252] use SimpleSystemMessage instead of getMessage()
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable and add Javadoc
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.dstore.shells;
|
||||
|
@ -32,6 +33,7 @@ import org.eclipse.dstore.core.model.IDataStoreProvider;
|
|||
import org.eclipse.rse.dstore.universal.miners.IUniversalDataStoreConstants;
|
||||
import org.eclipse.rse.internal.services.dstore.ServiceResources;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessage;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.dstore.AbstractDStoreService;
|
||||
import org.eclipse.rse.services.dstore.util.DStoreStatusMonitor;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
|
@ -60,7 +62,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS
|
|||
}
|
||||
|
||||
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor)
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) throws SystemMessageException
|
||||
{
|
||||
if (!isInitialized())
|
||||
{
|
||||
|
@ -69,7 +71,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS
|
|||
return launchShell(initialWorkingDirectory, null, environment, monitor);
|
||||
}
|
||||
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor)
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException
|
||||
{
|
||||
if (!isInitialized())
|
||||
{
|
||||
|
@ -79,7 +81,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS
|
|||
}
|
||||
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment,
|
||||
IProgressMonitor monitor)
|
||||
IProgressMonitor monitor) throws SystemMessageException
|
||||
{
|
||||
if (!isInitialized())
|
||||
{
|
||||
|
@ -89,7 +91,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS
|
|||
}
|
||||
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding,
|
||||
String[] environment, IProgressMonitor monitor)
|
||||
String[] environment, IProgressMonitor monitor) throws SystemMessageException
|
||||
{
|
||||
if (!isInitialized())
|
||||
{
|
||||
|
@ -98,7 +100,7 @@ public class DStoreShellService extends AbstractDStoreService implements IShellS
|
|||
return new DStoreHostShell(getStatusMonitor(getDataStore()), getDataStore(), initialWorkingDirectory, command, encoding, environment);
|
||||
}
|
||||
|
||||
public String[] getHostEnvironment()
|
||||
public String[] getHostEnvironment() throws SystemMessageException
|
||||
{
|
||||
if (_envVars == null || _envVars.length == 0)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.local.shells;
|
||||
|
@ -26,6 +27,7 @@ import java.util.List;
|
|||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.rse.internal.services.local.ILocalService;
|
||||
import org.eclipse.rse.internal.services.local.LocalServiceResources;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.shells.AbstractShellService;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
|
||||
|
@ -48,21 +50,21 @@ public class LocalShellService extends AbstractShellService implements ILocalSer
|
|||
return LocalServiceResources.Local_Shell_Service_Description;
|
||||
}
|
||||
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor)
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException
|
||||
{
|
||||
LocalHostShell hostShell = new LocalHostShell(initialWorkingDirectory,SHELL_INVOCATION, encoding, environment);
|
||||
hostShell.run(monitor);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, IProgressMonitor monitor)
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException
|
||||
{
|
||||
LocalHostShell hostShell = new LocalHostShell(initialWorkingDirectory,command, encoding, environment);
|
||||
hostShell.run(monitor);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
public String[] getHostEnvironment()
|
||||
public String[] getHostEnvironment() throws SystemMessageException
|
||||
{
|
||||
if (_envVars == null)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* Martin Oberhuber (Wind River) - Adapted from LocalShellService.
|
||||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.ssh.shell;
|
||||
|
@ -24,6 +25,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
import org.eclipse.rse.internal.services.ssh.ISshService;
|
||||
import org.eclipse.rse.internal.services.ssh.ISshSessionProvider;
|
||||
import org.eclipse.rse.internal.services.ssh.SshServiceResources;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.shells.AbstractShellService;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
|
||||
|
@ -41,23 +43,18 @@ public class SshShellService extends AbstractShellService implements ISshService
|
|||
|
||||
public IHostShell launchShell(String initialWorkingDirectory,
|
||||
String encoding, String[] environment,
|
||||
IProgressMonitor monitor) {
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
SshHostShell hostShell = new SshHostShell(fSessionProvider, initialWorkingDirectory, SshHostShell.SHELL_INVOCATION, encoding, environment);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
public IHostShell runCommand(String initialWorkingDirectory,
|
||||
String command, String encoding, String[] environment,
|
||||
IProgressMonitor monitor) {
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
SshHostShell hostShell = new SshHostShell(fSessionProvider, initialWorkingDirectory, command, encoding, environment);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
public String[] getHostEnvironment() {
|
||||
//TODO getHostEnvironment is not yet implemented for ssh (needs running remote command and parsing)
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return SshServiceResources.SshShellService_Name;
|
||||
}
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
* Martin Oberhuber (Wind River) - Adapted from LocalShellService.
|
||||
* Sheldon D'souza (Celunite) - Adapted from SshShellService.
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable
|
||||
*******************************************************************************/
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
s *******************************************************************************/
|
||||
package org.eclipse.rse.internal.services.telnet.shell;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.rse.internal.services.telnet.ITelnetService;
|
||||
import org.eclipse.rse.internal.services.telnet.ITelnetSessionProvider;
|
||||
import org.eclipse.rse.internal.services.telnet.TelnetServiceResources;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.shells.AbstractShellService;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
|
||||
|
@ -33,20 +35,16 @@ public class TelnetShellService extends AbstractShellService implements ITelnetS
|
|||
this.fTelnetSessionProvider = sessionProvider;
|
||||
}
|
||||
|
||||
public String[] getHostEnvironment() {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public IHostShell launchShell(String initialWorkingDirectory,
|
||||
String encoding, String[] environment,
|
||||
IProgressMonitor monitor) {
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
TelnetHostShell hostShell = new TelnetHostShell(fTelnetSessionProvider, initialWorkingDirectory, TelnetHostShell.SHELL_INVOCATION, encoding, environment);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
public IHostShell runCommand(String initialWorkingDirectory,
|
||||
String command, String encoding, String[] environment,
|
||||
IProgressMonitor monitor) {
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
TelnetHostShell hostShell = new TelnetHostShell(fTelnetSessionProvider, initialWorkingDirectory, TelnetHostShell.SHELL_INVOCATION, encoding, environment);
|
||||
return hostShell;
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ import org.eclipse.core.runtime.PlatformObject;
|
|||
/**
|
||||
* Abstract default implementation of an RSE Service. Clients are expected to
|
||||
* extend this class.
|
||||
*
|
||||
*
|
||||
* @see IService
|
||||
* @since org.eclipse.rse.core 3.0
|
||||
* @since org.eclipse.rse.services 3.0
|
||||
*/
|
||||
public abstract class AbstractService extends PlatformObject implements IService {
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.services.shells;
|
||||
|
@ -14,31 +15,41 @@ package org.eclipse.rse.services.shells;
|
|||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import org.eclipse.rse.services.AbstractService;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
|
||||
/**
|
||||
* Abstract base class for RSE Shell Service implementations.
|
||||
*
|
||||
* @since org.eclipse.rse.services 3.0
|
||||
*/
|
||||
public abstract class AbstractShellService extends AbstractService implements IShellService {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.rse.services.shells.IShellService#getHostEnvironment()
|
||||
private static final String[] EMPTY_ARRAY = new String[0];
|
||||
|
||||
/**
|
||||
* Return an empty host environment. Extenders should override this method
|
||||
* if they are able to return environment on the remote side. If they do not
|
||||
* implement this feature, they must not override this method.
|
||||
*
|
||||
* @see IShellService#getHostEnvironment()
|
||||
*/
|
||||
public String[] getHostEnvironment() {
|
||||
public String[] getHostEnvironment() throws SystemMessageException {
|
||||
// not implemented by default
|
||||
return null;
|
||||
// TODO SSH https://bugs.eclipse.org/bugs/show_bug.cgi?id=162018
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.rse.services.shells.IShellService#launchShell(java.lang.String, java.lang.String[], org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) {
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) throws SystemMessageException {
|
||||
return launchShell(initialWorkingDirectory, null, environment, monitor);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.rse.services.shells.IShellService#runCommand(java.lang.String, java.lang.String, java.lang.String[], org.eclipse.core.runtime.IProgressMonitor)
|
||||
*/
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, IProgressMonitor monitor) {
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, IProgressMonitor monitor) throws SystemMessageException {
|
||||
return runCommand(initialWorkingDirectory, command, null, environment, monitor);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable and add Javadoc
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.rse.services.shells;
|
||||
|
@ -20,6 +21,7 @@ package org.eclipse.rse.services.shells;
|
|||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import org.eclipse.rse.services.IService;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
|
||||
/**
|
||||
* IShellService is an abstraction for running shells and shell commands.
|
||||
|
@ -36,16 +38,19 @@ public interface IShellService extends IService
|
|||
*
|
||||
* This is a convenience method, passing <code>null</code> as encoding
|
||||
* into {@link #launchShell(String, String, String[], IProgressMonitor)}.
|
||||
*
|
||||
* @throws SystemMessageException in case an error occurred or the user
|
||||
* chose to cancel the operation via the progress monitor.
|
||||
*/
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor);
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String[] environment, IProgressMonitor monitor) throws SystemMessageException;
|
||||
|
||||
/**
|
||||
* Launch a new shell in the specified directory.
|
||||
*
|
||||
* @param initialWorkingDirectory initial working directory or
|
||||
* <code>null</code> if not relevant. The remote shell will
|
||||
* launch in a directory of its own choice in that case
|
||||
* (typically a user's home directory).
|
||||
* @param initialWorkingDirectory initial working directory or empty String
|
||||
* ("") if not relevant. The remote shell will launch in a
|
||||
* directory of its own choice in that case (typically a user's
|
||||
* home directory).
|
||||
* @param encoding Stream encoding to use, or <code>null</code> to fall
|
||||
* back to a default encoding. The Shell Service will make
|
||||
* efforts to determine a proper default encoding on the remote
|
||||
|
@ -57,11 +62,13 @@ public interface IShellService extends IService
|
|||
* set.
|
||||
* @param monitor Progress Monitor for monitoring and cancellation
|
||||
* @return the shell object. Note that the shell may not actually be usable
|
||||
* in case an error occurred or the operation was canceled. In this
|
||||
* case, {@link IHostShell#isActive()} returns <code>false</code>
|
||||
* on the created Shell object.
|
||||
* in case the remote side allows opening a channel but immediately
|
||||
* closes it again. In this case, {@link IHostShell#isActive()}
|
||||
* returns <code>false</code> on the created Shell object.
|
||||
* @throws SystemMessageException in case an error occurred or the user
|
||||
* chose to cancel the operation via the progress monitor.
|
||||
*/
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor);
|
||||
public IHostShell launchShell(String initialWorkingDirectory, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -70,8 +77,11 @@ public interface IShellService extends IService
|
|||
* This is a convenience method, passing <code>null</code> as encoding
|
||||
* into
|
||||
* {@link #runCommand(String, String, String, String[], IProgressMonitor)}.
|
||||
*
|
||||
* @throws SystemMessageException in case an error occurred or the user
|
||||
* chose to cancel the operation via the progress monitor.
|
||||
*/
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, IProgressMonitor monitor);
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String[] environment, IProgressMonitor monitor) throws SystemMessageException;
|
||||
|
||||
/**
|
||||
* Run a single command in it's own shell.
|
||||
|
@ -85,10 +95,10 @@ public interface IShellService extends IService
|
|||
* connection automatically. Clients need to call {@link IHostShell#exit()}
|
||||
* in case the shell remains active after the initial command is completed.
|
||||
*
|
||||
* @param initialWorkingDirectory initial working directory or
|
||||
* <code>null</code> if not relevant. The remote shell will
|
||||
* launch in a directory of its own choice in that case
|
||||
* (typically a user's home directory).
|
||||
* @param initialWorkingDirectory initial working directory or empty String
|
||||
* ("") if not relevant. The remote command will launch in a
|
||||
* directory of its own choice in that case (typically a user's
|
||||
* home directory).
|
||||
* @param encoding Stream encoding to use, or <code>null</code> to fall
|
||||
* back to a default encoding. The Shell Service will make
|
||||
* efforts to determine a proper default encoding on the remote
|
||||
|
@ -100,23 +110,27 @@ public interface IShellService extends IService
|
|||
* set.
|
||||
* @param monitor Progress Monitor for monitoring and cancellation
|
||||
* @return the shell object for getting output and error streams. Note that
|
||||
* the shell may not actually be usable in case an error occurred or
|
||||
* the operation was canceled. In this case,
|
||||
* {@link IHostShell#isActive()} returns <code>false</code> on the
|
||||
* created Shell object.
|
||||
* the shell may not actually be usable in case an error occurred on
|
||||
* the remote side, such as the command not being executable. In
|
||||
* this case, {@link IHostShell#isActive()} returns
|
||||
* <code>false</code> on the created Shell object.
|
||||
* @throws SystemMessageException in case an error occurred or the user
|
||||
* chose to cancel the operation via the progress monitor.
|
||||
*/
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, IProgressMonitor monitor);
|
||||
public IHostShell runCommand(String initialWorkingDirectory, String command, String encoding, String[] environment, IProgressMonitor monitor) throws SystemMessageException;
|
||||
|
||||
/**
|
||||
* Return an array of environment variables that describe the environment on
|
||||
* the remote system. Each String returned is of the format "var=text":
|
||||
* Everything up to the first equals sign is the name of the given
|
||||
* environment variable, everything after the equals sign is its contents.
|
||||
*
|
||||
*
|
||||
* @return Array of environment variable Strings of the form "var=text" if
|
||||
* supported by a shell service implementation. May return
|
||||
* <code>null</code> in case environment variable retrieval is not
|
||||
* supported by a shell service implementation. Should return an
|
||||
* empty array in case environment variable retrieval is not
|
||||
* supported on a particular shell service implementation.
|
||||
* @throws SystemMessageException in case an error occurred or the user
|
||||
* chose to cancel the operation via the progress monitor.
|
||||
*/
|
||||
public String[] getHostEnvironment();
|
||||
public String[] getHostEnvironment() throws SystemMessageException;
|
||||
}
|
|
@ -1,20 +1,21 @@
|
|||
/********************************************************************************
|
||||
* Copyright (c) 2005, 2007 IBM Corporation and others. All rights reserved.
|
||||
* Copyright (c) 2005, 2008 IBM Corporation and others. All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
*
|
||||
* Contributors:
|
||||
* Yu-Fen Kuo (MontaVista) - adapted from RSE UniversalLinuxProcessHandler
|
||||
* Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
|
||||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||
* David McKnight (IBM) - [175308] Need to use a job to wait for shell to exit
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.subsystems.processes.shell.linux;
|
||||
|
@ -34,7 +35,7 @@ import org.eclipse.rse.services.shells.IShellService;
|
|||
|
||||
/**
|
||||
* Helper class that helps to get state code and user name info most of the code
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class LinuxProcessHelper {
|
||||
private HashMap stateMap;
|
||||
|
@ -92,11 +93,10 @@ public class LinuxProcessHelper {
|
|||
_uidsByUserName = new HashMap();
|
||||
|
||||
IShellService shellService = Activator.getShellService(host);
|
||||
IHostShell hostShell = shellService.launchShell(
|
||||
"", null, new NullProgressMonitor()); //$NON-NLS-1$
|
||||
hostShell.writeToShell(getUserNameCommand());
|
||||
Process p = null;
|
||||
try {
|
||||
IHostShell hostShell = shellService.launchShell("", null, new NullProgressMonitor()); //$NON-NLS-1$
|
||||
hostShell.writeToShell(getUserNameCommand());
|
||||
p = new HostShellProcessAdapter(hostShell);
|
||||
// when p.waitFor() is called here, the hostShell.isActive() always
|
||||
// return true.
|
||||
|
@ -131,7 +131,7 @@ public class LinuxProcessHelper {
|
|||
} catch (IOException e) {
|
||||
Activator.log(e);
|
||||
}
|
||||
|
||||
|
||||
// Wait for remote process to exit.
|
||||
WaiterJob waiter = new WaiterJob(p);
|
||||
waiter.schedule();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||
* David McKnight (IBM) - [175308] Need to use a job to wait for shell to exit
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable and add Javadoc
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.subsystems.processes.shell.linux;
|
||||
|
@ -212,15 +213,14 @@ public class LinuxShellProcessService extends AbstractProcessService {
|
|||
*/
|
||||
protected String[] internalGetSignalTypes() {
|
||||
IShellService shellService = Activator.getShellService(host);
|
||||
IHostShell hostShell = shellService.launchShell(
|
||||
"", null, new NullProgressMonitor()); //$NON-NLS-1$
|
||||
hostShell.writeToShell(getSignalTypesCommand());
|
||||
Process p = null;
|
||||
try {
|
||||
IHostShell hostShell = shellService.launchShell("", null, new NullProgressMonitor()); //$NON-NLS-1$
|
||||
hostShell.writeToShell(getSignalTypesCommand());
|
||||
p = new HostShellProcessAdapter(hostShell);
|
||||
// p.waitFor();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Activator.log(e);
|
||||
if (p != null) {
|
||||
p.destroy();
|
||||
}
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
/********************************************************************************
|
||||
* Copyright (c) 2006, 2008 IBM Corporation and others. All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - [175262] IHost.getSystemType() should return IRSESystemType
|
||||
* Martin Oberhuber (Wind River) - [175262] IHost.getSystemType() should return IRSESystemType
|
||||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||
* Martin Oberhuber (Wind River) - [186640] Add IRSESystemType.testProperty()
|
||||
* Martin Oberhuber (Wind River) - [186640] Add IRSESystemType.testProperty()
|
||||
* David McKnight (IBM) - [191599] Need to pass in shell encoding
|
||||
* David Dykstal (IBM) - [197036] refactored switch configuration
|
||||
* David Dykstal (IBM) - [217556] remove service subsystem types
|
||||
* David McKnight (IBM) - [220524] internalSwitchServiceSubSystemConfiguration -> internalSwitchSubSystemConfiguration
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem;
|
||||
|
@ -38,8 +39,9 @@ import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
|
|||
import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCommandShell;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.RemoteCmdSubSystem;
|
||||
import org.eclipse.rse.ui.SystemBasePlugin;
|
||||
|
||||
public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements IShellServiceSubSystem
|
||||
public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements IShellServiceSubSystem
|
||||
{
|
||||
protected String _userHome = null;
|
||||
protected IShellService _hostService;
|
||||
|
@ -49,17 +51,17 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
super(host, connectorService);
|
||||
_hostService = hostService;
|
||||
}
|
||||
|
||||
|
||||
public IShellService getShellService()
|
||||
{
|
||||
return _hostService;
|
||||
}
|
||||
|
||||
|
||||
public void setShellService(IShellService service)
|
||||
{
|
||||
_hostService = service;
|
||||
}
|
||||
|
||||
|
||||
protected String getUserHome()
|
||||
{
|
||||
if (_userHome == null)
|
||||
|
@ -82,7 +84,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
return _userHome;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected Object[] internalRunCommand(String cmd, Object context, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException, SystemMessageException
|
||||
{
|
||||
return internalRunCommand(cmd, context, false, monitor);
|
||||
|
@ -107,12 +109,12 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
}
|
||||
|
||||
|
||||
IShellService service = getShellService();
|
||||
IShellService service = getShellService();
|
||||
IHostShell hostShell = service.runCommand(cwd, cmd, getUserAndHostEnvVarsAsStringArray(), monitor);
|
||||
IServiceCommandShell cmdShell = createRemoteCommandShell(this, hostShell);
|
||||
hostShell.addOutputListener(cmdShell);
|
||||
|
||||
|
||||
|
||||
|
||||
if (_cmdShells.size() == 0)
|
||||
{
|
||||
// if this is first shell, start listening so that on disconnect, we persist
|
||||
|
@ -144,15 +146,15 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
}
|
||||
|
||||
|
||||
IShellService service = getShellService();
|
||||
IShellService service = getShellService();
|
||||
String encoding = getHost().getDefaultEncoding(true);
|
||||
IHostShell hostShell = service.launchShell(cwd, encoding, getUserAndHostEnvVarsAsStringArray(), monitor);
|
||||
IServiceCommandShell cmdShell = createRemoteCommandShell(this, hostShell);
|
||||
if (cmdShell != null)
|
||||
{
|
||||
hostShell.addOutputListener(cmdShell);
|
||||
|
||||
|
||||
|
||||
|
||||
if (_cmdShells.size() == 0)
|
||||
{
|
||||
// if this is first shell, start listening so that on disconnect, we persist
|
||||
|
@ -164,7 +166,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
|
||||
return cmdShell;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void internalCancelShell(Object command, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
|
||||
{
|
||||
|
@ -182,20 +184,25 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
IServiceCommandShell cmdWrapper = (IServiceCommandShell)command;
|
||||
cmdWrapper.writeToShell(cmd);
|
||||
cmdWrapper.updateHistory(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected IServiceCommandShell createRemoteCommandShell(IRemoteCmdSubSystem cmdSS, IHostShell hostShell)
|
||||
{
|
||||
IShellServiceSubSystemConfiguration config = (IShellServiceSubSystemConfiguration)getParentRemoteCmdSubSystemConfiguration();
|
||||
return config.createRemoteCommandShell(cmdSS, hostShell);
|
||||
}
|
||||
|
||||
|
||||
public String[] getHostEnvironment()
|
||||
{
|
||||
return getShellService().getHostEnvironment();
|
||||
try {
|
||||
return getShellService().getHostEnvironment();
|
||||
} catch (SystemMessageException e) {
|
||||
SystemBasePlugin.logError(e.getSystemMessage().getLevelOneText(), e);
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
|
||||
public List getHostEnvironmentVariables()
|
||||
{
|
||||
List l = new ArrayList();
|
||||
|
@ -213,7 +220,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
public boolean canSwitchTo(ISubSystemConfiguration configuration) {
|
||||
return configuration instanceof IShellServiceSubSystemConfiguration;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.rse.core.subsystems.SubSystem#internalServiceSubSystemConfiguration(org.eclipse.rse.core.subsystems.ISubSystemConfiguration)
|
||||
*/
|
||||
|
@ -222,7 +229,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
IHost host = getHost();
|
||||
setShellService(configuration.getShellService(host));
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.rse.core.subsystems.SubSystem#getServiceType()
|
||||
*/
|
||||
|
@ -232,7 +239,7 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
}
|
||||
|
||||
public void initializeSubSystem(IProgressMonitor monitor)
|
||||
{
|
||||
{
|
||||
getShellService().initService(monitor);
|
||||
}
|
||||
|
||||
|
@ -241,5 +248,5 @@ public final class ShellServiceSubSystem extends RemoteCmdSubSystem implements I
|
|||
cancelAllShells();
|
||||
getShellService().uninitService(monitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue