diff options
| author | Eduard Wiebe | 2012-04-21 18:11:51 +0800 |
|---|---|---|
| committer | Chong Yidong | 2012-04-21 18:11:51 +0800 |
| commit | b91b7e4d21bb1b675aeb678077901b758363db41 (patch) | |
| tree | 13ccc485a89294e50fb854a5b6664e885d07f2ae /src | |
| parent | b42287d22df7fe18831e2355429eec1761d97202 (diff) | |
| download | emacs-b91b7e4d21bb1b675aeb678077901b758363db41.tar.gz emacs-b91b7e4d21bb1b675aeb678077901b758363db41.zip | |
Add system processes support for FreeBSD.
* src/sysdep.c (list_system_processes, system_process_attributes): Add
implementation for FreeBSD.
Fixes: debbugs:5243
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/sysdep.c | 211 |
2 files changed, 216 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 304bca4e48b..a2c68317434 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2012-04-21 Eduard Wiebe <usenet@pusto.de> | ||
| 2 | |||
| 3 | * sysdep.c (list_system_processes, system_process_attributes): Add | ||
| 4 | implementation for FreeBSD (Bug#5243). | ||
| 5 | |||
| 1 | 2012-04-21 Andreas Schwab <schwab@linux-m68k.org> | 6 | 2012-04-21 Andreas Schwab <schwab@linux-m68k.org> |
| 2 | 7 | ||
| 3 | * lisp.mk (lisp): Update. | 8 | * lisp.mk (lisp): Update. |
diff --git a/src/sysdep.c b/src/sysdep.c index edaaa4c93d7..fdc04f6655d 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -37,6 +37,13 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 37 | #include "sysselect.h" | 37 | #include "sysselect.h" |
| 38 | #include "blockinput.h" | 38 | #include "blockinput.h" |
| 39 | 39 | ||
| 40 | #ifdef __FreeBSD__ | ||
| 41 | #include <sys/sysctl.h> | ||
| 42 | #include <sys/user.h> | ||
| 43 | #include <sys/resource.h> */ | ||
| 44 | #include <math.h> | ||
| 45 | #endif | ||
| 46 | |||
| 40 | #ifdef WINDOWSNT | 47 | #ifdef WINDOWSNT |
| 41 | #define read sys_read | 48 | #define read sys_read |
| 42 | #define write sys_write | 49 | #define write sys_write |
| @@ -2529,6 +2536,40 @@ list_system_processes (void) | |||
| 2529 | return proclist; | 2536 | return proclist; |
| 2530 | } | 2537 | } |
| 2531 | 2538 | ||
| 2539 | #elif defined (__FreeBSD__) | ||
| 2540 | |||
| 2541 | Lisp_Object | ||
| 2542 | list_system_processes () | ||
| 2543 | { | ||
| 2544 | int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC}; | ||
| 2545 | size_t len; | ||
| 2546 | struct kinfo_proc *procs; | ||
| 2547 | size_t i; | ||
| 2548 | |||
| 2549 | struct gcpro gcpro1; | ||
| 2550 | Lisp_Object proclist = Qnil; | ||
| 2551 | |||
| 2552 | if (sysctl (mib, 3, NULL, &len, NULL, 0) != 0) | ||
| 2553 | return proclist; | ||
| 2554 | |||
| 2555 | procs = xmalloc (len); | ||
| 2556 | if (sysctl (mib, 3, procs, &len, NULL, 0) != 0) | ||
| 2557 | { | ||
| 2558 | xfree (procs); | ||
| 2559 | return proclist; | ||
| 2560 | } | ||
| 2561 | |||
| 2562 | GCPRO1 (proclist); | ||
| 2563 | len /= sizeof (struct kinfo_proc); | ||
| 2564 | for (i = 0; i < len; i++) | ||
| 2565 | proclist = Fcons (make_fixnum_or_float (procs[i].ki_pid), proclist); | ||
| 2566 | UNGCPRO; | ||
| 2567 | |||
| 2568 | xfree (procs); | ||
| 2569 | |||
| 2570 | return proclist; | ||
| 2571 | } | ||
| 2572 | |||
| 2532 | /* The WINDOWSNT implementation is in w32.c. | 2573 | /* The WINDOWSNT implementation is in w32.c. |
| 2533 | The MSDOS implementation is in dosfns.c. */ | 2574 | The MSDOS implementation is in dosfns.c. */ |
| 2534 | #elif !defined (WINDOWSNT) && !defined (MSDOS) | 2575 | #elif !defined (WINDOWSNT) && !defined (MSDOS) |
| @@ -3079,6 +3120,176 @@ system_process_attributes (Lisp_Object pid) | |||
| 3079 | return attrs; | 3120 | return attrs; |
| 3080 | } | 3121 | } |
| 3081 | 3122 | ||
| 3123 | #elif defined(__FreeBSD__) | ||
| 3124 | |||
| 3125 | Lisp_Object | ||
| 3126 | system_process_attributes (Lisp_Object pid) | ||
| 3127 | { | ||
| 3128 | int proc_id; | ||
| 3129 | int pagesize = getpagesize(); | ||
| 3130 | int npages; | ||
| 3131 | int fscale; | ||
| 3132 | struct passwd *pw; | ||
| 3133 | struct group *gr; | ||
| 3134 | char *ttyname; | ||
| 3135 | size_t len; | ||
| 3136 | char args[MAXPATHLEN]; | ||
| 3137 | EMACS_TIME t, now; | ||
| 3138 | |||
| 3139 | int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID}; | ||
| 3140 | struct kinfo_proc proc; | ||
| 3141 | size_t proclen = sizeof(proc); | ||
| 3142 | |||
| 3143 | struct gcpro gcpro1, gcpro2; | ||
| 3144 | Lisp_Object attrs = Qnil; | ||
| 3145 | Lisp_Object decoded_comm; | ||
| 3146 | |||
| 3147 | CHECK_NUMBER_OR_FLOAT (pid); | ||
| 3148 | proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid); | ||
| 3149 | mib[3] = proc_id; | ||
| 3150 | |||
| 3151 | if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0) | ||
| 3152 | return attrs; | ||
| 3153 | |||
| 3154 | GCPRO2 (attrs, decoded_comm); | ||
| 3155 | |||
| 3156 | attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float(proc.ki_uid)), attrs); | ||
| 3157 | |||
| 3158 | BLOCK_INPUT; | ||
| 3159 | pw = getpwuid (proc.ki_uid); | ||
| 3160 | UNBLOCK_INPUT; | ||
| 3161 | if (pw) | ||
| 3162 | attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs); | ||
| 3163 | |||
| 3164 | attrs = Fcons (Fcons (Qegid, make_fixnum_or_float(proc.ki_svgid)), attrs); | ||
| 3165 | |||
| 3166 | BLOCK_INPUT; | ||
| 3167 | gr = getgrgid (proc.ki_svgid); | ||
| 3168 | UNBLOCK_INPUT; | ||
| 3169 | if (gr) | ||
| 3170 | attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); | ||
| 3171 | |||
| 3172 | decoded_comm = code_convert_string_norecord | ||
| 3173 | (make_unibyte_string (proc.ki_comm, strlen (proc.ki_comm)), | ||
| 3174 | Vlocale_coding_system, 0); | ||
| 3175 | |||
| 3176 | attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); | ||
| 3177 | { | ||
| 3178 | char state[2] = {'\0', '\0'}; | ||
| 3179 | switch (proc.ki_stat) | ||
| 3180 | { | ||
| 3181 | case SRUN: | ||
| 3182 | state[0] = 'R'; | ||
| 3183 | break; | ||
| 3184 | |||
| 3185 | case SSLEEP: | ||
| 3186 | state[0] = 'S'; | ||
| 3187 | break; | ||
| 3188 | |||
| 3189 | case SLOCK: | ||
| 3190 | state[0] = 'D'; | ||
| 3191 | break; | ||
| 3192 | |||
| 3193 | case SZOMB: | ||
| 3194 | state[0] = 'Z'; | ||
| 3195 | break; | ||
| 3196 | |||
| 3197 | case SSTOP: | ||
| 3198 | state[0] = 'T'; | ||
| 3199 | break; | ||
| 3200 | } | ||
| 3201 | attrs = Fcons (Fcons (Qstate, build_string (state)), attrs); | ||
| 3202 | } | ||
| 3203 | |||
| 3204 | attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (proc.ki_ppid)), attrs); | ||
| 3205 | attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (proc.ki_pgid)), attrs); | ||
| 3206 | attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (proc.ki_sid)), attrs); | ||
| 3207 | |||
| 3208 | BLOCK_INPUT; | ||
| 3209 | ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR); | ||
| 3210 | UNBLOCK_INPUT; | ||
| 3211 | if (ttyname) | ||
| 3212 | attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs); | ||
| 3213 | |||
| 3214 | attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (proc.ki_tpgid)), attrs); | ||
| 3215 | attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (proc.ki_rusage.ru_minflt)), attrs); | ||
| 3216 | attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (proc.ki_rusage.ru_majflt)), attrs); | ||
| 3217 | attrs = Fcons (Fcons (Qcminflt, make_number (proc.ki_rusage_ch.ru_minflt)), attrs); | ||
| 3218 | attrs = Fcons (Fcons (Qcmajflt, make_number (proc.ki_rusage_ch.ru_majflt)), attrs); | ||
| 3219 | |||
| 3220 | #define TIMELIST(ts) \ | ||
| 3221 | list3 (make_number (EMACS_SECS (ts) >> 16 & 0xffff), \ | ||
| 3222 | make_number (EMACS_SECS (ts) & 0xffff), \ | ||
| 3223 | make_number (EMACS_USECS (ts))) | ||
| 3224 | |||
| 3225 | attrs = Fcons (Fcons (Qutime, TIMELIST(proc.ki_rusage.ru_utime)), attrs); | ||
| 3226 | attrs = Fcons (Fcons (Qstime, TIMELIST(proc.ki_rusage.ru_stime)), attrs); | ||
| 3227 | EMACS_ADD_TIME (t, proc.ki_rusage.ru_utime, proc.ki_rusage.ru_stime); | ||
| 3228 | attrs = Fcons (Fcons (Qtime, TIMELIST(t)), attrs); | ||
| 3229 | |||
| 3230 | attrs = Fcons (Fcons (Qcutime, TIMELIST(proc.ki_rusage_ch.ru_utime)), attrs); | ||
| 3231 | attrs = Fcons (Fcons (Qcstime, TIMELIST(proc.ki_rusage_ch.ru_utime)), attrs); | ||
| 3232 | EMACS_ADD_TIME (t, proc.ki_rusage_ch.ru_utime, proc.ki_rusage_ch.ru_stime); | ||
| 3233 | attrs = Fcons (Fcons (Qctime, TIMELIST(t)), attrs); | ||
| 3234 | |||
| 3235 | attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (proc.ki_numthreads)), attrs); | ||
| 3236 | attrs = Fcons (Fcons (Qpri, make_number (proc.ki_pri.pri_native)), attrs); | ||
| 3237 | attrs = Fcons (Fcons (Qnice, make_number (proc.ki_nice)), attrs); | ||
| 3238 | attrs = Fcons (Fcons (Qstart, TIMELIST(proc.ki_start)), attrs); | ||
| 3239 | attrs = Fcons (Fcons (Qvsize, make_number (proc.ki_size >> 10)), attrs); | ||
| 3240 | attrs = Fcons (Fcons (Qrss, make_number (proc.ki_rssize * pagesize >> 10)), attrs); | ||
| 3241 | |||
| 3242 | EMACS_GET_TIME (now); | ||
| 3243 | EMACS_SUB_TIME (t, now, proc.ki_start); | ||
| 3244 | attrs = Fcons (Fcons (Qetime, TIMELIST(t)), attrs); | ||
| 3245 | |||
| 3246 | #undef TIMELIST | ||
| 3247 | |||
| 3248 | len = sizeof(fscale); | ||
| 3249 | if (sysctlbyname ("kern.fscale", &fscale, &len, NULL, 0) == 0) | ||
| 3250 | { | ||
| 3251 | float pcpu; | ||
| 3252 | fixpt_t ccpu; | ||
| 3253 | len = sizeof (ccpu); | ||
| 3254 | if (sysctlbyname ("kern.ccpu", &ccpu, &len, NULL, 0) == 0) | ||
| 3255 | { | ||
| 3256 | pcpu = 100.0 * ((double) proc.ki_pctcpu / fscale) | ||
| 3257 | / (1.0 - exp(proc.ki_swtime * log((double) ccpu / fscale))); | ||
| 3258 | attrs = Fcons (Fcons (Qpcpu, make_fixnum_or_float(pcpu)), attrs); | ||
| 3259 | } | ||
| 3260 | } | ||
| 3261 | |||
| 3262 | len = sizeof(npages); | ||
| 3263 | if (sysctlbyname ("hw.availpages", &npages, &len, NULL, 0) == 0) | ||
| 3264 | { | ||
| 3265 | float pmem = proc.ki_flag & P_INMEM | ||
| 3266 | ? 100.0 * ((float) proc.ki_rssize / npages) | ||
| 3267 | : 0.0; | ||
| 3268 | attrs = Fcons (Fcons (Qpmem, make_fixnum_or_float(pmem)), attrs); | ||
| 3269 | } | ||
| 3270 | |||
| 3271 | mib[2] = KERN_PROC_ARGS; | ||
| 3272 | len = MAXPATHLEN; | ||
| 3273 | if (sysctl (mib, 4, args, &len, NULL, 0) == 0) | ||
| 3274 | { | ||
| 3275 | int i; | ||
| 3276 | for (i = 0; i < len; i++) | ||
| 3277 | { | ||
| 3278 | if (! args[i] && i < len - 1) | ||
| 3279 | args[i] = ' '; | ||
| 3280 | } | ||
| 3281 | |||
| 3282 | decoded_comm = code_convert_string_norecord | ||
| 3283 | (make_unibyte_string (args, strlen (args)), | ||
| 3284 | Vlocale_coding_system, 0); | ||
| 3285 | |||
| 3286 | attrs = Fcons (Fcons (Qargs, decoded_comm), attrs); | ||
| 3287 | } | ||
| 3288 | |||
| 3289 | UNGCPRO; | ||
| 3290 | return attrs; | ||
| 3291 | } | ||
| 3292 | |||
| 3082 | /* The WINDOWSNT implementation is in w32.c. | 3293 | /* The WINDOWSNT implementation is in w32.c. |
| 3083 | The MSDOS implementation is in dosfns.c. */ | 3294 | The MSDOS implementation is in dosfns.c. */ |
| 3084 | #elif !defined (WINDOWSNT) && !defined (MSDOS) | 3295 | #elif !defined (WINDOWSNT) && !defined (MSDOS) |