1 /* Id */ 2 3 /* 4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/proc.h> 21 #include <sys/stat.h> 22 #include <sys/sysctl.h> 23 24 #include <errno.h> 25 #include <event.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 29 30 #define is_runnable(p) \ 31 ((p)->p_stat == LSRUN || (p)->p_stat == SIDL) 32 #define is_stopped(p) \ 33 ((p)->p_stat == SSTOP || (p)->p_stat == SZOMB) 34 35 struct kinfo_proc2 *cmp_procs(struct kinfo_proc2 *, struct kinfo_proc2 *); 36 char *osdep_get_name(int, char *); 37 char *osdep_get_cwd(int); 38 struct event_base *osdep_event_init(void); 39 40 struct kinfo_proc2 * 41 cmp_procs(struct kinfo_proc2 *p1, struct kinfo_proc2 *p2) 42 { 43 if (is_runnable(p1) && !is_runnable(p2)) 44 return (p1); 45 if (!is_runnable(p1) && is_runnable(p2)) 46 return (p2); 47 48 if (is_stopped(p1) && !is_stopped(p2)) 49 return (p1); 50 if (!is_stopped(p1) && is_stopped(p2)) 51 return (p2); 52 53 if (p1->p_estcpu > p2->p_estcpu) 54 return (p1); 55 if (p1->p_estcpu < p2->p_estcpu) 56 return (p2); 57 58 if (p1->p_slptime < p2->p_slptime) 59 return (p1); 60 if (p1->p_slptime > p2->p_slptime) 61 return (p2); 62 63 if (p1->p_pid > p2->p_pid) 64 return (p1); 65 return (p2); 66 } 67 68 char * 69 osdep_get_name(int fd, __unused char *tty) 70 { 71 int mib[6]; 72 struct stat sb; 73 size_t len, i; 74 struct kinfo_proc2 *buf, *newbuf, *bestp; 75 char *name; 76 77 if (stat(tty, &sb) == -1) 78 return (NULL); 79 if ((mib[3] = tcgetpgrp(fd)) == -1) 80 return (NULL); 81 82 buf = NULL; 83 len = sizeof(bestp); 84 mib[0] = CTL_KERN; 85 mib[1] = KERN_PROC2; 86 mib[2] = KERN_PROC_PGRP; 87 mib[4] = sizeof (*buf); 88 mib[5] = 0; 89 90 retry: 91 if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1) 92 return (NULL); 93 94 if ((newbuf = realloc(buf, len * sizeof (*buf))) == NULL) 95 goto error; 96 buf = newbuf; 97 98 mib[5] = len / sizeof(*buf); 99 if (sysctl(mib, __arraycount(mib), buf, &len, NULL, 0) == -1) { 100 if (errno == ENOMEM) 101 goto retry; /* possible infinite loop? */ 102 goto error; 103 } 104 105 bestp = NULL; 106 for (i = 0; i < len / sizeof (*buf); i++) { 107 if (buf[i].p_tdev != sb.st_rdev) 108 continue; 109 if (bestp == NULL) 110 bestp = &buf[i]; 111 else 112 bestp = cmp_procs(&buf[i], bestp); 113 } 114 115 name = NULL; 116 if (bestp != NULL) 117 name = strdup(bestp->p_comm); 118 119 free(buf); 120 return (name); 121 122 error: 123 free(buf); 124 return (NULL); 125 } 126 127 char * 128 osdep_get_cwd(int fd) 129 { 130 return (NULL); 131 } 132 133 struct event_base * 134 osdep_event_init(void) 135 { 136 return (event_init()); 137 } 138