Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: db08fbba065b24e986e7e34854abd27ca52a19f5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*******************************************************************************
 * Copyright (c) 2008 Red Hat, Inc.
 * 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:
 *    Elliott Baron <ebaron@redhat.com> - initial API and implementation
 *    Alena Laskavaia - javadoc comments and cleanup
 *******************************************************************************/
package org.eclipse.linuxtools.internal.valgrind.core;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.eclipse.cdt.utils.pty.PTY;
import org.eclipse.core.resources.IProject;
import org.eclipse.linuxtools.tools.launch.core.factory.CdtSpawnerProcessFactory;
import org.eclipse.linuxtools.tools.launch.core.factory.RuntimeProcessFactory;
import org.eclipse.linuxtools.valgrind.core.CommandLineConstants;

/**
 * Helper class to run valgrind
 */
public class ValgrindCommand {
    protected static final String WHICH_CMD = "which"; //$NON-NLS-1$
    protected static final String VALGRIND_CMD = "valgrind"; //$NON-NLS-1$

    protected Process process;
    protected String[] args;

    /**
     * The valgrind executable name
     * @return command line name
     */
    public String getValgrindCommand() {
        return VALGRIND_CMD;
    }

    /**
     * Attempt to local valgrind version
     * @param project - project to get execution context
     * @return version or emptry string if execution failed
     * @throws IOException if failed to create a process
     */
	public String whichVersion(IProject project) throws IOException {
		Process p = RuntimeProcessFactory.getFactory()
				.exec(new String[] { getValgrindCommand(), CommandLineConstants.OPT_VERSION }, project);
		try {
			StringBuffer out = new StringBuffer();
			readIntoBuffer(out, p);
			return out.toString().trim();
		} catch (IOException e) {
			e.printStackTrace(); // TODO fix
		}
		return ""; //$NON-NLS-1$
	}

    /**
     * Execute command
     * @param commandArray - command line arguments, first argument is executable itelv
     * @param env - environment variables
     * @param wd - working directory
     * @param usePty - option to allocate pty or not
     * @param project - project in context of which to launch the process
     * @throws IOException - if cannot execute the command
     */
    public void execute(String[] commandArray, String[] env, File wd, boolean usePty, IProject project) throws IOException {
        args = commandArray;
        try {
            process = startProcess(commandArray, env, wd, usePty, project);
        } catch (IOException e) {
            if (process != null) {
                process.destroy();
            }
            throw e;
        }
    }

    /**
     * Get current process
     * @return process
     */
    public Process getProcess() {
        return process;
    }

    /**
     * Get current valgrind command line, not escaped
     * @return process
     */
    public String getCommandLine() {
        StringBuffer ret = new StringBuffer();
        for (String arg : args) {
            ret.append(arg).append(" "); //$NON-NLS-1$
        }
        return ret.toString().trim();
    }

    private Process startProcess(String[] commandArray, String[] env, File workDir, boolean usePty, IProject project) throws IOException {
        if (workDir == null) {
            return CdtSpawnerProcessFactory.getFactory().exec(commandArray, env, project);
        }
        if (PTY.isSupported() && usePty) {
            return CdtSpawnerProcessFactory.getFactory().exec(commandArray, env, workDir, new PTY(), project);
        } else {
            return CdtSpawnerProcessFactory.getFactory().exec(commandArray, env, workDir, project);
        }
    }

	private void readIntoBuffer(StringBuffer out, Process p) throws IOException {
		if (p == null) {
			throw new IOException("Null Process object: unabled to read input into buffer"); //$NON-NLS-1$
		}
		// We need to get the inputs before calling waitFor
		try (InputStream err = p.getErrorStream(); InputStream input = p.getInputStream()) {
			boolean success = (p.waitFor() == 0);
			InputStream in;
			if (success) {
				in = input;
			} else {
				in = err;
			}
			int ch;
			while ((ch = in.read()) != -1) {
				out.append((char) ch); // TODO fix reading char by char ??
			}
			if (!success) {
				throw new IOException(out.toString());
			}
		} catch (InterruptedException e) {
			e.printStackTrace(); // TODO fix
		} finally {
			p.getOutputStream().close();
		}
	}
}

Back to the top