1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-28 11:25:35 +02:00

[159522] Initial submission of shell processes subsystem

This commit is contained in:
Martin Oberhuber 2007-02-21 17:29:58 +00:00
parent 03189e80a8
commit 1d8648b3b6
21 changed files with 1307 additions and 0 deletions

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.rse.subsystems.processes.shell.linux</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,70 @@
#Tue Jan 30 22:33:44 CET 2007
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
org.eclipse.jdt.core.compiler.compliance=1.4
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=warning
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
org.eclipse.jdt.core.compiler.problem.nullReference=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.3

View file

@ -0,0 +1,7 @@
#Fri Jul 07 11:19:10 CEST 2006
eclipse.preferences.version=1
internal.default.compliance=user
org.eclipse.jdt.ui.ignorelowercasenames=true
org.eclipse.jdt.ui.importorder=java;javax;org;com;org.eclipse.rse;
org.eclipse.jdt.ui.ondemandthreshold=99
org.eclipse.jdt.ui.staticondemandthreshold=99

View file

@ -0,0 +1,21 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.rse.subsystems.processes.ssh.linux;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.rse.internal.subsystems.processes.shell.linux.Activator
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.rse.ui,
org.eclipse.rse.services,
org.eclipse.rse.services.ssh,
org.eclipse.rse.core,
com.jcraft.jsch,
org.eclipse.rse.connectorservice.ssh,
org.eclipse.rse.subsystems.processes.core,
org.eclipse.rse.shells.ui,
org.eclipse.rse.subsystems.shells.core
Eclipse-LazyStart: true
Bundle-Vendor: %providerName
Bundle-RequiredExecutionEnvironment: J2SE-1.4

View file

@ -0,0 +1,28 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>About</title>
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>June 2, 2006</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
</body>
</html>

View file

@ -0,0 +1,19 @@
################################################################################
# Copyright (c) 2006, 2007 MontaVista Software, 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:
# Yufen Kuo (MontaVista) - initial API and implementation
# Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
################################################################################
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
about.html,\
plugin.properties,\
plugin.xml,\
icons/

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

View file

@ -0,0 +1,17 @@
################################################################################
# Copyright (c) 2006, 2007 MontaVista Software, 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:
# Yufen Kuo (MontaVista) - initial API and implementation
# Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
################################################################################
pluginName = RSE Linux Shell Processes
providerName = Eclipse.org
ShellProcessSubsystemName=Shell Processes
ShellProcessSubsystemDescription=This configuration allows you to work with processes on remote linux systems using any contributed Shell subsystem.

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<!--
Copyright (c) 2006, 2007 MontaVista Software, 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:
Yufen Kuo (MontaVista) - initial API and implementation
Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
-->
<plugin>
<extension
point="org.eclipse.rse.ui.subsystemConfigurations">
<configuration
systemTypeIds="org.eclipse.rse.systemtype.linux"
name="%ShellProcessSubsystemName"
description="%ShellProcessSubsystemDescription"
iconlive="icons/full/obj16/processsubsystemlive_obj.gif"
icon="icons/full/obj16/processsubsystem_obj.gif"
category="processes"
class="org.eclipse.rse.subsystems.processes.shell.linux.ShellProcessSubSystemConfiguration"
vendor="%providerName"
priority="200"
id="processes.shell.linux"/>
</extension>
</plugin>

View file

@ -0,0 +1,223 @@
/*******************************************************************************
* Copyright (c) 2006, 2007 MontaVista Software, 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:
* Yu-Fen Kuo (MontaVista) - initial API and implementation
* Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
*******************************************************************************/
package org.eclipse.rse.internal.subsystems.processes.shell.linux;
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.eclipse.rse.core.model.IHost;
import org.eclipse.rse.core.subsystems.ISubSystem;
import org.eclipse.rse.services.shells.IShellService;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IShellServiceSubSystem;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
/**
* The plug-in ID
*/
public static final String PLUGIN_ID = "org.eclipse.rse.subsystems.processes.shell.linux"; //$NON-NLS-1$
/**
* string to be echo'ed when running command in shell, used to indicate that
* the command has finished running
*/
public static String DONE_MARKUP_STRING = "--RSE:donedonedone:--"; //$NON-NLS-1$
/**
* command delimiter for shell
*/
public final static String CMD_DELIMITER = ";"; //$NON-NLS-1$
private final static String SHELL_EXIT_CMD = " exit "; //$NON-NLS-1$
private final static String SHELL_ECHO_CMD = " echo "; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
plugin = this;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Convenience method which returns the unique identifier of this plugin.
*/
public static String getUniqueIdentifier() {
if (getDefault() == null) {
// If the default instance is not yet initialized,
// return a static identifier. This identifier must
// match the plugin id defined in plugin.xml
return PLUGIN_ID;
}
return getDefault().getBundle().getSymbolicName();
}
/**
* Logs the specified status with this plug-in's log.
*
* @param status
* status to log
*/
public static void log(IStatus status) {
getDefault().getLog().log(status);
}
/**
* Logs an internal error with the specified message.
*
* @param message
* the error message to log
*/
public static void logErrorMessage(String message) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR,
message, null));
}
/**
* Logs an internal error with the specified throwable
*
* @param e
* the exception to be logged
*/
public static void log(Throwable e) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, e
.getMessage(), e));
}
/**
* format the command to be sent into the shell command with the done markup
* string and the exit string. The done markup string is needed so we can
* tell that end of output has been reached.
*
* @param cmd
* @return formatted command string
*/
public static String formatShellCommand(String cmd) {
if (cmd == null || cmd.equals("")) //$NON-NLS-1$
return cmd;
StringBuffer formattedCommand = new StringBuffer();
formattedCommand.append(cmd).append(CMD_DELIMITER);
formattedCommand.append(SHELL_ECHO_CMD).append(DONE_MARKUP_STRING);
formattedCommand.append(CMD_DELIMITER).append(SHELL_EXIT_CMD);
return formattedCommand.toString();
}
/**
* Find the first shell service associated with the host.
*
* @param host the connection
* @return shell service object, or <code>null</code> if not found.
*/
public static IShellService getShellService(IHost host) {
IShellServiceSubSystem ss = getShellServiceSubSystem(host);
if (ss!=null) {
return ss.getShellService();
}
return null;
}
/**
* Find the first IShellServiceSubSystem service associated with the host.
*
* @param host the connection
* @return shell service subsystem, or <code>null</code> if not found.
*/
public static IShellServiceSubSystem getShellServiceSubSystem(IHost host) {
if (host == null)
return null;
ISubSystem[] subSystems = host.getSubSystems();
for (int i = 0; subSystems != null && i < subSystems.length; i++) {
if (subSystems[i] instanceof IShellServiceSubSystem) {
return (IShellServiceSubSystem)subSystems[i];
}
}
return null;
}
/**
* append the error message into a string from reading the error Stream.
*
* @param errStream
* @return error message
*/
public static String getErrorMessage(InputStream errStream) {
// error buffer
StringBuffer errBuf = new StringBuffer();
byte[] bytes = null;
int numOfBytesRead = 0;
try {
int available = errStream.available();
while (available > 0) {
bytes = new byte[available];
numOfBytesRead = errStream.read(bytes);
if (numOfBytesRead > -1) {
errBuf.append(new String(bytes, 0, numOfBytesRead));
} else {
break;
}
available = errStream.available();
}
return errBuf.toString();
} catch (IOException e) {
Activator.log(e);
}
return null;
}
}

View file

@ -0,0 +1,172 @@
/********************************************************************************
* Copyright (c) 2006, 2007 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
* 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,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
*
* Contributors:
* Yu-Fen Kuo (MontaVista) - adapted from RSE AbstractHostProcess
* Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
*******************************************************************************/
package org.eclipse.rse.internal.subsystems.processes.shell.linux;
import java.util.StringTokenizer;
import org.eclipse.rse.services.processes.AbstractHostProcess;
/**
* This class parses one line of the process record at a time and saves property
* value into it's member fields.
*
*/
public class LinuxHostProcess extends AbstractHostProcess {
private static String NAME = "Name"; //$NON-NLS-1$
private static String STATE = "State"; //$NON-NLS-1$
private static String TGID = "Tgid"; //$NON-NLS-1$
private static String PID = "Pid"; //$NON-NLS-1$
private static String PPID = "PPid"; //$NON-NLS-1$
private static String TRACERPID = "TracerPid"; //$NON-NLS-1$
private static String UID = "Uid"; //$NON-NLS-1$
private static String GID = "Gid"; //$NON-NLS-1$
private static String VMSIZE = "VmSize"; //$NON-NLS-1$
private static String VMRSS = "VmRSS"; //$NON-NLS-1$
private static String STATUS_DELIMITER = "|"; //$NON-NLS-1$
private LinuxProcessHelper linuxProcessHelper;
/**
* constructor
*
* @param linuxProcessHelper
*/
public LinuxHostProcess(LinuxProcessHelper linuxProcessHelper) {
super();
this.linuxProcessHelper = linuxProcessHelper;
}
/**
* process one line of process record and based on the property name, put
* the corresponding value in the right member field(s). The state value
* would get converted into state code before the value is saved.
*
* @param line
* one line of the process record
*/
public void processLine(String line) {
String[] result = line.split(":"); //$NON-NLS-1$
if (result.length < 2)
return;
String propertyName = result[0];
String propertyValue = result[1].trim();
if (NAME.equals(propertyName)) {
this.setName(propertyValue);
this.setLabel(propertyValue);
// initialize some of the properties
this.setVmSizeInKB("0"); //$NON-NLS-1$
this.setVmRSSInKB("0"); //$NON-NLS-1$
} else if (STATE.equals(propertyName)) {
String firstValue = getFirstValue(propertyValue);
if (firstValue != null)
this.setState(linuxProcessHelper
.convertToStateCode(propertyValue));
} else if (TGID.equals(propertyName)) {
this.setTgid(propertyValue);
} else if (PID.equals(propertyName)) {
this.setPid(propertyValue);
} else if (PPID.equals(propertyName)) {
this.setPPid(propertyValue);
} else if (TRACERPID.equals(propertyName)) {
this.setTracerPid(propertyValue);
} else if (TRACERPID.equals(propertyName)) {
this.setTracerPid(propertyValue);
} else if (UID.equals(propertyName)) {
String firstValue = getFirstValue(propertyValue);
if (firstValue != null) {
this.setUid(firstValue);
this.setUsername(linuxProcessHelper.getUsername(firstValue));
}
} else if (GID.equals(propertyName)) {
String firstValue = getFirstValue(propertyValue);
if (firstValue != null)
this.setGid(firstValue);
} else if (VMSIZE.equals(propertyName)) {
String firstValue = getFirstValue(propertyValue);
if (firstValue != null)
this.setVmSizeInKB(firstValue);
} else if (VMRSS.equals(propertyName)) {
String firstValue = getFirstValue(propertyValue);
if (firstValue != null)
this.setVmRSSInKB(firstValue);
}
}
/**
* checks if the line is a starting of a new process record New process
* record should start with Name: string
*
* @param line
* one line of process record
* @return true if is a new process record
*/
public static boolean isNewRecord(String line) {
String[] result = line.split(":"); //$NON-NLS-1$
if (result.length >= 2 && NAME.equals(result[0])) {
return true;
}
return false;
}
private String getFirstValue(String propertyValue) {
StringTokenizer st = new StringTokenizer(propertyValue);
if (st.hasMoreTokens()) {
return st.nextToken();
}
return null;
}
// "pid|name|status|tgid|ppid|tracerpid|uid|username|gid|vmSize|vmRSS"
/**
* format the property values in the format that IHostProcessFilter.allows()
* can use it to determine if this process record is allowed by the filter
* to be displayed to the user.
*
* @return formatted string in the following format:
* "pid|name|status|tgid|ppid|tracerpid|uid|username|gid|vmSize|vmRSS"
*/
public String getStatusLine() {
StringBuffer statusLine = new StringBuffer();
statusLine = statusLine.append(getPid()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getName()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getState()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getTgid()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getPPid()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getTracerPid()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getUid()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getUsername()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getGid()).append(STATUS_DELIMITER);
statusLine = statusLine.append(getVmSizeInKB())
.append(STATUS_DELIMITER);
statusLine = statusLine.append(getVmRSSInKB()).append(STATUS_DELIMITER);
return statusLine.toString();
}
}

View file

@ -0,0 +1,163 @@
/********************************************************************************
* Copyright (c) 2005, 2007 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
* 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,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
*
* Contributors:
* Yu-Fen Kuo (MontaVista) - adapted from RSE UniversalLinuxProcessHandler
* Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
*******************************************************************************/
package org.eclipse.rse.internal.subsystems.processes.shell.linux;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.rse.core.model.IHost;
import org.eclipse.rse.services.clientserver.processes.ISystemProcessRemoteConstants;
import org.eclipse.rse.services.shells.HostShellProcessAdapter;
import org.eclipse.rse.services.shells.IHostShell;
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 implements ISystemProcessRemoteConstants {
private HashMap stateMap;
private HashMap _usernamesByUid;
private HashMap _uidsByUserName;
private static String COMMAND_GET_PASSWD = "getent passwd"; //$NON-NLS-1$
/**
* constructor
*/
public LinuxProcessHelper() {
super();
stateMap = new HashMap();
for (int i = STATE_STARTING_INDEX; i < STATE_ENDING_INDEX; i++) {
stateMap.put(new Character(ALL_STATES[i]), ALL_STATES_STR[i]);
}
}
/**
* this code is adapted from
* org.eclipse.rse.services.clientserver.processes.handlers.UniversalLinuxProcessHandler
*/
public String convertToStateCode(String state) {
String stateCode = " "; //$NON-NLS-1$
if (state == null)
return stateCode;
if (state.trim().equals("")) //$NON-NLS-1$
return stateCode;
for (int i = 0; i < state.length(); i++) {
String nextState = (String) stateMap.get(new Character(state
.charAt(i)));
if (nextState != null) {
stateCode = stateCode + nextState;
if (i < state.length() - 1)
stateCode = stateCode + ","; //$NON-NLS-1$
}
}
if (stateCode.trim().equals("")) //$NON-NLS-1$
return " "; //$NON-NLS-1$
else
return stateCode.trim();
}
/**
* this code is adapted from
* org.eclipse.rse.services.clientserver.processes.handlers.UniversalLinuxProcessHandler
*/
public void populateUsernames(IHost host) {
if (_usernamesByUid != null && _uidsByUserName != null || host == null)
return;
_usernamesByUid = new HashMap();
_uidsByUserName = new HashMap();
IShellService shellService = Activator.getShellService(host);
IHostShell hostShell = shellService.launchShell(
new NullProgressMonitor(), "", null); //$NON-NLS-1$
hostShell.writeToShell(getUserNameCommand());
Process p = null;
try {
p = new HostShellProcessAdapter(hostShell);
// when p.waitFor() is called here, the hostShell.isActive() always
// return true.
// p.waitFor();
} catch (Exception e) {
Activator.log(e);
if (p != null) {
p.destroy();
}
return;
}
BufferedReader bufferReader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String nextLine;
try {
while ((nextLine = bufferReader.readLine()) != null
&& !nextLine.equals(Activator.DONE_MARKUP_STRING)) {
String[] fields = nextLine.split(":"); //$NON-NLS-1$
int length = fields.length;
if (length < 3)
continue;
String uid = fields[2];
String username = fields[0];
if (uid != null && username != null) {
_usernamesByUid.put(uid, username);
_uidsByUserName.put(username, uid);
}
}
bufferReader.close();
} catch (IOException e) {
Activator.log(e);
}
if (p.exitValue() != 0) {
String errMsg = Activator.getErrorMessage(p.getErrorStream());
if (!errMsg.trim().equals("")) { //$NON-NLS-1$
Activator.logErrorMessage(errMsg.toString());
}
}
}
/**
* Gets the uid associated with the given username on this system
*/
public String getUid(String username) {
if (_uidsByUserName != null)
return (String) _uidsByUserName.get(username);
return ""; //$NON-NLS-1$
}
/**
* Gets the username associated with the given uid on this system
*/
public String getUsername(String uid) {
String username = null;
if (_usernamesByUid != null)
username = (String) _usernamesByUid.get(uid);
if (username != null && !username.equals("")) //$NON-NLS-1$
return username;
return uid;
}
protected String getUserNameCommand() {
return Activator.formatShellCommand(COMMAND_GET_PASSWD);
}
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, 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:
* Martin Oberhuber (Wind River) - initial API and implementation
*******************************************************************************/
package org.eclipse.rse.internal.subsystems.processes.shell.linux;
import org.eclipse.osgi.util.NLS;
public class LinuxShellProcessResources extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.rse.internal.subsystems.processes.shell.linux.LinuxShellProcessResources"; //$NON-NLS-1$
public static String LinuxRemoteProcessService_name;
public static String LinuxRemoteProcessService_description;
public static String LinuxRemoteProcessService_monitor_fetchProcesses;
public static String LinuxRemoteProcessService_getSignalTypes_empty;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, LinuxShellProcessResources.class);
}
private LinuxShellProcessResources() {
}
}

View file

@ -0,0 +1,16 @@
################################################################################
# Copyright (c) 2006, 2007 MontaVista Software, 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:
# Yu-Fen Kuo (MontaVista) - initial API and implementation
# Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
################################################################################
LinuxRemoteProcessService_name=Shell Process Service
LinuxRemoteProcessService_description=listing processes on the remote target through a contributed shell service
LinuxRemoteProcessService_monitor_fetchProcesses=Fetching Remote Process Information...
LinuxRemoteProcessService_getSignalTypes_empty=Failed to retrieve signal types from remote target.

View file

@ -0,0 +1,282 @@
/*******************************************************************************
* Copyright (c) 2006, 2007 MontaVista Software, 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:
* Yu-Fen Kuo (MontaVista) - initial API and implementation
* Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
*******************************************************************************/
package org.eclipse.rse.internal.subsystems.processes.shell.linux;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.rse.core.model.IHost;
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
import org.eclipse.rse.services.clientserver.processes.IHostProcess;
import org.eclipse.rse.services.clientserver.processes.IHostProcessFilter;
import org.eclipse.rse.services.clientserver.processes.ISystemProcessRemoteConstants;
import org.eclipse.rse.services.processes.AbstractProcessService;
import org.eclipse.rse.services.shells.HostShellProcessAdapter;
import org.eclipse.rse.services.shells.IHostShell;
import org.eclipse.rse.services.shells.IShellService;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IShellServiceSubSystem;
/**
* class to fetch remote linux target's process info
*
*/
public class LinuxShellProcessService extends AbstractProcessService {
private static String COMMAND_GET_SIGNAL_TYPES = "kill -l"; //$NON-NLS-1$
private static String COMMAND_GET_PROCESSES = "cat /proc/[0-9]*/status"; //$NON-NLS-1$
private static String COMMAND_KILL_PROCESSES = "kill "; //$NON-NLS-1$
private String[] statusTypes;
private LinuxProcessHelper linuxProcessHelper;
private IHost host;
/**
* constructor
*
* @param host the connection to work on
*/
public LinuxShellProcessService(final IHost host) {
this.host = host;
}
public String[] getSignalTypes() {
if (statusTypes == null)
statusTypes = internalGetSignalTypes();
return statusTypes;
}
public boolean kill(final IProgressMonitor monitor, final long PID,
final String signal) throws SystemMessageException {
String signalString;
if (signal
.equals(ISystemProcessRemoteConstants.PROCESS_SIGNAL_TYPE_DEFAULT))
signalString = ""; //$NON-NLS-1$
else
signalString = "-" + signal; //$NON-NLS-1$
IShellService shellService = Activator.getShellService(host);
IHostShell hostShell = shellService.launchShell(
new NullProgressMonitor(), "", null); //$NON-NLS-1$
hostShell.writeToShell(getKillCommand(PID, signalString));
Process p = null;
try {
p = new HostShellProcessAdapter(hostShell);
// p.waitFor();
} catch (Exception e) {
e.printStackTrace();
if (p != null) {
p.destroy();
}
return false;
}
// if (p.exitValue() != 0) {
String errMsg = Activator.getErrorMessage(p.getErrorStream());
if (!errMsg.trim().equals("")) { //$NON-NLS-1$
Activator.logErrorMessage(errMsg.toString());
} else
return true;
// }
return false;
}
public IHostProcess[] listAllProcesses(final IProgressMonitor monitor,
final IHostProcessFilter filter) throws SystemMessageException {
// this is to workaround RSE bug 147531
if (filter.getUsername().equals("${user.id}") && host != null) { //$NON-NLS-1$
IShellServiceSubSystem ss = Activator.getShellServiceSubSystem(host);
if (ss!=null) {
// change filter username so the filter will filter out the right
// process for my processes
String connectionUserId=ss.getConnectorService().getUserId();
filter.setUsername(connectionUserId);
}
}
if (monitor != null) {
monitor.beginTask(
LinuxShellProcessResources.LinuxRemoteProcessService_monitor_fetchProcesses,
100);
}
IShellService shellService = Activator.getShellService(host);
IHostShell hostShell = shellService.launchShell(
new NullProgressMonitor(), "", null); //$NON-NLS-1$
hostShell.writeToShell(getProcessesCommand());
Process p = null;
try {
p = new HostShellProcessAdapter(hostShell);
// p.waitFor();
} catch (Exception e) {
e.printStackTrace();
if (p != null) {
p.destroy();
}
return null;
}
BufferedReader bufferReader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String nextLine;
LinuxHostProcess hostProcess = null;
final ArrayList hostProcessList = new ArrayList();
try {
while ((nextLine = bufferReader.readLine()) != null
&& !nextLine.equals(Activator.DONE_MARKUP_STRING)) {
if ((hostProcess == null)
|| LinuxHostProcess.isNewRecord(nextLine)) {
if (hostProcess != null) {
boolean allows = filter.allows(hostProcess
.getStatusLine());
if (allows)
hostProcessList.add(hostProcess);
}
hostProcess = new LinuxHostProcess(linuxProcessHelper);
}
hostProcess.processLine(nextLine);
if (progressWorked(monitor, 1)) {
break;
}
}
if (hostProcess != null) {
// add the last record if allows by filter
boolean allows = filter.allows(hostProcess.getStatusLine());
if (allows)
hostProcessList.add(hostProcess);
}
bufferReader.close();
} catch (IOException e) {
Activator.log(e);
}
if (p.exitValue() != 0) {
String errMsg = Activator.getErrorMessage(p.getErrorStream());
if (!errMsg.trim().equals("")) { //$NON-NLS-1$
Activator.logErrorMessage(errMsg.toString());
}
}
return (IHostProcess[]) hostProcessList
.toArray(new IHostProcess[hostProcessList.size()]);
}
public String getDescription() {
return LinuxShellProcessResources.LinuxRemoteProcessService_description;
}
public String getName() {
return LinuxShellProcessResources.LinuxRemoteProcessService_name;
}
public void initService(final IProgressMonitor monitor) {
linuxProcessHelper = new LinuxProcessHelper();
// initialize username /uid hashmap before getting any process
linuxProcessHelper.populateUsernames(host);
}
public void uninitService(final IProgressMonitor monitor) {
}
private boolean progressWorked(final IProgressMonitor monitor,
final int work) {
boolean cancelRequested = false;
if (monitor != null) {
monitor.worked(work);
cancelRequested = monitor.isCanceled();
}
return cancelRequested;
}
/**
* Returns a list of the signal types supported by the 'kill' command on
* this system. Signal Types will be used in the Kill dialog for user to
* choose which signal they want to use for killing a process.
*
* @return a list of the signal types or null if there are none or there is
* an error in executing the kill command.
*/
protected String[] internalGetSignalTypes() {
IShellService shellService = Activator.getShellService(host);
IHostShell hostShell = shellService.launchShell(
new NullProgressMonitor(), "", null); //$NON-NLS-1$
hostShell.writeToShell(getSignalTypesCommand());
Process p = null;
try {
p = new HostShellProcessAdapter(hostShell);
// p.waitFor();
} catch (Exception e) {
e.printStackTrace();
if (p != null) {
p.destroy();
}
return null;
}
BufferedReader bufferReader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
ArrayList lines = null;
try {
StringBuffer output = new StringBuffer();
while ((line = bufferReader.readLine()) != null
&& !line.equals(Activator.DONE_MARKUP_STRING)) {
output = output.append(line);
}
bufferReader.close();
if (output.length() > 0) {
StringTokenizer st = new StringTokenizer(output.toString());
lines = new ArrayList();
while (st.hasMoreTokens()) {
String token = st.nextToken().trim();
if (token.matches("([A-Z]*)")) { //$NON-NLS-1$
lines.add(token);
}
}
}
} catch (IOException e) {
Activator.log(e);
}
if (p.exitValue() != 0) {
String errMsg = Activator.getErrorMessage(p.getErrorStream());
if (!errMsg.toString().trim().equals("")) { //$NON-NLS-1$
Activator.logErrorMessage(errMsg.toString());
}
}
if (lines == null || lines.size() <= 0) {
Activator.logErrorMessage(LinuxShellProcessResources.LinuxRemoteProcessService_getSignalTypes_empty);
} else {
return (String[]) lines.toArray(new String[lines.size()]);
}
return null;
}
protected String getSignalTypesCommand() {
return Activator.formatShellCommand(COMMAND_GET_SIGNAL_TYPES);
}
protected String getProcessesCommand() {
return Activator.formatShellCommand(COMMAND_GET_PROCESSES);
}
protected String getKillCommand(final long PID, final String signalString) {
String cmdLine = COMMAND_KILL_PROCESSES + signalString + " " + PID; //$NON-NLS-1$
return Activator.formatShellCommand(cmdLine);
}
}

View file

@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright (c) 2006, 2007 MontaVista Software, 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:
* Yu-Fen Kuo (MontaVista) - initial API and implementation
* Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
*******************************************************************************/
package org.eclipse.rse.internal.subsystems.processes.shell.linux;
import java.util.ArrayList;
import org.eclipse.rse.services.clientserver.processes.IHostProcess;
import org.eclipse.rse.subsystems.processes.core.subsystem.IHostProcessToRemoteProcessAdapter;
import org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcess;
import org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcessContext;
import org.eclipse.rse.subsystems.processes.core.subsystem.impl.RemoteProcessImpl;
/**
* Utility class to convert host process records into remote process records
*
*/
public class ShellProcessAdapter implements IHostProcessToRemoteProcessAdapter {
/**
* Convert a set of IHostProcess objects to IRemoteProcess objects.
*
* @see org.eclipse.rse.subsystems.processes.core.subsystem.IHostProcessToRemoteProcessAdapter#convertToRemoteProcesses(org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcessContext,
* org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcess,
* org.eclipse.rse.services.clientserver.processes.IHostProcess[])
*/
public IRemoteProcess[] convertToRemoteProcesses(
final IRemoteProcessContext context, final IRemoteProcess parent,
final IHostProcess[] nodes) {
if (nodes == null)
return null;
final ArrayList list = new ArrayList(nodes.length);
for (int idx = 0; idx < nodes.length; idx++) {
final LinuxHostProcess node = (LinuxHostProcess) nodes[idx];
final IRemoteProcess newProcess = new RemoteProcessImpl(context,
node);
list.add(newProcess);
}
final IRemoteProcess[] processes = new IRemoteProcess[list.size()];
for (int idx = 0; idx < list.size(); idx++) {
processes[idx] = (IRemoteProcess) list.get(idx);
}
return processes;
}
/**
* Convert a single IHostProcess object to an IRemoteProcess object.
*
* @see org.eclipse.rse.subsystems.processes.core.subsystem.IHostProcessToRemoteProcessAdapter#convertToRemoteProcess(org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcessContext,
* org.eclipse.rse.subsystems.processes.core.subsystem.IRemoteProcess,
* org.eclipse.rse.services.clientserver.processes.IHostProcess)
*/
public IRemoteProcess convertToRemoteProcess(
final IRemoteProcessContext context, final IRemoteProcess parent,
final IHostProcess node) {
final IHostProcess[] nodes = new IHostProcess[1];
nodes[0] = node;
final IRemoteProcess[] processes = convertToRemoteProcesses(context,
parent, nodes);
if (processes != null && processes.length > 0)
return processes[0];
else
return null;
}
}

View file

@ -0,0 +1,77 @@
/********************************************************************************
* Copyright (c) 2006, 2007 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
* 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,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
*
* Contributors:
* Yu-Fen Kuo (MontaVista) - adapted from RSE ProcessServiceSubSystemConfiguration
* Martin Oberhuber (Wind River) - [refactor] "shell" instead of "ssh" everywhere
*******************************************************************************/
package org.eclipse.rse.subsystems.processes.shell.linux;
import org.eclipse.rse.core.model.IHost;
import org.eclipse.rse.core.subsystems.IConnectorService;
import org.eclipse.rse.core.subsystems.ISubSystem;
import org.eclipse.rse.internal.subsystems.processes.shell.linux.Activator;
import org.eclipse.rse.internal.subsystems.processes.shell.linux.LinuxShellProcessService;
import org.eclipse.rse.internal.subsystems.processes.shell.linux.ShellProcessAdapter;
import org.eclipse.rse.services.processes.IProcessService;
import org.eclipse.rse.services.shells.IShellService;
import org.eclipse.rse.subsystems.processes.core.subsystem.IHostProcessToRemoteProcessAdapter;
import org.eclipse.rse.subsystems.processes.servicesubsystem.ProcessServiceSubSystem;
import org.eclipse.rse.subsystems.processes.servicesubsystem.ProcessServiceSubSystemConfiguration;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IShellServiceSubSystem;
/**
* This class is used by org.eclipse.rse.ui.subsystemConfigurations extension
* that defines the process subsystem using ssh protocol on linux remote
* targets.
*
*/
public class ShellProcessSubSystemConfiguration extends
ProcessServiceSubSystemConfiguration {
protected IHostProcessToRemoteProcessAdapter hostProcessAdapter;
public ISubSystem createSubSystemInternal(IHost conn) {
IConnectorService connectorService = getConnectorService(conn);
ISubSystem subsys = new ProcessServiceSubSystem(conn, connectorService,
getProcessService(conn), getHostProcessAdapter());
return subsys;
}
public IHostProcessToRemoteProcessAdapter getHostProcessAdapter() {
if (hostProcessAdapter == null) {
hostProcessAdapter = new ShellProcessAdapter();
}
return hostProcessAdapter;
}
public IConnectorService getConnectorService(IHost host) {
IShellServiceSubSystem ss = Activator.getShellServiceSubSystem(host);
if (ss!=null) {
return ss.getConnectorService();
}
return null;
}
public Class getServiceImplType() {
return IShellService.class;
}
public void setConnectorService(IHost host, IConnectorService connectorService) {
//Nothing to do here since we just re-use the existing IShellServiceSubSystem
}
public IProcessService createProcessService(IHost host) {
return new LinuxShellProcessService(host);
}
}

View file

@ -0,0 +1,31 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="Martin Oberhuber (Wind River)">
<title>Package-level Javadoc</title>
</head>
<body>
Application programming interface for creating customized shell process subsystems.
<h2>
Package Specification</h2>
The package provides support classes for creating customized shell process
subsystems.
<p>The class <b>ShellProcessSubSystemConfiguration</b> is the main factory
for creating a shell process subsystem: a process subsystem that gathers
its data by running commands on a remote system through a shell subsystem
that's registered against the same host. By deriving from it, extenders
can create their customized shell process subsystem configuration which can
then be registered against their system types. A custom
<b>SubSystemConfigurationAdapter</b> can be registered for UI-specific
customizations. Possible customizations include:
<ul>
<li>Changing the isCaseSensitive() method for system types that
are not of UNIX style.</li>
<li>Registering pre-defined filters through a filter pool manager.</li>
<li>Wrapping the created ProcessServiceSubSystem or LinuxShellProcessService
in a delegate for modifying operation of the Subsystem.</li>
</ul>
</p>
</body>
</html>