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