1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1989-2011 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Eclipse Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.eclipse.org/org/documents/epl-v10.html * 11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <glenn.s.fowler@gmail.com> * 18 * * 19 ***********************************************************************/ 20 #pragma prototyped 21 /* 22 * Glenn Fowler 23 * AT&T Research 24 * 25 * process status stream PSS_METHOD_cygwin implementation 26 */ 27 28 #include "psslib.h" 29 30 #if PSS_METHOD != PSS_METHOD_cygwin 31 32 NoN(pss_cygwin) 33 34 #else 35 36 #ifndef PR_HZ 37 #define PR_HZ 100 38 #endif 39 #ifndef PRNODEV 40 #define PRNODEV ((Pss_dev_t)(-1)) 41 #endif 42 #ifndef PID_ZOMBIE 43 #define PID_ZOMBIE 0 44 #endif 45 46 #undef PR_CTIME 47 #define PR_CTIME(p) (((p)->rusage_children.ru_utime.tv_sec+(p)->rusage_children.ru_stime.tv_sec)*PR_HZ+((((p)->rusage_children.ru_utime.tv_usec+(p)->rusage_children.ru_stime.tv_usec)*PR_HZ)/1000000)) 48 #undef PR_START 49 #define PR_START(p) ((p)->start_time) 50 #undef PR_TIME 51 #define PR_TIME(p) (((p)->rusage_self.ru_utime.tv_sec+(p)->rusage_self.ru_stime.tv_sec)*PR_HZ+((((p)->rusage_self.ru_utime.tv_usec+(p)->rusage_self.ru_stime.tv_usec)*PR_HZ)/1000000)) 52 53 #undef PSS_addr 54 #define PSS_addr 0 55 #undef PSS_sched 56 #define PSS_sched 0 57 #undef PSS_cpu 58 #define PSS_cpu 0 59 #undef PSS_nice 60 #define PSS_nice 0 61 #undef PSS_pri 62 #define PSS_pri 0 63 #undef PSS_proc 64 #define PSS_proc 0 65 #undef PSS_refcount 66 #define PSS_refcount 0 67 #undef PSS_tgrp 68 #define PSS_tgrp 0 69 #undef PSS_wchan 70 #define PSS_wchan 0 71 72 static int 73 cygwin_init(Pss_t* pss) 74 { 75 cygwin_internal(CW_LOCK_PINFO, 1000); 76 return 1; 77 } 78 79 static int 80 cygwin_done(Pss_t* pss) 81 { 82 cygwin_internal(CW_UNLOCK_PINFO); 83 return 1; 84 } 85 86 static int 87 cygwin_read(Pss_t* pss, Pss_id_t pid) 88 { 89 if (pid) 90 pss->pid = pid; 91 else 92 { 93 if (!pss->data) 94 pss->pid = 0; 95 else if (!(pss->pid = ((struct external_pinfo*)pss->data)->pid)) 96 { 97 pss->data = 0; 98 return 0; 99 } 100 pss->pid |= CW_NEXTPID; 101 } 102 return 1; 103 } 104 105 static int 106 cygwin_part(register Pss_t* pss, register Pssent_t* pe) 107 { 108 register struct external_pinfo* pr; 109 110 if (!(pr = (struct external_pinfo*)cygwin_internal(CW_GETPINFO, pss->pid)) || !pr->pid) 111 return 0; 112 pss->data = (void*)pr; 113 pe->gid = pr->gid; 114 pe->pgrp = pr->pgid; 115 pe->sid = pr->sid; 116 pe->tty = pr->ctty == PRNODEV ? PSS_NODEV : pr->ctty; 117 pe->uid = pr->uid; 118 if (pr->process_state & (PID_EXITED|PID_ZOMBIE)) 119 pe->state = PSS_ZOMBIE; 120 else if (pr->process_state & PID_STOPPED) 121 pe->state = 'S'; 122 else if (pr->process_state & PID_TTYIN) 123 pe->state = 'I'; 124 else if (pr->process_state & PID_TTYOU) 125 pe->state = 'O'; 126 else 127 pe->state = ' '; 128 return 1; 129 } 130 131 static int 132 cygwin_full(register Pss_t* pss, register Pssent_t* pe) 133 { 134 register struct external_pinfo* pr = (struct external_pinfo*)pss->data; 135 unsigned long fields = pss->disc->fields & pss->meth->fields; 136 char* s; 137 int i; 138 139 if (pe->state != PSS_ZOMBIE) 140 { 141 if (fields & PSS_args) 142 { 143 cygwin_conv_to_posix_path(pr->progname, pss->buf); 144 s = pss->buf; 145 if ((i = strlen(s)) > 4 && !strcasecmp(s + i - 4, ".exe")) 146 *(s + i - 4) = 0; 147 pe->args = s; 148 } 149 if (fields & PSS_command) 150 { 151 cygwin_conv_to_posix_path(pr->progname, pss->buf); 152 if (s = strrchr(pss->buf, '/')) 153 s++; 154 else 155 s = pss->buf; 156 if ((i = strlen(s)) > 4 && !strcasecmp(s + i - 4, ".exe")) 157 *(s + i - 4) = 0; 158 pe->command = s; 159 } 160 } 161 pe->flags = pr->process_state; 162 pe->pid = pr->pid; 163 pe->npid = pr->dwProcessId; 164 pe->ppid = pr->ppid; 165 pe->rss = pr->rusage_self.ru_maxrss; 166 pe->size = pr->rusage_self.ru_idrss; 167 pe->start = PR_START(pr); 168 pe->time = PR_TIME(pr); 169 return 1; 170 } 171 172 static char* 173 cygwin_ttyname(Pss_t* pss, register Pssent_t* pe) 174 { 175 if (pe->tty < 0) 176 return "?"; 177 if (pe->tty == (Pss_dev_t)TTY_CONSOLE) 178 return "con"; 179 sfsprintf(pss->buf, sizeof(pss->buf), "%I*d", sizeof(pe->tty), pe->tty); 180 return pss->buf; 181 } 182 183 static Pss_dev_t 184 cygwin_ttymap(Pss_t* pss, Pss_dev_t dev) 185 { 186 return minor(dev); 187 } 188 189 static Pssmeth_t cygwin_method = 190 { 191 "cygwin", 192 "[-version?@(#)$Id: pss cygwin (AT&T Research) 2003-02-01 $\n]" 193 "[-author?Glenn Fowler <gsf@research.att.com>]", 194 PSS_all, 195 cygwin_init, 196 cygwin_read, 197 cygwin_part, 198 cygwin_full, 199 0, 200 cygwin_ttyname, 201 cygwin_ttymap, 202 cygwin_done 203 }; 204 205 Pssmeth_t* _pss_method = &cygwin_method; 206 207 #endif 208