debuggercdi/com.nokia.cdt.debug.launch/src/com/nokia/cdt/internal/debug/launch/EmulationLaunchDelegate.java
author Ed Swartz <ed.swartz@nokia.com>
Wed, 21 Apr 2010 15:10:34 -0500
changeset 1260 f3b387a17eb7
parent 94 d74b720418db
permissions -rw-r--r--
Merge PlatSim changes from 2.x, but move ILaunchDelegateConnectionExtension into com.nokia.cdt.debug.common so EDC can use it
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
cawthron
parents:
diff changeset
     1
/*
cawthron
parents:
diff changeset
     2
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
cawthron
parents:
diff changeset
     3
* All rights reserved.
cawthron
parents:
diff changeset
     4
* This component and the accompanying materials are made available
cawthron
parents:
diff changeset
     5
* under the terms of the License "Eclipse Public License v1.0"
cawthron
parents:
diff changeset
     6
* which accompanies this distribution, and is available
cawthron
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
cawthron
parents:
diff changeset
     8
*
cawthron
parents:
diff changeset
     9
* Initial Contributors:
cawthron
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
cawthron
parents:
diff changeset
    11
*
cawthron
parents:
diff changeset
    12
* Contributors:
cawthron
parents:
diff changeset
    13
*
cawthron
parents:
diff changeset
    14
* Description: 
cawthron
parents:
diff changeset
    15
*
cawthron
parents:
diff changeset
    16
*/
cawthron
parents:
diff changeset
    17
package com.nokia.cdt.internal.debug.launch;
cawthron
parents:
diff changeset
    18
cawthron
parents:
diff changeset
    19
import java.io.BufferedInputStream;
cawthron
parents:
diff changeset
    20
import java.io.File;
cawthron
parents:
diff changeset
    21
import java.io.FileNotFoundException;
cawthron
parents:
diff changeset
    22
import java.io.IOException;
cawthron
parents:
diff changeset
    23
import java.io.InputStream;
cawthron
parents:
diff changeset
    24
import java.io.OutputStream;
cawthron
parents:
diff changeset
    25
import java.io.RandomAccessFile;
cawthron
parents:
diff changeset
    26
import java.util.ArrayList;
cawthron
parents:
diff changeset
    27
import java.util.Arrays;
cawthron
parents:
diff changeset
    28
cawthron
parents:
diff changeset
    29
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
cawthron
parents:
diff changeset
    30
import org.eclipse.cdt.core.model.ICProject;
cawthron
parents:
diff changeset
    31
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
cawthron
parents:
diff changeset
    32
import org.eclipse.cdt.debug.core.ICDebugConfiguration;
cawthron
parents:
diff changeset
    33
import org.eclipse.cdt.debug.core.cdi.ICDISession;
cawthron
parents:
diff changeset
    34
import org.eclipse.cdt.launch.internal.ui.LaunchMessages;
cawthron
parents:
diff changeset
    35
import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin;
cawthron
parents:
diff changeset
    36
import org.eclipse.cdt.utils.pty.PTY;
cawthron
parents:
diff changeset
    37
import org.eclipse.cdt.utils.spawner.EnvironmentReader;
cawthron
parents:
diff changeset
    38
import org.eclipse.cdt.utils.spawner.ProcessFactory;
cawthron
parents:
diff changeset
    39
import org.eclipse.core.runtime.CoreException;
cawthron
parents:
diff changeset
    40
import org.eclipse.core.runtime.IPath;
cawthron
parents:
diff changeset
    41
import org.eclipse.core.runtime.IProgressMonitor;
cawthron
parents:
diff changeset
    42
import org.eclipse.core.runtime.IStatus;
cawthron
parents:
diff changeset
    43
import org.eclipse.core.runtime.NullProgressMonitor;
cawthron
parents:
diff changeset
    44
import org.eclipse.core.runtime.Path;
cawthron
parents:
diff changeset
    45
import org.eclipse.core.runtime.Status;
cawthron
parents:
diff changeset
    46
import org.eclipse.core.runtime.SubProgressMonitor;
cawthron
parents:
diff changeset
    47
import org.eclipse.debug.core.DebugPlugin;
cawthron
parents:
diff changeset
    48
import org.eclipse.debug.core.ILaunch;
cawthron
parents:
diff changeset
    49
import org.eclipse.debug.core.ILaunchConfiguration;
cawthron
parents:
diff changeset
    50
import org.eclipse.debug.core.ILaunchManager;
cawthron
parents:
diff changeset
    51
import org.eclipse.debug.core.IStatusHandler;
cawthron
parents:
diff changeset
    52
import org.eclipse.debug.core.model.IProcess;
cawthron
parents:
diff changeset
    53
import org.eclipse.ui.console.ConsolePlugin;
cawthron
parents:
diff changeset
    54
import org.eclipse.ui.console.IConsole;
cawthron
parents:
diff changeset
    55
import org.eclipse.ui.console.IOConsoleOutputStream;
cawthron
parents:
diff changeset
    56
cawthron
parents:
diff changeset
    57
import com.freescale.cdt.debug.cw.DebuggerLog;
cawthron
parents:
diff changeset
    58
import com.freescale.cdt.debug.cw.core.cdi.ISessionListener;
cawthron
parents:
diff changeset
    59
import com.freescale.cdt.debug.cw.core.cdi.Session;
94
d74b720418db Test framework support: Ask debugger to remember DebugTarget so test framework can use it to setup test framework related utility. With this we can use the DebugUI way of launching while keeping test framework functionality
tzelaw
parents: 2
diff changeset
    60
import com.freescale.cdt.debug.cw.core.cdi.model.Target;
2
cawthron
parents:
diff changeset
    61
import com.freescale.cdt.debug.cw.core.settings.DebuggerCommonData;
cawthron
parents:
diff changeset
    62
import com.freescale.cdt.debug.cw.core.ui.console.LoggingConsole;
cawthron
parents:
diff changeset
    63
import com.nokia.cdt.debug.cw.symbian.SettingsData;
cawthron
parents:
diff changeset
    64
import com.nokia.cdt.debug.cw.symbian.SymbianPlugin;
cawthron
parents:
diff changeset
    65
cawthron
parents:
diff changeset
    66
import cwdbg.PreferenceConstants;
cawthron
parents:
diff changeset
    67
cawthron
parents:
diff changeset
    68
public class EmulationLaunchDelegate extends NokiaAbstractLaunchDelegate {
cawthron
parents:
diff changeset
    69
cawthron
parents:
diff changeset
    70
	private IPath verifyHostApp(ILaunchConfiguration config) throws CoreException {
cawthron
parents:
diff changeset
    71
		String hostApp = config.getAttribute(DebuggerCommonData.Host_App_Path, (String)null);
cawthron
parents:
diff changeset
    72
		if (hostApp.length() > 0)
cawthron
parents:
diff changeset
    73
		{
cawthron
parents:
diff changeset
    74
			Path hostAppPath = new Path(hostApp);
cawthron
parents:
diff changeset
    75
			if (hostAppPath == null || hostAppPath.isEmpty()) {
cawthron
parents:
diff changeset
    76
				return null;
cawthron
parents:
diff changeset
    77
			}
cawthron
parents:
diff changeset
    78
			if (!hostAppPath.toFile().exists()) {
cawthron
parents:
diff changeset
    79
				abort(
cawthron
parents:
diff changeset
    80
						"File does not exist",
cawthron
parents:
diff changeset
    81
						new FileNotFoundException(
cawthron
parents:
diff changeset
    82
								LaunchMessages.getFormattedString(
cawthron
parents:
diff changeset
    83
																	"AbstractCLaunchDelegate.PROGRAM_PATH_not_found", hostAppPath.toOSString())), //$NON-NLS-1$
cawthron
parents:
diff changeset
    84
						ICDTLaunchConfigurationConstants.ERR_PROGRAM_NOT_EXIST);
cawthron
parents:
diff changeset
    85
			}
cawthron
parents:
diff changeset
    86
			return hostAppPath;
cawthron
parents:
diff changeset
    87
		}
cawthron
parents:
diff changeset
    88
		return null;
cawthron
parents:
diff changeset
    89
	}
cawthron
parents:
diff changeset
    90
cawthron
parents:
diff changeset
    91
	public void launch(
cawthron
parents:
diff changeset
    92
			ILaunchConfiguration 	config, 
cawthron
parents:
diff changeset
    93
			String 					mode, 
cawthron
parents:
diff changeset
    94
			ILaunch 				launch, 
cawthron
parents:
diff changeset
    95
			IProgressMonitor monitor) throws CoreException 
cawthron
parents:
diff changeset
    96
	{
cawthron
parents:
diff changeset
    97
	// See comment at definition of the "mutex" for why this "synchronized".		
cawthron
parents:
diff changeset
    98
	synchronized(Session.sessionStartStopMutex()) {
cawthron
parents:
diff changeset
    99
cawthron
parents:
diff changeset
   100
		if (monitor == null) {
cawthron
parents:
diff changeset
   101
			monitor = new NullProgressMonitor();
cawthron
parents:
diff changeset
   102
		}
cawthron
parents:
diff changeset
   103
		
cawthron
parents:
diff changeset
   104
		monitor.beginTask(LaunchMessages.getString("LocalRunLaunchDelegate.Launching_Local_C_Application"), 10); //$NON-NLS-1$
cawthron
parents:
diff changeset
   105
		// check for cancellation
cawthron
parents:
diff changeset
   106
		if (monitor.isCanceled()) {
cawthron
parents:
diff changeset
   107
			return;
cawthron
parents:
diff changeset
   108
		}
cawthron
parents:
diff changeset
   109
		try {
cawthron
parents:
diff changeset
   110
        	addBeingLaunched(config); // indicating the LC is being launched
cawthron
parents:
diff changeset
   111
        	
cawthron
parents:
diff changeset
   112
			monitor.worked(1);
cawthron
parents:
diff changeset
   113
			IPath exePath = verifyProgramPath(config);
cawthron
parents:
diff changeset
   114
			ICProject project = verifyCProject(config);
cawthron
parents:
diff changeset
   115
			IBinaryObject exeFile = verifyBinary(project, exePath);
cawthron
parents:
diff changeset
   116
			String arguments[] = getProgramArgumentsArray(config);
cawthron
parents:
diff changeset
   117
			verifyHostApp(config);
cawthron
parents:
diff changeset
   118
cawthron
parents:
diff changeset
   119
			// See comment for this method for more.
cawthron
parents:
diff changeset
   120
            SettingsData.setInternalPreferences(config, SettingsData.LaunchConfig_Emulator);
cawthron
parents:
diff changeset
   121
            			
cawthron
parents:
diff changeset
   122
			// set the default source locator if required
cawthron
parents:
diff changeset
   123
			setDefaultSourceLocator(launch, config);
cawthron
parents:
diff changeset
   124
cawthron
parents:
diff changeset
   125
			if (mode.equals(ILaunchManager.DEBUG_MODE)) {
cawthron
parents:
diff changeset
   126
				// debug mode
cawthron
parents:
diff changeset
   127
				ICDebugConfiguration debugConfig = getDebugConfig(config);
cawthron
parents:
diff changeset
   128
				ICDISession dsession = null;
cawthron
parents:
diff changeset
   129
				String debugMode = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE,
cawthron
parents:
diff changeset
   130
						ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN);
cawthron
parents:
diff changeset
   131
				if (debugMode.equals(ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN)) {
cawthron
parents:
diff changeset
   132
					dsession = debugConfig.createDebugger().createDebuggerSession(launch, exeFile,
cawthron
parents:
diff changeset
   133
							new SubProgressMonitor(monitor, 8));
cawthron
parents:
diff changeset
   134
cawthron
parents:
diff changeset
   135
					assert(dsession instanceof Session);
cawthron
parents:
diff changeset
   136
					Session cwDebugSession = (Session)dsession;
cawthron
parents:
diff changeset
   137
cawthron
parents:
diff changeset
   138
					doAdditionalSessionSetup(cwDebugSession);
cawthron
parents:
diff changeset
   139
					
cawthron
parents:
diff changeset
   140
					IPath[] otherExecutables = getOtherExecutables(project, exePath, config, monitor);
cawthron
parents:
diff changeset
   141
					{
cawthron
parents:
diff changeset
   142
						try {
cawthron
parents:
diff changeset
   143
							monitor.worked(1);
cawthron
parents:
diff changeset
   144
							
cawthron
parents:
diff changeset
   145
							// if enabled in the prefs, show the console view(s)
cawthron
parents:
diff changeset
   146
							if (config.getAttribute(PreferenceConstants.J_PN_ViewSystemMessage, false)) {
cawthron
parents:
diff changeset
   147
								SymbianPlugin.getDefault().openSystemConsole(true);
cawthron
parents:
diff changeset
   148
							}
cawthron
parents:
diff changeset
   149
cawthron
parents:
diff changeset
   150
							if (config.getAttribute(PreferenceConstants.J_PN_ViewProcessOutput, false)) {
cawthron
parents:
diff changeset
   151
								SymbianPlugin.getDefault().openDebugConsole(true);
cawthron
parents:
diff changeset
   152
							}
cawthron
parents:
diff changeset
   153
cawthron
parents:
diff changeset
   154
							if (config.getAttribute(SymbianPlugin.DebugTraceLaunchSetting, false)) {
cawthron
parents:
diff changeset
   155
								openDebugTraceConsole(cwDebugSession);
cawthron
parents:
diff changeset
   156
							}
cawthron
parents:
diff changeset
   157
cawthron
parents:
diff changeset
   158
							config = synchronizeWithProjectAccessPaths(project, config);
cawthron
parents:
diff changeset
   159
							
cawthron
parents:
diff changeset
   160
							File wd = getWorkingDirectory(config);
cawthron
parents:
diff changeset
   161
							long t = System.currentTimeMillis();
94
d74b720418db Test framework support: Ask debugger to remember DebugTarget so test framework can use it to setup test framework related utility. With this we can use the DebugUI way of launching while keeping test framework functionality
tzelaw
parents: 2
diff changeset
   162
							Target target = cwDebugSession.launchExecutable(launch, config, exeFile, otherExecutables, arguments, wd, getEnvironmentAsProperty(config), monitor, project, renderTargetLabel(debugConfig), true);
d74b720418db Test framework support: Ask debugger to remember DebugTarget so test framework can use it to setup test framework related utility. With this we can use the DebugUI way of launching while keeping test framework functionality
tzelaw
parents: 2
diff changeset
   163
							ATFLaunchSupport.saveDebugTargetFromLaunchDelegate(target.getCoreModelTarget());
2
cawthron
parents:
diff changeset
   164
							t = System.currentTimeMillis() - t;
cawthron
parents:
diff changeset
   165
//							System.out.println("launchExecutable returns in : " + t);
cawthron
parents:
diff changeset
   166
							DebuggerLog.log("launchExecutable returns in : " + t);
cawthron
parents:
diff changeset
   167
						} catch (CoreException e) {
cawthron
parents:
diff changeset
   168
							Session session = (Session)dsession;
cawthron
parents:
diff changeset
   169
							session.cleanupAfterLaunchFailure();
cawthron
parents:
diff changeset
   170
							throw e;
cawthron
parents:
diff changeset
   171
						} catch (Exception e) {
cawthron
parents:
diff changeset
   172
							Session session = (Session)dsession;
cawthron
parents:
diff changeset
   173
							session.debuggingStopped(null);
cawthron
parents:
diff changeset
   174
							this.abort(e.getLocalizedMessage(), null, 0);
cawthron
parents:
diff changeset
   175
						}
cawthron
parents:
diff changeset
   176
					}
cawthron
parents:
diff changeset
   177
				}
cawthron
parents:
diff changeset
   178
			} else if (mode.equals(ILaunchManager.RUN_MODE)) {
cawthron
parents:
diff changeset
   179
				// run mode
cawthron
parents:
diff changeset
   180
				File wd = getWorkingDirectory(config);
cawthron
parents:
diff changeset
   181
				if (wd == null) {
cawthron
parents:
diff changeset
   182
					wd = new File(System.getProperty("user.home", ".")); //$NON-NLS-1$ //$NON-NLS-2$
cawthron
parents:
diff changeset
   183
				}
cawthron
parents:
diff changeset
   184
				ArrayList<String> command = new ArrayList<String>(1 + arguments.length);
cawthron
parents:
diff changeset
   185
cawthron
parents:
diff changeset
   186
		    	// run the host app if specified 
cawthron
parents:
diff changeset
   187
		    	String hostAppPath = config.getAttribute(DebuggerCommonData.Host_App_Path, ""); //$NON-NLS-1$
cawthron
parents:
diff changeset
   188
		    	if (hostAppPath.length() > 0)
cawthron
parents:
diff changeset
   189
			    	command.add(hostAppPath);
cawthron
parents:
diff changeset
   190
		    	else
cawthron
parents:
diff changeset
   191
			    	command.add(exePath.toOSString());
cawthron
parents:
diff changeset
   192
		    	
cawthron
parents:
diff changeset
   193
				command.addAll(Arrays.asList(arguments));
cawthron
parents:
diff changeset
   194
				String[] commandArray = (String[]) command.toArray(new String[command.size()]);
cawthron
parents:
diff changeset
   195
				boolean usePty = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL,
cawthron
parents:
diff changeset
   196
						ICDTLaunchConfigurationConstants.USE_TERMINAL_DEFAULT);
cawthron
parents:
diff changeset
   197
				monitor.worked(5);
cawthron
parents:
diff changeset
   198
				Process process = exec(commandArray, getEnvironment(config), wd, usePty);
cawthron
parents:
diff changeset
   199
				monitor.worked(3);
cawthron
parents:
diff changeset
   200
				IProcess proc = DebugPlugin.newProcess(launch, process, renderProcessLabel(commandArray[0]));
cawthron
parents:
diff changeset
   201
				
cawthron
parents:
diff changeset
   202
				// set the command line attribute so it shows up in the process
cawthron
parents:
diff changeset
   203
				// information property page
cawthron
parents:
diff changeset
   204
				String cmdLine = ""; //$NON-NLS-1$
cawthron
parents:
diff changeset
   205
				for (int i=0; i<commandArray.length; i++) {
cawthron
parents:
diff changeset
   206
					cmdLine += commandArray[i];
cawthron
parents:
diff changeset
   207
					if (i != commandArray.length - 1) {
cawthron
parents:
diff changeset
   208
						cmdLine += " "; //$NON-NLS-1$
cawthron
parents:
diff changeset
   209
					}
cawthron
parents:
diff changeset
   210
				}
cawthron
parents:
diff changeset
   211
				proc.setAttribute(IProcess.ATTR_CMDLINE, cmdLine);
cawthron
parents:
diff changeset
   212
			}
cawthron
parents:
diff changeset
   213
		} catch (CoreException e) {
cawthron
parents:
diff changeset
   214
        	if (! monitor.isCanceled()) // don't throw on user cancellation
cawthron
parents:
diff changeset
   215
        		throw e;
cawthron
parents:
diff changeset
   216
		} finally {
cawthron
parents:
diff changeset
   217
			monitor.done();
cawthron
parents:
diff changeset
   218
            removeBeingLaunched(config);
cawthron
parents:
diff changeset
   219
		}
cawthron
parents:
diff changeset
   220
		}	// end of synchronized
cawthron
parents:
diff changeset
   221
	}
cawthron
parents:
diff changeset
   222
cawthron
parents:
diff changeset
   223
	/**
cawthron
parents:
diff changeset
   224
	 * Performs a runtime exec on the given command line in the context of the
cawthron
parents:
diff changeset
   225
	 * specified working directory, and returns the resulting process. If the
cawthron
parents:
diff changeset
   226
	 * current runtime does not support the specification of a working
cawthron
parents:
diff changeset
   227
	 * directory, the status handler for error code
cawthron
parents:
diff changeset
   228
	 * <code>ERR_WORKING_DIRECTORY_NOT_SUPPORTED</code> is queried to see if
cawthron
parents:
diff changeset
   229
	 * the exec should be re-executed without specifying a working directory.
cawthron
parents:
diff changeset
   230
	 * 
cawthron
parents:
diff changeset
   231
	 * @param cmdLine
cawthron
parents:
diff changeset
   232
	 *            the command line
cawthron
parents:
diff changeset
   233
	 * @param workingDirectory
cawthron
parents:
diff changeset
   234
	 *            the working directory, or <code>null</code>
cawthron
parents:
diff changeset
   235
	 * @return the resulting process or <code>null</code> if the exec is
cawthron
parents:
diff changeset
   236
	 *         cancelled
cawthron
parents:
diff changeset
   237
	 * @see Runtime
cawthron
parents:
diff changeset
   238
	 */
cawthron
parents:
diff changeset
   239
	protected Process exec(String[] cmdLine, String[] environ, File workingDirectory, boolean usePty)
cawthron
parents:
diff changeset
   240
			throws CoreException {
cawthron
parents:
diff changeset
   241
		Process p = null;
cawthron
parents:
diff changeset
   242
		try {
cawthron
parents:
diff changeset
   243
			if (workingDirectory == null) {
cawthron
parents:
diff changeset
   244
				p = ProcessFactory.getFactory().exec(cmdLine, environ);
cawthron
parents:
diff changeset
   245
			} else {
cawthron
parents:
diff changeset
   246
				if (usePty && PTY.isSupported()) {
cawthron
parents:
diff changeset
   247
					p = ProcessFactory.getFactory().exec(cmdLine, environ, workingDirectory, new PTY());
cawthron
parents:
diff changeset
   248
				} else {
cawthron
parents:
diff changeset
   249
					p = ProcessFactory.getFactory().exec(cmdLine, environ, workingDirectory);
cawthron
parents:
diff changeset
   250
				}
cawthron
parents:
diff changeset
   251
			}
cawthron
parents:
diff changeset
   252
		} catch (IOException e) {
cawthron
parents:
diff changeset
   253
			if (p != null) {
cawthron
parents:
diff changeset
   254
				p.destroy();
cawthron
parents:
diff changeset
   255
			}
cawthron
parents:
diff changeset
   256
			abort(LaunchMessages.getString("LocalRunLaunchDelegate.Error_starting_process"), e, //$NON-NLS-1$
cawthron
parents:
diff changeset
   257
					ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR);
cawthron
parents:
diff changeset
   258
		} catch (NoSuchMethodError e) {
cawthron
parents:
diff changeset
   259
			//attempting launches on 1.2.* - no ability to set working
cawthron
parents:
diff changeset
   260
			// directory
cawthron
parents:
diff changeset
   261
cawthron
parents:
diff changeset
   262
			IStatus status = new Status(IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(),
cawthron
parents:
diff changeset
   263
					ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages
cawthron
parents:
diff changeset
   264
							.getString("LocalRunLaunchDelegate.Does_not_support_working_dir"), //$NON-NLS-1$
cawthron
parents:
diff changeset
   265
					e);
cawthron
parents:
diff changeset
   266
			IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(status);
cawthron
parents:
diff changeset
   267
cawthron
parents:
diff changeset
   268
			if (handler != null) {
cawthron
parents:
diff changeset
   269
				Object result = handler.handleStatus(status, this);
cawthron
parents:
diff changeset
   270
				if (result instanceof Boolean && ((Boolean) result).booleanValue()) {
cawthron
parents:
diff changeset
   271
					p = exec(cmdLine, environ, null, usePty);
cawthron
parents:
diff changeset
   272
				}
cawthron
parents:
diff changeset
   273
			}
cawthron
parents:
diff changeset
   274
		}
cawthron
parents:
diff changeset
   275
		return p;
cawthron
parents:
diff changeset
   276
	}
cawthron
parents:
diff changeset
   277
	
cawthron
parents:
diff changeset
   278
	@Override
cawthron
parents:
diff changeset
   279
	protected String getCPUString() {
cawthron
parents:
diff changeset
   280
		return "x86"; //$NON-NLS-1$
cawthron
parents:
diff changeset
   281
	}
cawthron
parents:
diff changeset
   282
cawthron
parents:
diff changeset
   283
	/**
cawthron
parents:
diff changeset
   284
	 * Input stream at the tail of a file, used to capture the contents of the epocwind.out file.
cawthron
parents:
diff changeset
   285
	 */
cawthron
parents:
diff changeset
   286
	public class FileTailInputStream extends InputStream {
cawthron
parents:
diff changeset
   287
cawthron
parents:
diff changeset
   288
		private RandomAccessFile file;
cawthron
parents:
diff changeset
   289
		private long tail;
cawthron
parents:
diff changeset
   290
cawthron
parents:
diff changeset
   291
		public FileTailInputStream(File file) throws IOException {
cawthron
parents:
diff changeset
   292
			super();
cawthron
parents:
diff changeset
   293
			this.file = new RandomAccessFile(file, "r"); //$NON-NLS-1$
cawthron
parents:
diff changeset
   294
			
cawthron
parents:
diff changeset
   295
			// save the original file length when the input stream is created
cawthron
parents:
diff changeset
   296
			tail = file.length();
cawthron
parents:
diff changeset
   297
cawthron
parents:
diff changeset
   298
			// start at the tail of the file
cawthron
parents:
diff changeset
   299
			this.file.seek(tail);
cawthron
parents:
diff changeset
   300
		}
cawthron
parents:
diff changeset
   301
		
cawthron
parents:
diff changeset
   302
		public int read() throws IOException {
cawthron
parents:
diff changeset
   303
			checkTail();
cawthron
parents:
diff changeset
   304
			byte[] b = new byte[1];
cawthron
parents:
diff changeset
   305
			int len = file.read(b, 0, 1);
cawthron
parents:
diff changeset
   306
			if (len < 0) {
cawthron
parents:
diff changeset
   307
				return len;
cawthron
parents:
diff changeset
   308
			}
cawthron
parents:
diff changeset
   309
			return b[0];
cawthron
parents:
diff changeset
   310
		}
cawthron
parents:
diff changeset
   311
cawthron
parents:
diff changeset
   312
		public int read(byte[] b) throws IOException {
cawthron
parents:
diff changeset
   313
			checkTail();
cawthron
parents:
diff changeset
   314
			return file.read(b, 0, b.length);
cawthron
parents:
diff changeset
   315
		}
cawthron
parents:
diff changeset
   316
cawthron
parents:
diff changeset
   317
		public int read(byte[] b, int off, int len) throws IOException {
cawthron
parents:
diff changeset
   318
			checkTail();
cawthron
parents:
diff changeset
   319
			return file.read(b, off, len);
cawthron
parents:
diff changeset
   320
		}
cawthron
parents:
diff changeset
   321
cawthron
parents:
diff changeset
   322
		public void close() throws IOException {
cawthron
parents:
diff changeset
   323
			file.close();
cawthron
parents:
diff changeset
   324
		}
cawthron
parents:
diff changeset
   325
cawthron
parents:
diff changeset
   326
		private void checkTail() throws IOException {
cawthron
parents:
diff changeset
   327
			// this checks to see if the file was cleared at
cawthron
parents:
diff changeset
   328
			// some point after we created the input stream.  if
cawthron
parents:
diff changeset
   329
			// so we want to start at the beginning of the file.
cawthron
parents:
diff changeset
   330
			if (file.length() < tail) {
cawthron
parents:
diff changeset
   331
				tail = 0;
cawthron
parents:
diff changeset
   332
				file.seek(0);
cawthron
parents:
diff changeset
   333
			}
cawthron
parents:
diff changeset
   334
		}
cawthron
parents:
diff changeset
   335
	}
cawthron
parents:
diff changeset
   336
cawthron
parents:
diff changeset
   337
	// file monitoring thread
cawthron
parents:
diff changeset
   338
	class ReadThread extends Thread implements Runnable, ISessionListener {
cawthron
parents:
diff changeset
   339
		
cawthron
parents:
diff changeset
   340
		private InputStream in = null;
cawthron
parents:
diff changeset
   341
		private OutputStream out = null;
cawthron
parents:
diff changeset
   342
		private boolean keepListening = true;
cawthron
parents:
diff changeset
   343
cawthron
parents:
diff changeset
   344
		public ReadThread(InputStream in, OutputStream out) {
cawthron
parents:
diff changeset
   345
			this.in = in;
cawthron
parents:
diff changeset
   346
			this.out = out;
cawthron
parents:
diff changeset
   347
			setName("epocwind monitor thread"); //$NON-NLS-1$
cawthron
parents:
diff changeset
   348
		}
cawthron
parents:
diff changeset
   349
		
cawthron
parents:
diff changeset
   350
		public void run() {
cawthron
parents:
diff changeset
   351
			
cawthron
parents:
diff changeset
   352
			byte[] buffer = new byte[1024];
cawthron
parents:
diff changeset
   353
			
cawthron
parents:
diff changeset
   354
			try {
cawthron
parents:
diff changeset
   355
				while (keepListening) {
cawthron
parents:
diff changeset
   356
					int bytesRead = in.read(buffer);
cawthron
parents:
diff changeset
   357
					if (bytesRead > 0) {
cawthron
parents:
diff changeset
   358
						out.write(buffer, 0, bytesRead);
cawthron
parents:
diff changeset
   359
					}
cawthron
parents:
diff changeset
   360
					
cawthron
parents:
diff changeset
   361
					try {
cawthron
parents:
diff changeset
   362
						Thread.sleep(20);
cawthron
parents:
diff changeset
   363
					} catch (InterruptedException e) {
cawthron
parents:
diff changeset
   364
					}
cawthron
parents:
diff changeset
   365
				}
cawthron
parents:
diff changeset
   366
			} catch (IOException e) {
cawthron
parents:
diff changeset
   367
				LaunchUIPlugin.log(e);
cawthron
parents:
diff changeset
   368
			} finally {
cawthron
parents:
diff changeset
   369
				// close the input stream (the file).  leave the output stream open
cawthron
parents:
diff changeset
   370
				// for future debug sessions.
cawthron
parents:
diff changeset
   371
				try {
cawthron
parents:
diff changeset
   372
					in.close();
cawthron
parents:
diff changeset
   373
				} catch (IOException e) {
cawthron
parents:
diff changeset
   374
				}
cawthron
parents:
diff changeset
   375
			}
cawthron
parents:
diff changeset
   376
		}
cawthron
parents:
diff changeset
   377
cawthron
parents:
diff changeset
   378
		public void sessionEnded() {
cawthron
parents:
diff changeset
   379
			keepListening = false;
cawthron
parents:
diff changeset
   380
		}
cawthron
parents:
diff changeset
   381
	}
cawthron
parents:
diff changeset
   382
cawthron
parents:
diff changeset
   383
	public void openDebugTraceConsole(Session session) {
cawthron
parents:
diff changeset
   384
		final String consoleName = SymbianPlugin.DebugTraceMessagesConsoleName;
cawthron
parents:
diff changeset
   385
		
cawthron
parents:
diff changeset
   386
		// add it if necessary
cawthron
parents:
diff changeset
   387
		LoggingConsole console = null;
cawthron
parents:
diff changeset
   388
		boolean found = false;
cawthron
parents:
diff changeset
   389
cawthron
parents:
diff changeset
   390
		IConsole[] consoles = ConsolePlugin.getDefault().getConsoleManager().getConsoles();
cawthron
parents:
diff changeset
   391
		for (int i=0; i<consoles.length; i++) {
cawthron
parents:
diff changeset
   392
			if (consoleName.equals(consoles[i].getName())) {
cawthron
parents:
diff changeset
   393
				console = (LoggingConsole)consoles[i];
cawthron
parents:
diff changeset
   394
				found = true;
cawthron
parents:
diff changeset
   395
				break;
cawthron
parents:
diff changeset
   396
			}
cawthron
parents:
diff changeset
   397
		}
cawthron
parents:
diff changeset
   398
				
cawthron
parents:
diff changeset
   399
		if (!found) {
cawthron
parents:
diff changeset
   400
        	console = new LoggingConsole(consoleName);
cawthron
parents:
diff changeset
   401
        	ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[]{console});			
cawthron
parents:
diff changeset
   402
		}
cawthron
parents:
diff changeset
   403
cawthron
parents:
diff changeset
   404
		ConsolePlugin.getDefault().getConsoleManager().showConsoleView(console);
cawthron
parents:
diff changeset
   405
		
cawthron
parents:
diff changeset
   406
		// clear the console and get an output stream for it
cawthron
parents:
diff changeset
   407
		console.clearConsole();
cawthron
parents:
diff changeset
   408
		IOConsoleOutputStream consoleOut = console.getLoggingStream();
cawthron
parents:
diff changeset
   409
		
cawthron
parents:
diff changeset
   410
		// locate the file
cawthron
parents:
diff changeset
   411
		File traceFile = null;
cawthron
parents:
diff changeset
   412
		String value = EnvironmentReader.getEnvVar("TEMP"); //$NON-NLS-1$
cawthron
parents:
diff changeset
   413
		if (value != null) {
cawthron
parents:
diff changeset
   414
			try {
cawthron
parents:
diff changeset
   415
				traceFile = new File(value + "\\epocwind.out").getCanonicalFile(); //$NON-NLS-1$
cawthron
parents:
diff changeset
   416
			} catch (IOException e) {
cawthron
parents:
diff changeset
   417
				e.printStackTrace();
cawthron
parents:
diff changeset
   418
			}
cawthron
parents:
diff changeset
   419
		}
cawthron
parents:
diff changeset
   420
cawthron
parents:
diff changeset
   421
		if (traceFile != null) {
cawthron
parents:
diff changeset
   422
			// create it if it doesn't already exist.  the emulator would create it but
cawthron
parents:
diff changeset
   423
			// hasn't been launched yet and we need to create an input stream from the file now.
cawthron
parents:
diff changeset
   424
			if (!traceFile.exists()) {
cawthron
parents:
diff changeset
   425
				try {
cawthron
parents:
diff changeset
   426
					traceFile.createNewFile();
cawthron
parents:
diff changeset
   427
				} catch (IOException e) {
cawthron
parents:
diff changeset
   428
					e.printStackTrace();
cawthron
parents:
diff changeset
   429
				}
cawthron
parents:
diff changeset
   430
			}
cawthron
parents:
diff changeset
   431
			
cawthron
parents:
diff changeset
   432
			try {
cawthron
parents:
diff changeset
   433
				// create the monitor thread and kick it off
cawthron
parents:
diff changeset
   434
				FileTailInputStream inputStream = new FileTailInputStream(traceFile);
cawthron
parents:
diff changeset
   435
				ReadThread rt = new ReadThread(new BufferedInputStream(inputStream), consoleOut);
cawthron
parents:
diff changeset
   436
				session.addListener(rt);
cawthron
parents:
diff changeset
   437
				rt.start();
cawthron
parents:
diff changeset
   438
			} catch (IOException e) {
cawthron
parents:
diff changeset
   439
			}
cawthron
parents:
diff changeset
   440
		} else {
cawthron
parents:
diff changeset
   441
			try {
cawthron
parents:
diff changeset
   442
				consoleOut.write("Unable to open %TEMP%\\epocwind.out"); //$NON-NLS-1$
cawthron
parents:
diff changeset
   443
				consoleOut.close();
cawthron
parents:
diff changeset
   444
			} catch (IOException e) {
cawthron
parents:
diff changeset
   445
				e.printStackTrace();
cawthron
parents:
diff changeset
   446
			}
cawthron
parents:
diff changeset
   447
		}
cawthron
parents:
diff changeset
   448
	}
cawthron
parents:
diff changeset
   449
}