1 /* $Id: osdep-openbsd.c,v 1.1.1.2 2011/08/17 18:40:06 jmmv Exp $ */ 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/sysctl.h> 21 #include <sys/stat.h> 22 23 #include <errno.h> 24 #include <event.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <unistd.h> 28 29 #ifndef nitems 30 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 31 #endif 32 33 #define is_runnable(p) \ 34 ((p)->p_stat == SRUN || (p)->p_stat == SIDL || (p)->p_stat == SONPROC) 35 #define is_stopped(p) \ 36 ((p)->p_stat == SSTOP || (p)->p_stat == SZOMB || (p)->p_stat == SDEAD) 37 38 struct kinfo_proc *cmp_procs(struct kinfo_proc *, struct kinfo_proc *); 39 char *osdep_get_name(int, char *); 40 struct event_base *osdep_event_init(void); 41 42 struct kinfo_proc * 43 cmp_procs(struct kinfo_proc *p1, struct kinfo_proc *p2) 44 { 45 if (is_runnable(p1) && !is_runnable(p2)) 46 return (p1); 47 if (!is_runnable(p1) && is_runnable(p2)) 48 return (p2); 49 50 if (is_stopped(p1) && !is_stopped(p2)) 51 return (p1); 52 if (!is_stopped(p1) && is_stopped(p2)) 53 return (p2); 54 55 if (p1->p_estcpu > p2->p_estcpu) 56 return (p1); 57 if (p1->p_estcpu < p2->p_estcpu) 58 return (p2); 59 60 if (p1->p_slptime < p2->p_slptime) 61 return (p1); 62 if (p1->p_slptime > p2->p_slptime) 63 return (p2); 64 65 if ((p1->p_flag & P_SINTR) && !(p2->p_flag & P_SINTR)) 66 return (p1); 67 if (!(p1->p_flag & P_SINTR) && (p2->p_flag & P_SINTR)) 68 return (p2); 69 70 if (strcmp(p1->p_comm, p2->p_comm) < 0) 71 return (p1); 72 if (strcmp(p1->p_comm, p2->p_comm) > 0) 73 return (p2); 74 75 if (p1->p_pid > p2->p_pid) 76 return (p1); 77 return (p2); 78 } 79 80 char * 81 osdep_get_name(int fd, char *tty) 82 { 83 int mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, 0, 84 sizeof(struct kinfo_proc), 0 }; 85 struct stat sb; 86 size_t len; 87 struct kinfo_proc *buf, *newbuf, *bestp; 88 u_int i; 89 char *name; 90 91 buf = NULL; 92 93 if (stat(tty, &sb) == -1) 94 return (NULL); 95 if ((mib[3] = tcgetpgrp(fd)) == -1) 96 return (NULL); 97 98 retry: 99 if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1) 100 return (NULL); 101 len = (len * 5) / 4; 102 103 if ((newbuf = realloc(buf, len)) == NULL) 104 goto error; 105 buf = newbuf; 106 107 mib[5] = (int)(len / sizeof(struct kinfo_proc)); 108 if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) { 109 if (errno == ENOMEM) 110 goto retry; 111 goto error; 112 } 113 114 bestp = NULL; 115 for (i = 0; i < len / sizeof (struct kinfo_proc); i++) { 116 if ((dev_t)buf[i].p_tdev != sb.st_rdev) 117 continue; 118 if (bestp == NULL) 119 bestp = &buf[i]; 120 else 121 bestp = cmp_procs(&buf[i], bestp); 122 } 123 124 name = NULL; 125 if (bestp != NULL) 126 name = strdup(bestp->p_comm); 127 128 free(buf); 129 return (name); 130 131 error: 132 free(buf); 133 return (NULL); 134 } 135 136 struct event_base * 137 osdep_event_init(void) 138 { 139 return (event_init()); 140 } 141