2 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include <QtCore/QFile>
25 #include <QtCore/QMap>
26 #include <QtCore/QString>
27 #include <QtCore/QVector>
33 * Takes a snapshot of the state of a process and provides access to
34 * information such as the process name, parent process,
35 * the foreground process in the controlling terminal,
36 * the arguments with which the process was started and the
39 * To create a new snapshot, construct a new ProcessInfo instance,
40 * using ProcessInfo::newInstance(),
41 * passing the process identifier of the process you are interested in.
43 * After creating a new instance, call the update() method to take a
44 * snapshot of the current state of the process.
46 * Before calling any additional methods, check that the process state
47 * was read successfully using the isValid() method.
49 * Each accessor method which provides information about the process state ( such as pid(),
50 * currentDir(), name() ) takes a pointer to a boolean as an argument. If the information
51 * requested was read successfully then the boolean is set to true, otherwise it is set
52 * to false, in which case the return value from the function should be ignored.
53 * If this boolean is set to false, it may indicate an error reading the process information,
54 * or it may indicate that the information is not available on the current platform.
59 * ProcessInfo* info = ProcessInfo::newInstance(pid);
62 * if ( info->isValid() )
65 * QString value = info->name(&ok);
67 * if ( ok ) kDebug() << "process name - " << name;
68 * int parentPid = info->parentPid(&ok);
69 * if ( ok ) kDebug() << "parent process - " << parentPid;
70 * int foregroundPid = info->foregroundColororegroundPid(&ok);
71 * if ( ok ) kDebug() << "foreground process - " << foregroundPid;
79 * Constructs a new instance of a suitable ProcessInfo sub-class for
80 * the current platform which provides information about a given process.
82 * @param pid The pid of the process to examine
83 * @param readEnvironment Specifies whether environment bindings should
84 * be read. If this is false, then environment() calls will
85 * always fail. This is an optimization to avoid the overhead
86 * of reading the (potentially large) environment data when it
89 static ProcessInfo
* newInstance(int pid
,bool readEnvironment
= false);
91 virtual ~ProcessInfo() {}
94 * Updates the information about the process. This must
95 * be called before attempting to use any of the accessor methods.
99 /** Returns true if the process state was read successfully. */
100 bool isValid() const;
102 * Returns the process id.
104 * @param ok Set to true if the process id was read successfully or false otherwise
106 int pid(bool* ok
) const;
108 * Returns the id of the parent process id was read successfully or false otherwise
110 * @param ok Set to true if the parent process id
112 int parentPid(bool* ok
) const;
115 * Returns the id of the current foreground process
117 * NOTE: Using the foregroundProcessGroup() method of the Pty
118 * instance associated with the terminal of interest is preferred
119 * over using this method.
121 * @param ok Set to true if the foreground process id was read successfully or false otherwise
123 int foregroundPid(bool* ok
) const;
125 /** Returns the name of the current process */
126 QString
name(bool* ok
) const;
129 * Returns the command-line arguments which the process
132 * The first argument is the name used to launch the process.
134 * @param ok Set to true if the arguments were read successfully or false otherwise.
136 QVector
<QString
> arguments(bool* ok
) const;
138 * Returns the environment bindings which the process
140 * In the returned map, the key is the name of the environment variable,
141 * and the value is the corresponding value.
143 * @param ok Set to true if the environment bindings were read successfully or false otherwise
145 QMap
<QString
,QString
> environment(bool* ok
) const;
148 * Returns the current working directory of the process
150 * @param ok Set to true if the current working directory was read successfully or false otherwise
152 QString
currentDir(bool* ok
) const;
155 * Returns the current working directory of the process (or its parent)
157 QString
validCurrentDir() const;
160 * Parses an input string, looking for markers beginning with a '%'
161 * character and returns a string with the markers replaced
162 * with information from this process description.
164 * The markers recognised are:
166 * <li> %u - Name of the user which owns the process. </li>
167 * <li> %n - Replaced with the name of the process. </li>
168 * <li> %d - Replaced with the last part of the path name of the
169 * process' current working directory.
171 * (eg. if the current directory is '/home/bob' then
172 * 'bob' would be returned)
174 * <li> %D - Replaced with the current working directory of the process. </li>
177 QString
format(const QString
& text
) const;
180 * This enum describes the errors which can occur when trying to read
181 * a process's information.
185 /** No error occurred. */
187 /** The nature of the error is unknown. */
189 /** Konsole does not have permission to obtain the process information. */
194 * Returns the last error which occurred.
200 * Constructs a new process instance. You should not call the constructor
201 * of ProcessInfo or its subclasses directly. Instead use the
202 * static ProcessInfo::newInstance() method which will return
203 * a suitable ProcessInfo instance for the current platform.
205 explicit ProcessInfo(int pid
, bool readEnvironment
= false);
208 * This is called on construction to read the process state
209 * Subclasses should reimplement this function to provide
210 * platform-specific process state reading functionality.
212 * When called, readProcessInfo() should attempt to read all
213 * of the necessary state information. If the attempt is successful,
214 * it should set the process id using setPid(), and update
215 * the other relevant information using setParentPid(), setName(),
216 * setArguments() etc.
218 * Calls to isValid() will return true only if the process id
219 * has been set using setPid()
221 * @param pid The process id of the process to read
222 * @param readEnvironment Specifies whether the environment bindings
223 * for the process should be read
225 virtual bool readProcessInfo(int pid
, bool readEnvironment
) = 0;
227 /** Sets the process id associated with this ProcessInfo instance */
228 void setPid(int pid
);
229 /** Sets the parent process id as returned by parentPid() */
230 void setParentPid(int pid
);
231 /** Sets the foreground process id as returend by foregroundPid() */
232 void setForegroundPid(int pid
);
233 /** Sets the name of the process as returned by name() */
234 void setName(const QString
& name
);
235 /** Sets the current working directory for the process */
236 void setCurrentDir(const QString
& dir
);
238 /** Sets the error */
239 void setError( Error error
);
241 /** Convenience method. Sets the error based on a QFile error code. */
242 void setFileError( QFile::FileError error
);
245 * Adds a commandline argument for the process, as returned
248 void addArgument(const QString
& argument
);
250 * Adds an environment binding for the process, as returned by
253 * @param name The name of the environment variable, eg. "PATH"
254 * @param value The value of the environment variable, eg. "/bin"
256 void addEnvironmentBinding(const QString
& name
, const QString
& value
);
259 // takes a full directory path and returns a
260 // shortened version suitable for display in
261 // space-constrained UI elements (eg. tabs)
262 QString
formatShortDir(const QString
& dirPath
) const;
269 // takes a process name and its arguments and produces formatted output
270 QString
formatCommand(const QString
& name
, const QVector
<QString
>& arguments
,
271 CommandFormat format
) const;
273 // valid bits for _fields variable, ensure that
274 // _fields is changed to an int if more than 8 fields are added
286 char _fields
; // a bitmap indicating which fields are valid
287 // used to set the "ok" parameters for the public
288 // accessor functions
290 bool _enableEnvironmentRead
; // specifies whether to read the environment
291 // bindings when update() is called
301 QVector
<QString
> _arguments
;
302 QMap
<QString
,QString
> _environment
;
304 static QSet
<QString
> commonDirNames();
305 static QSet
<QString
> _commonDirNames
;
309 * Implementation of ProcessInfo which does nothing.
310 * Used on platforms where a suitable ProcessInfo subclass is not
313 * isValid() will always return false for instances of NullProcessInfo
315 class NullProcessInfo
: public ProcessInfo
319 * Constructs a new NullProcessInfo instance.
320 * See ProcessInfo::newInstance()
322 explicit NullProcessInfo(int pid
,bool readEnvironment
= false);
324 virtual bool readProcessInfo(int pid
,bool readEnvironment
);
328 * Implementation of ProcessInfo for Unix platforms which uses
329 * the /proc filesystem
331 class UnixProcessInfo
: public ProcessInfo
335 * Constructs a new instance of UnixProcessInfo.
336 * See ProcessInfo::newInstance()
338 explicit UnixProcessInfo(int pid
,bool readEnvironment
= false);
342 * Implementation of ProcessInfo::readProcessInfo(); calls the
343 * four private methods below in turn.
345 virtual bool readProcessInfo(int pid
, bool readEnvironment
);
349 * Read the standard process information -- PID, parent PID, foreground PID.
350 * @param pid process ID to use
351 * @return true on success
353 virtual bool readProcInfo(int pid
)=0;
356 * Read the environment of the process. Sets _environment.
357 * @param pid process ID to use
358 * @return true on success
360 virtual bool readEnvironment(int pid
)=0;
363 * Determine what arguments were passed to the process. Sets _arguments.
364 * @param pid process ID to use
365 * @return true on success
367 virtual bool readArguments(int pid
)=0;
370 * Determine the current directory of the process.
371 * @param pid process ID to use
372 * @return true on success
374 virtual bool readCurrentDir(int pid
)=0;
378 * Lightweight class which provides additional information about SSH processes.
384 * Constructs a new SSHProcessInfo instance which provides additional
385 * information about the specified SSH process.
387 * @param process A ProcessInfo instance for a SSH process.
389 SSHProcessInfo(const ProcessInfo
& process
);
392 * Returns the user name which the user initially logged into on
393 * the remote computer.
395 QString
userName() const;
398 * Returns the host which the user has connected to.
400 QString
host() const;
403 * Returns the command which the user specified to execute on the
404 * remote computer when starting the SSH process.
406 QString
command() const;
409 * Operates in the same way as ProcessInfo::format(), except
410 * that the set of markers understood is different:
412 * %u - Replaced with user name which the user initially logged
413 * into on the remote computer.
414 * %h - Replaced with the first part of the host name which
416 * %H - Replaced with the full host name of the computer which
418 * %c - Replaced with the command which the user specified
419 * to execute when starting the SSH process.
421 QString
format(const QString
& input
) const;
424 const ProcessInfo
& _process
;
431 #endif //PROCESSINFO_H
436 c-file-style: "stroustrup"
437 indent-tabs-mode: nil