diff --git a/src/ProcessInfo.cpp b/src/ProcessInfo.cpp index b3c02c76f..6a5ac2db0 100644 --- a/src/ProcessInfo.cpp +++ b/src/ProcessInfo.cpp @@ -97,7 +97,7 @@ void ProcessInfo::setError(Error error) void ProcessInfo::update() { - readProcessInfo(_pid); + readCurrentDir(_pid); } QString ProcessInfo::validCurrentDir() const @@ -360,6 +360,11 @@ bool NullProcessInfo::readProcessInfo(int /*pid*/) return false; } +bool NullProcessInfo::readCurrentDir(int /*pid*/) +{ + return false; +} + void NullProcessInfo::readUserName() { } @@ -423,6 +428,24 @@ public: UnixProcessInfo(aPid, titleFormat) { } +protected: + virtual bool readCurrentDir(int aPid) { + char path_buffer[MAXPATHLEN + 1]; + path_buffer[MAXPATHLEN] = 0; + QByteArray procCwd = QFile::encodeName(QStringLiteral("/proc/%1/cwd").arg(aPid)); + const int length = readlink(procCwd.constData(), path_buffer, MAXPATHLEN); + if (length == -1) { + setError(UnknownError); + return false; + } + + path_buffer[length] = '\0'; + QString path = QFile::decodeName(path_buffer); + + setCurrentDir(path); + return true; + } + private: virtual bool readProcInfo(int aPid) { // indicies of various fields within the process status file which @@ -559,23 +582,6 @@ private: return true; } - - virtual bool readCurrentDir(int aPid) { - char path_buffer[MAXPATHLEN + 1]; - path_buffer[MAXPATHLEN] = 0; - QByteArray procCwd = QFile::encodeName(QStringLiteral("/proc/%1/cwd").arg(aPid)); - const int length = readlink(procCwd.constData(), path_buffer, MAXPATHLEN); - if (length == -1) { - setError(UnknownError); - return false; - } - - path_buffer[length] = '\0'; - QString path = QFile::decodeName(path_buffer); - - setCurrentDir(path); - return true; - } }; #elif defined(Q_OS_FREEBSD) @@ -586,6 +592,48 @@ public: UnixProcessInfo(aPid, titleFormat) { } +protected: + virtual bool readCurrentDir(int aPid) { +#if defined(HAVE_OS_DRAGONFLYBSD) + char buf[PATH_MAX]; + int managementInfoBase[4]; + size_t len; + + managementInfoBase[0] = CTL_KERN; + managementInfoBase[1] = KERN_PROC; + managementInfoBase[2] = KERN_PROC_CWD; + managementInfoBase[3] = aPid; + + len = sizeof(buf); + if (sysctl(managementInfoBase, 4, buf, &len, NULL, 0) == -1) + return false; + + setCurrentDir(buf); + + return true; +#else + int numrecords; + struct kinfo_file* info = 0; + + info = kinfo_getfile(aPid, &numrecords); + + if (!info) + return false; + + for (int i = 0; i < numrecords; ++i) { + if (info[i].kf_fd == KF_FD_TYPE_CWD) { + setCurrentDir(info[i].kf_path); + + free(info); + return true; + } + } + + free(info); + return false; +#endif + } + private: virtual bool readProcInfo(int aPid) { int managementInfoBase[4]; @@ -653,47 +701,6 @@ private: return true; } - - virtual bool readCurrentDir(int aPid) { -#if defined(HAVE_OS_DRAGONFLYBSD) - char buf[PATH_MAX]; - int managementInfoBase[4]; - size_t len; - - managementInfoBase[0] = CTL_KERN; - managementInfoBase[1] = KERN_PROC; - managementInfoBase[2] = KERN_PROC_CWD; - managementInfoBase[3] = aPid; - - len = sizeof(buf); - if (sysctl(managementInfoBase, 4, buf, &len, NULL, 0) == -1) - return false; - - setCurrentDir(buf); - - return true; -#else - int numrecords; - struct kinfo_file* info = 0; - - info = kinfo_getfile(aPid, &numrecords); - - if (!info) - return false; - - for (int i = 0; i < numrecords; ++i) { - if (info[i].kf_fd == KF_FD_TYPE_CWD) { - setCurrentDir(info[i].kf_path); - - free(info); - return true; - } - } - - free(info); - return false; -#endif - } }; #elif defined(Q_OS_OPENBSD) @@ -704,6 +711,26 @@ public: UnixProcessInfo(aPid, titleFormat) { } +protected: + virtual bool readCurrentDir(int aPid) { + char buf[PATH_MAX]; + int managementInfoBase[3]; + size_t len; + + managementInfoBase[0] = CTL_KERN; + managementInfoBase[1] = KERN_PROC_CWD; + managementInfoBase[2] = aPid; + + len = sizeof(buf); + if (::sysctl(managementInfoBase, 3, buf, &len, NULL, 0) == -1) { + qWarning() << "sysctl() call failed with code" << errno; + return false; + } + + setCurrentDir(buf); + return true; + } + private: virtual bool readProcInfo(int aPid) { int managementInfoBase[6]; @@ -787,25 +814,6 @@ private: free(argv); return true; } - - virtual bool readCurrentDir(int aPid) { - char buf[PATH_MAX]; - int managementInfoBase[3]; - size_t len; - - managementInfoBase[0] = CTL_KERN; - managementInfoBase[1] = KERN_PROC_CWD; - managementInfoBase[2] = aPid; - - len = sizeof(buf); - if (::sysctl(managementInfoBase, 3, buf, &len, NULL, 0) == -1) { - qWarning() << "sysctl() call failed with code" << errno; - return false; - } - - setCurrentDir(buf); - return true; - } }; #elif defined(Q_OS_OSX) @@ -816,6 +824,17 @@ public: UnixProcessInfo(aPid, titleFormat) { } +protected: + virtual bool readCurrentDir(int aPid) { + struct proc_vnodepathinfo vpi; + const int nb = proc_pidinfo(aPid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)); + if (nb == sizeof(vpi)) { + setCurrentDir(QString(vpi.pvi_cdir.vip_path)); + return true; + } + return false; + } + private: virtual bool readProcInfo(int aPid) { int managementInfoBase[4]; @@ -875,15 +894,6 @@ private: Q_UNUSED(aPid); return false; } - virtual bool readCurrentDir(int aPid) { - struct proc_vnodepathinfo vpi; - const int nb = proc_pidinfo(aPid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi)); - if (nb == sizeof(vpi)) { - setCurrentDir(QString(vpi.pvi_cdir.vip_path)); - return true; - } - return false; - } }; #elif defined(Q_OS_SOLARIS) @@ -904,6 +914,27 @@ public: SolarisProcessInfo(int aPid, const QString& titleFormat) : UnixProcessInfo(aPid, titleFormat) { } + +protected: + // FIXME: This will have the same issues as BKO 251351; the Linux + // version uses readlink. + virtual bool readCurrentDir(int aPid) { + QFileInfo info(QString("/proc/%1/path/cwd").arg(aPid)); + const bool readable = info.isReadable(); + + if (readable && info.isSymLink()) { + setCurrentDir(info.symLinkTarget()); + return true; + } else { + if (!readable) + setError(PermissionsError); + else + setError(UnknownError); + + return false; + } + } + private: virtual bool readProcInfo(int aPid) { QFile psinfo(QString("/proc/%1/psinfo").arg(aPid)); @@ -929,25 +960,6 @@ private: // Handled in readProcInfo() return false; } - - // FIXME: This will have the same issues as BKO 251351; the Linux - // version uses readlink. - virtual bool readCurrentDir(int aPid) { - QFileInfo info(QString("/proc/%1/path/cwd").arg(aPid)); - const bool readable = info.isReadable(); - - if (readable && info.isSymLink()) { - setCurrentDir(info.symLinkTarget()); - return true; - } else { - if (!readable) - setError(PermissionsError); - else - setError(UnknownError); - - return false; - } - } }; #endif @@ -1124,18 +1136,21 @@ QString SSHProcessInfo::format(const QString& input) const ProcessInfo* ProcessInfo::newInstance(int aPid, const QString& titleFormat) { + ProcessInfo *info; #if defined(Q_OS_LINUX) - return new LinuxProcessInfo(aPid, titleFormat); + info = new LinuxProcessInfo(aPid, titleFormat); #elif defined(Q_OS_SOLARIS) - return new SolarisProcessInfo(aPid, titleFormat); + info = new SolarisProcessInfo(aPid, titleFormat); #elif defined(Q_OS_OSX) - return new MacProcessInfo(aPid, titleFormat); + info = new MacProcessInfo(aPid, titleFormat); #elif defined(Q_OS_FREEBSD) - return new FreeBSDProcessInfo(aPid, titleFormat); + info = new FreeBSDProcessInfo(aPid, titleFormat); #elif defined(Q_OS_OPENBSD) - return new OpenBSDProcessInfo(aPid, titleFormat); + info = new OpenBSDProcessInfo(aPid, titleFormat); #else - return new NullProcessInfo(aPid, titleFormat); + info = new NullProcessInfo(aPid, titleFormat); #endif + info->readProcessInfo(aPid); + return info; } diff --git a/src/ProcessInfo.h b/src/ProcessInfo.h index f2c348afd..35906517d 100644 --- a/src/ProcessInfo.h +++ b/src/ProcessInfo.h @@ -231,6 +231,13 @@ protected: */ virtual bool readProcessInfo(int pid) = 0; + /** + * Determine the current directory of the process. + * @param pid process ID to use + * @return true on success + */ + virtual bool readCurrentDir(int pid) = 0; + /* Read the user name */ virtual void readUserName(void) = 0; @@ -316,6 +323,7 @@ public: explicit NullProcessInfo(int pid, const QString& titleFormat); protected: virtual bool readProcessInfo(int pid); + virtual bool readCurrentDir(int pid); virtual void readUserName(void); }; @@ -356,13 +364,6 @@ private: * @return true on success */ virtual bool readArguments(int pid) = 0; - - /** - * Determine the current directory of the process. - * @param pid process ID to use - * @return true on success - */ - virtual bool readCurrentDir(int pid) = 0; }; #endif