1 /* $Id: osdep-netbsd.c,v 1.1.1.1 2011/03/10 09:15:38 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/proc.h> 21 #include <sys/stat.h> 22 #include <sys/sysctl.h> 23 24 #include <errno.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <unistd.h> 28 29 #define is_runnable(p) \ 30 ((p)->p_stat == LSRUN || (p)->p_stat == SIDL) 31 #define is_stopped(p) \ 32 ((p)->p_stat == SSTOP || (p)->p_stat == SZOMB) 33 34 struct kinfo_proc2 *cmp_procs(struct kinfo_proc2 *, struct kinfo_proc2 *); 35 char *osdep_get_name(int, char *); 36 37 struct kinfo_proc2 * 38 cmp_procs(struct kinfo_proc2 *p1, struct kinfo_proc2 *p2) 39 { 40 if (is_runnable(p1) && !is_runnable(p2)) 41 return (p1); 42 if (!is_runnable(p1) && is_runnable(p2)) 43 return (p2); 44 45 if (is_stopped(p1) && !is_stopped(p2)) 46 return (p1); 47 if (!is_stopped(p1) && is_stopped(p2)) 48 return (p2); 49 50 if (p1->p_estcpu > p2->p_estcpu) 51 return (p1); 52 if (p1->p_estcpu < p2->p_estcpu) 53 return (p2); 54 55 if (p1->p_slptime < p2->p_slptime) 56 return (p1); 57 if (p1->p_slptime > p2->p_slptime) 58 return (p2); 59 60 if (p1->p_pid > p2->p_pid) 61 return (p1); 62 return (p2); 63 } 64 65 char * 66 osdep_get_name(int fd, __unused char *tty) 67 { 68 int mib[6]; 69 struct stat sb; 70 size_t len, i; 71 struct kinfo_proc2 *buf, *newbuf, *bestp; 72 char *name; 73 74 if (stat(tty, &sb) == -1) 75 return (NULL); 76 if ((mib[3] = tcgetpgrp(fd)) == -1) 77 return (NULL); 78 79 buf = NULL; 80 len = sizeof(bestp); 81 mib[0] = CTL_KERN; 82 mib[1] = KERN_PROC2; 83 mib[2] = KERN_PROC_PGRP; 84 mib[4] = sizeof (*buf); 85 mib[5] = 0; 86 87 retry: 88 if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1) 89 return (NULL); 90 91 if ((newbuf = realloc(buf, len * sizeof (*buf))) == NULL) 92 goto error; 93 buf = newbuf; 94 95 mib[5] = len / sizeof(*buf); 96 if (sysctl(mib, __arraycount(mib), buf, &len, NULL, 0) == -1) { 97 if (errno == ENOMEM) 98 goto retry; /* possible infinite loop? */ 99 goto error; 100 } 101 102 bestp = NULL; 103 for (i = 0; i < len / sizeof (*buf); i++) { 104 if (buf[i].p_tdev != sb.st_rdev) 105 continue; 106 if (bestp == NULL) 107 bestp = &buf[i]; 108 else 109 bestp = cmp_procs(&buf[i], bestp); 110 } 111 112 name = NULL; 113 if (bestp != NULL) 114 name = strdup(bestp->p_comm); 115 116 free(buf); 117 return (name); 118 119 error: 120 free(buf); 121 return (NULL); 122 } 123