File indexing completed on 2024-04-14 05:44:11

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef PROCESSINFO_H
0008 #define PROCESSINFO_H
0009 
0010 // Qt
0011 #include <QFile>
0012 #include <QString>
0013 #include <QVector>
0014 
0015 #include "konsoleprivate_export.h"
0016 
0017 namespace Konsole
0018 {
0019 /**
0020  * Takes a snapshot of the state of a process and provides access to
0021  * information such as the process name, parent process,
0022  * the foreground process in the controlling terminal,
0023  * the arguments with which the process was started.
0024  *
0025  * To create a new snapshot, construct a new ProcessInfo instance,
0026  * using ProcessInfo::newInstance(),
0027  * passing the process identifier of the process you are interested in.
0028  *
0029  * After creating a new instance, call the update() method to take a
0030  * snapshot of the current state of the process.
0031  *
0032  * Before calling any additional methods, check that the process state
0033  * was read successfully using the isValid() method.
0034  *
0035  * Each accessor method which provides information about the process state ( such as pid(),
0036  * currentDir(), name() ) takes a pointer to a boolean as an argument.  If the information
0037  * requested was read successfully then the boolean is set to true, otherwise it is set
0038  * to false, in which case the return value from the function should be ignored.
0039  * If this boolean is set to false, it may indicate an error reading the process information,
0040  * or it may indicate that the information is not available on the current platform.
0041  *
0042  * eg.
0043  *
0044  * @code
0045  *   ProcessInfo* info = ProcessInfo::newInstance(pid);
0046  *   info->update();
0047  *
0048  *   if ( info->isValid() )
0049  *   {
0050  *      bool ok;
0051  *
0052  *      QString name = info->name(&ok);
0053  *      if ( ok ) qDebug() << "process name - " << name;
0054  *      int parentPid = info->parentPid(&ok);
0055  *      if ( ok ) qDebug() << "parent process - " << parentPid;
0056  *      int foregroundPid = info->foregroundPid(&ok);
0057  *      if ( ok ) qDebug() << "foreground process - " << foregroundPid;
0058  *   }
0059  * @endcode
0060  */
0061 class KONSOLEPRIVATE_EXPORT ProcessInfo
0062 {
0063 public:
0064     /**
0065      * Constructs a new instance of a suitable ProcessInfo sub-class for
0066      * the current platform which provides information about a given process.
0067      *
0068      * @param pid The pid of the process to examine
0069      * @param sessionPid -1 if examined process is session process,
0070      *      else will be pid of session process of the tab housing examined process
0071      */
0072     static ProcessInfo *newInstance(int pid, int sessionPid = -1);
0073 
0074     virtual ~ProcessInfo()
0075     {
0076     }
0077 
0078     /**
0079      * Updates the information about the process.  This must
0080      * be called before attempting to use any of the accessor methods.
0081      */
0082     void update();
0083 
0084     /**
0085      * Reads the most recent arguments passed to the process.
0086      */
0087     void refreshArguments();
0088 
0089     /** Returns true if the process state was read successfully. */
0090     bool isValid() const;
0091     /**
0092      * Returns the process id.
0093      *
0094      * @param ok Set to true if the process id was read successfully or false otherwise
0095      */
0096     int pid(bool *ok) const;
0097     /**
0098      * Returns the id of the parent process id was read successfully or false otherwise
0099      *
0100      * @param ok Set to true if the parent process id
0101      */
0102     int parentPid(bool *ok) const;
0103 
0104     /**
0105      * Returns the id of the current foreground process
0106      *
0107      * NOTE:  Using the foregroundProcessGroup() method of the Pty
0108      * instance associated with the terminal of interest is preferred
0109      * over using this method.
0110      *
0111      * @param ok Set to true if the foreground process id was read successfully or false otherwise
0112      */
0113     int foregroundPid(bool *ok) const;
0114 
0115     /* Returns the user id of the process */
0116     int userId(bool *ok) const;
0117 
0118     /** Returns the user's name of the process */
0119     QString userName() const;
0120 
0121     /** Returns the user's home directory of the process */
0122     QString userHomeDir() const;
0123 
0124     /** Returns the local host */
0125     static QString localHost();
0126 
0127     /** Returns the name of the current process */
0128     QString name(bool *ok) const;
0129 
0130     /**
0131      * Returns the command-line arguments which the process
0132      * was started with.
0133      *
0134      * The first argument is the name used to launch the process.
0135      *
0136      * @param ok Set to true if the arguments were read successfully or false otherwise.
0137      */
0138     QVector<QString> arguments(bool *ok) const;
0139 
0140     /**
0141      * Returns the current working directory of the process
0142      *
0143      * @param ok Set to true if the current working directory was read successfully or false otherwise
0144      */
0145     QString currentDir(bool *ok) const;
0146 
0147     /**
0148      * Returns the current working directory of the process (or its parent)
0149      */
0150     QString validCurrentDir() const;
0151 
0152     /** Forces the user home directory to be calculated */
0153     void setUserHomeDir();
0154 
0155     /**
0156      * This enum describes the errors which can occur when trying to read
0157      * a process's information.
0158      */
0159     enum Error {
0160         /** No error occurred. */
0161         NoError,
0162         /** The nature of the error is unknown. */
0163         UnknownError,
0164         /** Konsole does not have permission to obtain the process information. */
0165         PermissionsError,
0166     };
0167 
0168     /**
0169      * Returns the last error which occurred.
0170      */
0171     Error error() const;
0172 
0173     enum Field {
0174         PROCESS_ID = 1,
0175         PARENT_PID = 2,
0176         FOREGROUND_PID = 4,
0177         ARGUMENTS = 8,
0178         NAME = 16,
0179         CURRENT_DIR = 32,
0180         UID = 64,
0181     };
0182     Q_DECLARE_FLAGS(Fields, Field)
0183 
0184     // takes a full directory path and returns a
0185     // shortened version suitable for display in
0186     // space-constrained UI elements (eg. tabs)
0187     QString formatShortDir(const QString &dirPath) const;
0188 
0189     void setUserNameRequired(bool need);
0190 
0191 protected:
0192     /**
0193      * Constructs a new process instance.  You should not call the constructor
0194      * of ProcessInfo or its subclasses directly.  Instead use the
0195      * static ProcessInfo::newInstance() method which will return
0196      * a suitable ProcessInfo instance for the current platform.
0197      */
0198     explicit ProcessInfo(int pid);
0199 
0200     /**
0201      * This is called on construction to read the process state
0202      * Subclasses should reimplement this function to provide
0203      * platform-specific process state reading functionality.
0204      *
0205      * When called, readProcessInfo() should attempt to read all
0206      * of the necessary state information.  If the attempt is successful,
0207      * it should set the process id using setPid(), and update
0208      * the other relevant information using setParentPid(), setName(),
0209      * setArguments() etc.
0210      *
0211      * Calls to isValid() will return true only if the process id
0212      * has been set using setPid()
0213      *
0214      * @param pid The process id of the process to read
0215      */
0216     virtual void readProcessInfo(int pid) = 0;
0217 
0218     /**
0219      * Only reads and updates the name of the process
0220      * @param pid process ID to use
0221      * @return true on success
0222      */
0223     virtual bool readProcessName(int pid) = 0;
0224 
0225     /**
0226      * Determine the current directory of the process.
0227      * @param pid process ID to use
0228      * @return true on success
0229      */
0230     virtual bool readCurrentDir(int pid) = 0;
0231 
0232     /**
0233      * Determine what arguments were passed to the process.
0234      * Sets _arguments.
0235      * @param pid process ID to use
0236      * @return true on success
0237      */
0238     virtual bool readArguments(int pid) = 0;
0239 
0240     /* Read the user name */
0241     virtual void readUserName(void) = 0;
0242 
0243     /** Sets the process id associated with this ProcessInfo instance */
0244     void setPid(int pid);
0245     /** Sets the parent process id as returned by parentPid() */
0246     void setParentPid(int pid);
0247     /** Sets the foreground process id as returned by foregroundPid() */
0248     void setForegroundPid(int pid);
0249     /** Sets the user id associated with this ProcessInfo instance */
0250     void setUserId(int uid);
0251     /** Sets the user name of the process as set by readUserName() */
0252     void setUserName(const QString &name);
0253     /** Sets the name of the process as returned by name() */
0254     void setName(const QString &name);
0255     /** Sets the current working directory for the process */
0256     void setCurrentDir(const QString &dir);
0257 
0258     /** Sets the error */
0259     void setError(Error error);
0260 
0261     /** Convenience method.  Sets the error based on a QFile error code. */
0262     void setFileError(QFile::FileError error);
0263 
0264     /**
0265      * Adds a commandline argument for the process, as returned
0266      * by arguments()
0267      */
0268     void addArgument(const QString &argument);
0269 
0270     /**
0271      * clear the commandline arguments for the process, as returned
0272      * by arguments()
0273      */
0274     void clearArguments();
0275 
0276     bool userNameRequired() const;
0277 
0278 private:
0279     Fields _fields;
0280 
0281     int _pid;
0282     int _parentPid;
0283     int _foregroundPid;
0284     int _userId;
0285 
0286     Error _lastError;
0287 
0288     QString _name;
0289     QString _userName;
0290     QString _userHomeDir;
0291     QString _currentDir;
0292 
0293     bool _userNameRequired;
0294 
0295     QVector<QString> _arguments;
0296 
0297     static QStringList commonDirNames();
0298     static QStringList _commonDirNames;
0299 };
0300 Q_DECLARE_OPERATORS_FOR_FLAGS(ProcessInfo::Fields)
0301 
0302 }
0303 
0304 #endif // PROCESSINFO_H