2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "NSProcessInfo+misc.h"
26 #if !LIB_FOUNDATION_LIBRARY && !GNUSTEP_BASE_LIBRARY
27 # import <NGExtensions/NSString+Ext.h>
30 @implementation NSProcessInfo(misc)
34 - (NSArray *)argumentsWithoutDefaults {
41 if ((count = [a count]) == 0) return nil;
42 if (count == 1) return a;
44 ma = [NSMutableArray arrayWithCapacity:count];
45 [ma addObject:[a objectAtIndex:0]]; // tool name
47 for (i = 1, foundDefault = NO; i < count; i++) {
50 arg = [a objectAtIndex:i];
51 if ([arg hasPrefix:@"-"] && ([arg length] > 1)) {
53 i++; /* consume value */
61 return foundDefault ? (NSArray *)ma : a;
64 /* create temp file name */
66 - (NSString *)temporaryFileName:(NSString *)_prefix {
70 s = [NSString stringWithFormat:
71 @"%04X%X%02X.tmp", getpid(), time(NULL),
73 return [_prefix stringByAppendingString:s];
75 - (NSString *)temporaryFileName {
78 prefix = [@"/tmp/" stringByAppendingPathComponent:[self processName]];
79 return [self temporaryFileName:prefix];
82 /* return process-id (pid on Unix) */
86 #if defined(__MINGW32__)
87 pid = (int)GetCurrentProcessId();
91 return [NSNumber numberWithInt:pid];
94 - (NSString *)procDirectoryPathForProcess {
98 p = [@"/proc/" stringByAppendingString:[[self processId] stringValue]];
99 if (![[NSFileManager defaultManager] fileExistsAtPath:p isDirectory:&isDir])
102 return isDir ? p : (NSString *)nil;
105 - (NSDictionary *)procStatusDictionary {
106 NSMutableDictionary *dict;
107 NSString *procStatusPath;
113 [[self procDirectoryPathForProcess]
114 stringByAppendingPathComponent:@"status"];
116 s = [[NSString alloc] initWithContentsOfFile:procStatusPath];
117 if (s == nil) return nil;
119 dict = [NSMutableDictionary dictionaryWithCapacity:32];
121 lines = [[s componentsSeparatedByString:@"\n"] objectEnumerator];
122 while ((line = [lines nextObject])) {
127 r = [line rangeOfString:@":"];
128 if (r.length == 0) continue;
130 key = [line substringToIndex:r.location];
131 value = [[line substringFromIndex:(r.location + r.length)]
132 stringByTrimmingSpaces];
135 value = [NSNull null];
137 [dict setObject:value forKey:key];
140 return [[dict copy] autorelease];
143 static NSNumber *_int(int i) __attribute__((unused));
144 static NSNumber *_uint(unsigned int i) __attribute__((unused));
146 static NSNumber *_int(int i) {
147 return [NSNumber numberWithInt:i];
149 static NSNumber *_uint(unsigned int i) {
150 return [NSNumber numberWithUnsignedInt:i];
153 #define NG_GET_PROC_INFO \
157 int pid, ppid, pgrp, session, tty, tpgid;\
158 unsigned int flags, minflt, cminflt, majflt, cmajflt;\
159 int utime, stime, cutime, cstime, counter;\
160 unsigned char comm[256];\
162 int priority, starttime;\
163 unsigned int timeout, itrealvalue, vsize, rss, rlim, startcode, endcode;\
164 unsigned int startstack, kstkesp, kstkeip;\
165 int signal, blocked, sigignore, sigcatch;\
169 snprintf(pp, 255, "/proc/%i/stat", pid);\
170 fh = fopen(pp, "r");\
175 "%d %255s %c %d %d %d %d %d "\
184 &pid, &(comm[0]), &state, &ppid, &pgrp, &session, &tty, \
186 &flags, &minflt, &cminflt, &majflt, &cmajflt,\
187 &utime, &stime, &cutime, &cstime, &counter,\
188 &priority, &timeout, &itrealvalue, &starttime,\
189 &vsize, &rss, &rlim, &startcode, &endcode,\
190 &startstack, &kstkesp, &kstkeip,\
191 &signal, &blocked, &sigignore, &sigcatch,\
194 fclose(fh); fh = NULL;
196 - (unsigned int)virtualMemorySize {
204 - (unsigned int)residentSetSize {
212 - (unsigned int)residentSetSizeLimit {
221 - (NSDictionary *)procStatDictionary {
223 /* see 'man 5 proc' */
224 NSMutableDictionary *dict;
228 dict = [NSMutableDictionary dictionaryWithCapacity:res];
230 if (res > 0) [dict setObject:_int(pid) forKey:@"pid"];
231 if (res > 1) [dict setObject:[NSString stringWithCString:(char *)comm]
233 if (res > 2) [dict setObject:[NSString stringWithCString:&state length:1]
235 if (res > 3) [dict setObject:_int(ppid) forKey:@"ppid"];
236 if (res > 4) [dict setObject:_int(pgrp) forKey:@"pgrp"];
237 if (res > 5) [dict setObject:_int(session) forKey:@"session"];
238 if (res > 6) [dict setObject:_int(tty) forKey:@"tty"];
239 if (res > 7) [dict setObject:_int(tpgid) forKey:@"tpgid"];
240 if (res > 8) [dict setObject:_uint(flags) forKey:@"flags"];
241 if (res > 9) [dict setObject:_uint(minflt) forKey:@"minflt"];
242 if (res > 10) [dict setObject:_uint(cminflt) forKey:@"cminflt"];
243 if (res > 11) [dict setObject:_uint(majflt) forKey:@"majflt"];
244 if (res > 12) [dict setObject:_uint(cmajflt) forKey:@"cmajflt"];
245 if (res > 13) [dict setObject:_int(utime) forKey:@"utime"];
246 if (res > 14) [dict setObject:_int(stime) forKey:@"stime"];
247 if (res > 15) [dict setObject:_int(cutime) forKey:@"cutime"];
248 if (res > 16) [dict setObject:_int(cstime) forKey:@"cstime"];
249 if (res > 17) [dict setObject:_int(counter) forKey:@"counter"];
250 if (res > 18) [dict setObject:_int(priority) forKey:@"priority"];
251 if (res > 19) [dict setObject:_uint(timeout) forKey:@"timeout"];
252 if (res > 20) [dict setObject:_uint(itrealvalue) forKey:@"itrealvalue"];
253 if (res > 21) [dict setObject:_int(starttime) forKey:@"starttime"];
254 if (res > 22) [dict setObject:_uint(vsize) forKey:@"vsize"];
255 if (res > 23) [dict setObject:_uint(rss) forKey:@"rss"];
256 if (res > 24) [dict setObject:_uint(rlim) forKey:@"rlim"];
257 if (res > 25) [dict setObject:_uint(startcode) forKey:@"startcode"];
258 if (res > 26) [dict setObject:_uint(endcode) forKey:@"endcode"];
259 if (res > 27) [dict setObject:_uint(startstack) forKey:@"startstack"];
260 if (res > 28) [dict setObject:_uint(kstkesp) forKey:@"kstkesp"];
261 if (res > 29) [dict setObject:_uint(kstkeip) forKey:@"kstkeip"];
262 if (res > 30) [dict setObject:_int(signal) forKey:@"signal"];
263 if (res > 31) [dict setObject:_int(blocked) forKey:@"blocked"];
264 if (res > 32) [dict setObject:_int(sigignore) forKey:@"sigignore"];
265 if (res > 33) [dict setObject:_int(sigcatch) forKey:@"sigcatch"];
266 if (res > 34) [dict setObject:_uint(wchan) forKey:@"wchan"];
271 NSLog(@"%s: couldn't scan /proc-info ...", __PRETTY_FUNCTION__);
275 return [[dict copy] autorelease];
281 @end /* NSProcessInfo(misc) */
285 void __link_NSProcessInfo_misc(void) {
286 __link_NSProcessInfo_misc();