]> err.no Git - sope/blob - sope-core/NGExtensions/FdExt.subproj/NSProcessInfo+misc.m
fixed OGo bug 912
[sope] / sope-core / NGExtensions / FdExt.subproj / NSProcessInfo+misc.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include "NSProcessInfo+misc.h"
23 #include "common.h"
24 #include <time.h>
25
26 #if !LIB_FOUNDATION_LIBRARY && !GNUSTEP_BASE_LIBRARY
27 #  import <NGExtensions/NSString+Ext.h>
28 #endif
29
30 @implementation NSProcessInfo(misc)
31
32 /* arguments */
33
34 - (NSArray *)argumentsWithoutDefaults {
35   NSMutableArray *ma;
36   NSArray  *a;
37   unsigned count, i;
38   BOOL     foundDefault;
39   
40   a = [self arguments];
41   if ((count = [a count]) == 0) return nil;
42   if (count == 1) return a;
43   
44   ma = [NSMutableArray arrayWithCapacity:count];
45   [ma addObject:[a objectAtIndex:0]]; // tool name
46   
47   for (i = 1, foundDefault = NO; i < count; i++) {
48     NSString *arg;
49     
50     arg = [a objectAtIndex:i];
51     if ([arg hasPrefix:@"-"] && ([arg length] > 1)) {
52       /* a default .. */
53       i++; /* consume value */
54       foundDefault = YES;
55       continue;
56     }
57     
58     [ma addObject:arg];
59   }
60   
61   return foundDefault ? (id)ma : a;
62 }
63
64 /* create temp file name */
65
66 - (NSString *)temporaryFileName:(NSString *)_prefix {
67   static int cnt = 0;
68   NSString *s;
69   cnt++;
70   s = [NSString stringWithFormat:
71                   @"%04X%X%02X.tmp", getpid(), time(NULL),
72                   cnt];
73   return [_prefix stringByAppendingString:s];
74 }
75 - (NSString *)temporaryFileName {
76   NSString *prefix;
77   
78   prefix = [@"/tmp/" stringByAppendingPathComponent:[self processName]];
79   return [self temporaryFileName:prefix];
80 }
81
82 /* return process-id (pid on Unix) */
83
84 - (id)processId {
85   int pid;
86 #if defined(__MINGW32__)
87   pid = (int)GetCurrentProcessId();
88 #else                     
89   pid = (int)getpid();
90 #endif
91   return [NSNumber numberWithInt:pid];
92 }
93
94 - (NSString *)procDirectoryPathForProcess {
95   NSString *p;
96   BOOL isDir;
97   
98   p = [@"/proc/" stringByAppendingString:[[self processId] stringValue]];
99   if (![[NSFileManager defaultManager] fileExistsAtPath:p isDirectory:&isDir])
100     return nil;
101   
102   return isDir ? p : nil;
103 }
104
105 - (NSDictionary *)procStatusDictionary {
106   NSMutableDictionary *dict;
107   NSString     *procStatusPath;
108   NSString     *s;
109   NSEnumerator *lines;
110   NSString     *line;
111   
112   procStatusPath =
113     [[self procDirectoryPathForProcess]
114            stringByAppendingPathComponent:@"status"];
115   
116   s = [[NSString alloc] initWithContentsOfFile:procStatusPath];
117   if (s == nil) return nil;
118   
119   dict = [NSMutableDictionary dictionaryWithCapacity:32];
120   
121   lines = [[s componentsSeparatedByString:@"\n"] objectEnumerator];
122   while ((line = [lines nextObject])) {
123     NSString *key;
124     NSRange  r;
125     id value;
126     
127     r = [line rangeOfString:@":"];
128     if (r.length == 0) continue;
129     
130     key   = [line substringToIndex:r.location];
131     value = [[line substringFromIndex:(r.location + r.length)] 
132                    stringByTrimmingSpaces];
133     
134     if (value == nil)
135       value = [NSNull null];
136     
137     [dict setObject:value forKey:key];
138   }
139   
140   return [[dict copy] autorelease];
141 }
142
143 static NSNumber *_int(int i) __attribute__((unused));
144 static NSNumber *_uint(unsigned int i) __attribute__((unused));
145
146 static NSNumber *_int(int i) {
147   return [NSNumber numberWithInt:i];
148 }
149 static NSNumber *_uint(unsigned int i) {
150   return [NSNumber numberWithUnsignedInt:i];
151 }
152
153 #define NG_GET_PROC_INFO \
154     FILE          *fh;\
155     char          pp[256];\
156     int           res;\
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];\
161     char          state = 0;\
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;\
166     unsigned int  wchan;\
167     \
168     pid = getpid();\
169     snprintf(pp, 255, "/proc/%i/stat", pid);\
170     fh = fopen(pp, "r");\
171     if (fh == NULL)\
172       res = -1;\
173     else\
174       res = fscanf(fh,\
175                  "%d %255s %c %d %d %d %d %d "\
176                  "%u %u %u %u %u "\
177                  "%d %d %d %d %d "\
178                  "%d %u %u %d "\
179                  "%u %u %u %u %u"\
180                  "%u %u %u "\
181                  "%d %d %d %d "\
182                  "%u"\
183                  ,\
184                  &pid, &(comm[0]), &state, &ppid, &pgrp, &session, &tty, \
185                  &tpgid,\
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,\
192                  &wchan\
193                  );\
194     fclose(fh); fh = NULL;
195
196 - (unsigned int)virtualMemorySize {
197 #ifdef __linux__
198   NG_GET_PROC_INFO;
199   return vsize;
200 #else
201   return 0;
202 #endif
203 }
204 - (unsigned int)residentSetSize {
205 #ifdef __linux__
206   NG_GET_PROC_INFO;
207   return rss;
208 #else
209   return 0;
210 #endif
211 }
212 - (unsigned int)residentSetSizeLimit {
213 #ifdef __linux__
214   NG_GET_PROC_INFO;
215   return rlim;
216 #else
217   return 0;
218 #endif
219 }
220
221 - (NSDictionary *)procStatDictionary {
222 #ifdef __linux__
223   /* see 'man 5 proc' */
224   NSMutableDictionary *dict;
225   NG_GET_PROC_INFO;
226   
227   if (res > 0) {
228     dict = [NSMutableDictionary dictionaryWithCapacity:res];
229     
230     if (res >  0) [dict setObject:_int(pid)          forKey:@"pid"];
231     if (res >  1) [dict setObject:[NSString stringWithCString:comm]
232                         forKey:@"comm"];
233     if (res >  2) [dict setObject:[NSString stringWithCString:&state length:1]
234                         forKey:@"state"];
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"];
267     
268     return dict;
269   }
270   else {
271     NSLog(@"%s: couldn't scan /proc-info ...", __PRETTY_FUNCTION__);
272     dict = nil;
273   }
274   
275   return [[dict copy] autorelease];
276 #else
277   return nil;
278 #endif
279 }
280
281 @end /* NSProcessInfo(misc) */
282
283 // linking
284
285 void __link_NSProcessInfo_misc(void) {
286   __link_NSProcessInfo_misc();
287 }