2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
6 OGo 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 OGo 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 OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "NSProcessInfo+misc.h"
27 #if !LIB_FOUNDATION_LIBRARY && !GNUSTEP_BASE_LIBRARY
28 # import <NGExtensions/NSString+Ext.h>
31 @implementation NSProcessInfo(misc)
35 - (NSArray *)argumentsWithoutDefaults {
42 if ((count = [a count]) == 0) return nil;
43 if (count == 1) return a;
45 ma = [NSMutableArray arrayWithCapacity:count];
46 [ma addObject:[a objectAtIndex:0]]; // tool name
48 for (i = 1, foundDefault = NO; i < count; i++) {
51 arg = [a objectAtIndex:i];
52 if ([arg hasPrefix:@"-"] && ([arg length] > 1)) {
54 i++; /* consume value */
62 return foundDefault ? (id)ma : a;
65 /* create temp file name */
67 - (NSString *)temporaryFileName:(NSString *)_prefix {
71 s = [NSString stringWithFormat:
72 @"%04X%X%02X.tmp", getpid(), time(NULL),
74 return [_prefix stringByAppendingString:s];
76 - (NSString *)temporaryFileName {
79 prefix = [@"/tmp/" stringByAppendingPathComponent:[self processName]];
80 return [self temporaryFileName:prefix];
83 /* return process-id (pid on Unix) */
87 #if defined(__MINGW32__)
88 pid = (int)GetCurrentProcessId();
92 return [NSNumber numberWithInt:pid];
95 - (NSString *)procDirectoryPathForProcess {
99 p = [@"/proc/" stringByAppendingString:[[self processId] stringValue]];
100 if (![[NSFileManager defaultManager] fileExistsAtPath:p isDirectory:&isDir])
103 return isDir ? p : nil;
106 - (NSDictionary *)procStatusDictionary {
107 NSMutableDictionary *dict;
108 NSString *procStatusPath;
114 [[self procDirectoryPathForProcess]
115 stringByAppendingPathComponent:@"status"];
117 s = [[NSString alloc] initWithContentsOfFile:procStatusPath];
118 if (s == nil) return nil;
120 dict = [NSMutableDictionary dictionaryWithCapacity:32];
122 lines = [[s componentsSeparatedByString:@"\n"] objectEnumerator];
123 while ((line = [lines nextObject])) {
128 r = [line rangeOfString:@":"];
129 if (r.length == 0) continue;
131 key = [line substringToIndex:r.location];
132 value = [[line substringFromIndex:(r.location + r.length)]
133 stringByTrimmingSpaces];
136 value = [NSNull null];
138 [dict setObject:value forKey:key];
141 return [[dict copy] autorelease];
144 static NSNumber *_int(int i) __attribute__((unused));
145 static NSNumber *_uint(unsigned int i) __attribute__((unused));
147 static NSNumber *_int(int i) {
148 return [NSNumber numberWithInt:i];
150 static NSNumber *_uint(unsigned int i) {
151 return [NSNumber numberWithUnsignedInt:i];
154 #define NG_GET_PROC_INFO \
158 int pid, ppid, pgrp, session, tty, tpgid;\
159 unsigned int flags, minflt, cminflt, majflt, cmajflt;\
160 int utime, stime, cutime, cstime, counter;\
161 unsigned char comm[256];\
163 int priority, starttime;\
164 unsigned int timeout, itrealvalue, vsize, rss, rlim, startcode, endcode;\
165 unsigned int startstack, kstkesp, kstkeip;\
166 int signal, blocked, sigignore, sigcatch;\
170 snprintf(pp, 255, "/proc/%i/stat", pid);\
171 fh = fopen(pp, "r");\
176 "%d %255s %c %d %d %d %d %d "\
185 &pid, &(comm[0]), &state, &ppid, &pgrp, &session, &tty, \
187 &flags, &minflt, &cminflt, &majflt, &cmajflt,\
188 &utime, &stime, &cutime, &cstime, &counter,\
189 &priority, &timeout, &itrealvalue, &starttime,\
190 &vsize, &rss, &rlim, &startcode, &endcode,\
191 &startstack, &kstkesp, &kstkeip,\
192 &signal, &blocked, &sigignore, &sigcatch,\
195 fclose(fh); fh = NULL;
197 - (unsigned int)virtualMemorySize {
205 - (unsigned int)residentSetSize {
213 - (unsigned int)residentSetSizeLimit {
222 - (NSDictionary *)procStatDictionary {
224 /* see 'man 5 proc' */
225 NSMutableDictionary *dict;
229 dict = [NSMutableDictionary dictionaryWithCapacity:res];
231 if (res > 0) [dict setObject:_int(pid) forKey:@"pid"];
232 if (res > 1) [dict setObject:[NSString stringWithCString:comm]
234 if (res > 2) [dict setObject:[NSString stringWithCString:&state length:1]
236 if (res > 3) [dict setObject:_int(ppid) forKey:@"ppid"];
237 if (res > 4) [dict setObject:_int(pgrp) forKey:@"pgrp"];
238 if (res > 5) [dict setObject:_int(session) forKey:@"session"];
239 if (res > 6) [dict setObject:_int(tty) forKey:@"tty"];
240 if (res > 7) [dict setObject:_int(tpgid) forKey:@"tpgid"];
241 if (res > 8) [dict setObject:_uint(flags) forKey:@"flags"];
242 if (res > 9) [dict setObject:_uint(minflt) forKey:@"minflt"];
243 if (res > 10) [dict setObject:_uint(cminflt) forKey:@"cminflt"];
244 if (res > 11) [dict setObject:_uint(majflt) forKey:@"majflt"];
245 if (res > 12) [dict setObject:_uint(cmajflt) forKey:@"cmajflt"];
246 if (res > 13) [dict setObject:_int(utime) forKey:@"utime"];
247 if (res > 14) [dict setObject:_int(stime) forKey:@"stime"];
248 if (res > 15) [dict setObject:_int(cutime) forKey:@"cutime"];
249 if (res > 16) [dict setObject:_int(cstime) forKey:@"cstime"];
250 if (res > 17) [dict setObject:_int(counter) forKey:@"counter"];
251 if (res > 18) [dict setObject:_int(priority) forKey:@"priority"];
252 if (res > 19) [dict setObject:_uint(timeout) forKey:@"timeout"];
253 if (res > 20) [dict setObject:_uint(itrealvalue) forKey:@"itrealvalue"];
254 if (res > 21) [dict setObject:_int(starttime) forKey:@"starttime"];
255 if (res > 22) [dict setObject:_uint(vsize) forKey:@"vsize"];
256 if (res > 23) [dict setObject:_uint(rss) forKey:@"rss"];
257 if (res > 24) [dict setObject:_uint(rlim) forKey:@"rlim"];
258 if (res > 25) [dict setObject:_uint(startcode) forKey:@"startcode"];
259 if (res > 26) [dict setObject:_uint(endcode) forKey:@"endcode"];
260 if (res > 27) [dict setObject:_uint(startstack) forKey:@"startstack"];
261 if (res > 28) [dict setObject:_uint(kstkesp) forKey:@"kstkesp"];
262 if (res > 29) [dict setObject:_uint(kstkeip) forKey:@"kstkeip"];
263 if (res > 30) [dict setObject:_int(signal) forKey:@"signal"];
264 if (res > 31) [dict setObject:_int(blocked) forKey:@"blocked"];
265 if (res > 32) [dict setObject:_int(sigignore) forKey:@"sigignore"];
266 if (res > 33) [dict setObject:_int(sigcatch) forKey:@"sigcatch"];
267 if (res > 34) [dict setObject:_uint(wchan) forKey:@"wchan"];
272 NSLog(@"%s: couldn't scan /proc-info ...", __PRETTY_FUNCTION__);
276 return [[dict copy] autorelease];
282 @end /* NSProcessInfo(misc) */
286 void __link_NSProcessInfo_misc(void) {
287 __link_NSProcessInfo_misc();