File indexing completed on 2024-04-21 05:51:27
0001 /* 0002 SPDX-FileCopyrightText: 2007-2008 Robert Knight <robertknight@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 // Own 0008 #include "UnixProcessInfo.h" 0009 0010 #ifndef Q_OS_WIN 0011 // Unix 0012 #include <arpa/inet.h> 0013 #include <cerrno> 0014 #include <netinet/in.h> 0015 #include <pwd.h> 0016 #include <sys/param.h> 0017 #include <sys/socket.h> 0018 #include <unistd.h> 0019 0020 // Qt 0021 #include <QDebug> 0022 #include <QtGlobal> 0023 0024 #if defined(Q_OS_FREEBSD) || defined(Q_OS_OPEN_BSD) || defined(Q_OS_MACOS) 0025 #include <QSharedPointer> 0026 #include <sys/sysctl.h> 0027 #endif 0028 0029 using namespace Konsole; 0030 0031 UnixProcessInfo::UnixProcessInfo(int pid) 0032 : ProcessInfo(pid) 0033 { 0034 setUserNameRequired(true); 0035 } 0036 0037 void UnixProcessInfo::readProcessInfo(int pid) 0038 { 0039 // prevent _arguments from growing longer and longer each time this 0040 // method is called. 0041 clearArguments(); 0042 0043 if (readProcInfo(pid)) { 0044 readArguments(pid); 0045 readCurrentDir(pid); 0046 0047 bool ok = false; 0048 const QString &processNameString = name(&ok); 0049 0050 if (ok && processNameString == QLatin1String("sudo")) { 0051 // Append process name along with sudo 0052 const QVector<QString> &args = arguments(&ok); 0053 0054 if (ok && args.size() > 1) { 0055 setName(processNameString + QStringLiteral(" ") + args[1]); 0056 } 0057 } 0058 } 0059 } 0060 0061 void UnixProcessInfo::readUserName() 0062 { 0063 bool ok = false; 0064 const int uid = userId(&ok); 0065 if (!ok) { 0066 return; 0067 } 0068 0069 struct passwd passwdStruct; 0070 struct passwd *getpwResult; 0071 char *getpwBuffer; 0072 long getpwBufferSize; 0073 int getpwStatus; 0074 0075 getpwBufferSize = sysconf(_SC_GETPW_R_SIZE_MAX); 0076 if (getpwBufferSize == -1) { 0077 getpwBufferSize = 16384; 0078 } 0079 0080 getpwBuffer = new char[getpwBufferSize]; 0081 if (getpwBuffer == nullptr) { 0082 return; 0083 } 0084 getpwStatus = getpwuid_r(uid, &passwdStruct, getpwBuffer, getpwBufferSize, &getpwResult); 0085 if ((getpwStatus == 0) && (getpwResult != nullptr)) { 0086 setUserName(QLatin1String(passwdStruct.pw_name)); 0087 } else { 0088 setUserName(QString()); 0089 qWarning() << "getpwuid_r returned error : " << getpwStatus; 0090 } 0091 delete[] getpwBuffer; 0092 } 0093 0094 bool UnixProcessInfo::readArguments(int pid) 0095 { 0096 // used for LinuxProcessInfo and SolarisProcessInfo 0097 // read command-line arguments file found at /proc/<pid>/cmdline 0098 // the expected format is a list of strings delimited by null characters, 0099 // and ending in a double null character pair. 0100 0101 QFile argumentsFile(QStringLiteral("/proc/%1/cmdline").arg(pid)); 0102 if (argumentsFile.open(QIODevice::ReadOnly)) { 0103 QTextStream stream(&argumentsFile); 0104 const QString &data = stream.readAll(); 0105 0106 const QStringList &argList = data.split(QLatin1Char('\0')); 0107 0108 for (const QString &entry : argList) { 0109 if (!entry.isEmpty()) { 0110 addArgument(entry); 0111 } 0112 } 0113 } else { 0114 setFileError(argumentsFile.error()); 0115 } 0116 0117 return true; 0118 } 0119 0120 #if defined(Q_OS_FREEBSD) || defined(Q_OS_OPEN_BSD) || defined(Q_OS_MACOS) 0121 QSharedPointer<struct kinfo_proc> UnixProcessInfo::getProcInfoStruct(int *managementInfoBase, int mibCount) 0122 { 0123 size_t structLength; 0124 0125 if (::sysctl(managementInfoBase, mibCount, NULL, &structLength, NULL, 0) == -1) { 0126 qWarning() << "first sysctl() call failed with code " << errno; 0127 return nullptr; 0128 } 0129 0130 QSharedPointer<struct kinfo_proc> kInfoProc(new struct kinfo_proc[structLength]); 0131 0132 if (::sysctl(managementInfoBase, mibCount, kInfoProc.get(), &structLength, NULL, 0) == -1) { 0133 qWarning() << "second sysctl() call failed with code " << errno; 0134 return nullptr; 0135 } 0136 0137 return kInfoProc; 0138 } 0139 #endif 0140 0141 #endif // Q_OS_WIN