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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
$NetBSD: patch-src_ProcessInfo.cpp,v 1.1.1.1 2012/03/20 05:07:49 markd Exp $
--- src/ProcessInfo.cpp.orig 2010-03-26 17:26:32.000000000 +0000
+++ src/ProcessInfo.cpp
@@ -894,6 +894,171 @@ private:
}
} ;
+class NetBSDProcessInfo : public UnixProcessInfo
+{
+public:
+ NetBSDProcessInfo(int pid, bool env) :
+ UnixProcessInfo(pid,env)
+ {
+ }
+
+private:
+ virtual bool readProcInfo(int pid)
+ {
+ // indicies of various fields within the process status file which
+ // contain various information about the process
+ const int PARENT_PID_FIELD = 2;
+ const int PROCESS_NAME_FIELD = 0;
+ const int GROUP_PROCESS_FIELD = 3;
+ const int UID_PROCESS_FIELD = 11;
+
+ QString parentPidString;
+ QString processNameString;
+ QString foregroundPidString;
+ QString uidString;
+
+ // read process status file ( /proc/<pid/status )
+ //
+ // the expected file format is a list of fields separated by spaces, using
+ // parenthesies to escape fields such as the process name which may itself contain
+ // spaces:
+ //
+ // FIELD FIELD (FIELD WITH SPACES) FIELD FIELD
+ //
+ QFile processInfo( QString("/proc/%1/status").arg(pid) );
+ if ( processInfo.open(QIODevice::ReadOnly) )
+ {
+ QTextStream stream(&processInfo);
+ QString data = stream.readAll();
+
+ int stack = 0;
+ int field = 0;
+ int pos = 0;
+
+ while (pos < data.count())
+ {
+ QChar c = data[pos];
+
+ if ( c == '(' )
+ stack++;
+ else if ( c == ')' )
+ stack--;
+ else if ( stack == 0 && c == ' ' )
+ field++;
+ else
+ {
+ switch ( field )
+ {
+ case PARENT_PID_FIELD:
+ parentPidString.append(c);
+ break;
+ case PROCESS_NAME_FIELD:
+ processNameString.append(c);
+ break;
+ case GROUP_PROCESS_FIELD:
+ foregroundPidString.append(c);
+ break;
+ case UID_PROCESS_FIELD:
+ uidString.append(c);
+ break;
+ }
+ }
+
+ pos++;
+ }
+ }
+ else
+ {
+ setFileError( processInfo.error() );
+ return false;
+ }
+
+ // check that data was read successfully
+ bool ok = false;
+
+ // uid string must be less than 5 chars (uint)
+ if (uidString.size() > 5)
+ uidString.clear();
+
+ int uid = uidString.toInt(&ok);
+ if (ok)
+ setUserId(uid);
+ readUserName();
+
+ int foregroundPid = foregroundPidString.toInt(&ok);
+ if (ok)
+ setForegroundPid(foregroundPid);
+
+ int parentPid = parentPidString.toInt(&ok);
+ if (ok)
+ setParentPid(parentPid);
+
+ if (!processNameString.isEmpty())
+ setName(processNameString);
+
+ // update object state
+ setPid(pid);
+
+ return ok;
+ }
+
+ virtual bool readArguments(int pid)
+ {
+ // read command-line arguments file found at /proc/<pid>/cmdline
+ // the expected format is a list of strings delimited by null characters,
+ // and ending in a double null character pair.
+
+ QFile argumentsFile( QString("/proc/%1/cmdline").arg(pid) );
+ if ( argumentsFile.open(QIODevice::ReadOnly) )
+ {
+ QTextStream stream(&argumentsFile);
+ QString data = stream.readAll();
+
+ QStringList argList = data.split( QChar('\0') );
+
+ foreach ( const QString &entry , argList )
+ {
+ if (!entry.isEmpty())
+ addArgument(entry);
+ }
+ }
+ else
+ {
+ setFileError( argumentsFile.error() );
+ }
+
+ return true;
+ }
+
+ virtual bool readCurrentDir(int pid)
+ {
+ QFileInfo info( QString("/proc/%1/cwd").arg(pid) );
+
+ const bool readable = info.isReadable();
+
+ if ( readable && info.isSymLink() )
+ {
+ setCurrentDir( info.symLinkTarget() );
+ return true;
+ }
+ else
+ {
+ if ( !readable )
+ setError( PermissionsError );
+ else
+ setError( UnknownError );
+
+ return false;
+ }
+ }
+
+ virtual bool readEnvironment(int pid)
+ {
+ // Not supported in NetBSD
+ return true;
+ }
+} ;
+
SSHProcessInfo::SSHProcessInfo(const ProcessInfo& process)
: _process(process)
{
@@ -1039,6 +1204,8 @@ ProcessInfo* ProcessInfo::newInstance(in
return new LinuxProcessInfo(pid,enableEnvironmentRead);
#elif defined(Q_OS_SOLARIS)
return new SolarisProcessInfo(pid,enableEnvironmentRead);
+#elif defined(Q_OS_NETBSD)
+ return new NetBSDProcessInfo(pid,enableEnvironmentRead);
#elif defined(Q_OS_MAC)
return new MacProcessInfo(pid,enableEnvironmentRead);
#elif defined(Q_OS_FREEBSD)
|