1 /* $OpenBSD$ */ 2 3 /* 4 * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> 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 85 mib[0] = CTL_KERN; 86 mib[1] = KERN_PROC2; 87 mib[2] = KERN_PROC_PGRP; 88 mib[4] = sizeof *buf; 89 90 retry: 91 mib[5] = 0; 92 93 if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1) 94 return (NULL); 95 96 if ((newbuf = realloc(buf, len)) == NULL) 97 goto error; 98 buf = newbuf; 99 100 mib[5] = len / (sizeof *buf); 101 if (sysctl(mib, __arraycount(mib), buf, &len, NULL, 0) == -1) { 102 if (errno == ENOMEM) 103 goto retry; 104 goto error; 105 } 106 107 bestp = NULL; 108 for (i = 0; i < len / (sizeof *buf); i++) { 109 if (buf[i].p_tdev != sb.st_rdev) 110 continue; 111 if (bestp == NULL) 112 bestp = &buf[i]; 113 else 114 bestp = cmp_procs(&buf[i], bestp); 115 } 116 117 name = NULL; 118 if (bestp != NULL) 119 name = strdup(bestp->p_comm); 120 121 free(buf); 122 return (name); 123 124 error: 125 free(buf); 126 return (NULL); 127 } 128 129 char * 130 osdep_get_cwd(int fd) 131 { 132 return (NULL); 133 } 134 135 struct event_base * 136 osdep_event_init(void) 137 { 138 return (event_init()); 139 } 140