osdep-netbsd.c revision 1.1.1.9
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 <limits.h> 27#include <stdlib.h> 28#include <string.h> 29#include <unistd.h> 30 31#include "tmux.h" 32 33#define is_runnable(p) \ 34 ((p)->p_stat == LSRUN || (p)->p_stat == SIDL) 35#define is_stopped(p) \ 36 ((p)->p_stat == SSTOP || (p)->p_stat == SZOMB) 37 38struct kinfo_proc2 *cmp_procs(struct kinfo_proc2 *, struct kinfo_proc2 *); 39char *osdep_get_name(int, char *); 40char *osdep_get_cwd(int); 41struct event_base *osdep_event_init(void); 42 43struct kinfo_proc2 * 44cmp_procs(struct kinfo_proc2 *p1, struct kinfo_proc2 *p2) 45{ 46 if (is_runnable(p1) && !is_runnable(p2)) 47 return (p1); 48 if (!is_runnable(p1) && is_runnable(p2)) 49 return (p2); 50 51 if (is_stopped(p1) && !is_stopped(p2)) 52 return (p1); 53 if (!is_stopped(p1) && is_stopped(p2)) 54 return (p2); 55 56 if (p1->p_estcpu > p2->p_estcpu) 57 return (p1); 58 if (p1->p_estcpu < p2->p_estcpu) 59 return (p2); 60 61 if (p1->p_slptime < p2->p_slptime) 62 return (p1); 63 if (p1->p_slptime > p2->p_slptime) 64 return (p2); 65 66 if (p1->p_pid > p2->p_pid) 67 return (p1); 68 return (p2); 69} 70 71char * 72osdep_get_name(int fd, __unused char *tty) 73{ 74 int mib[6]; 75 struct stat sb; 76 size_t len, i; 77 struct kinfo_proc2 *buf, *newbuf, *bestp; 78 char *name; 79 80 if (stat(tty, &sb) == -1) 81 return (NULL); 82 if ((mib[3] = tcgetpgrp(fd)) == -1) 83 return (NULL); 84 85 buf = NULL; 86 len = sizeof bestp; 87 88 mib[0] = CTL_KERN; 89 mib[1] = KERN_PROC2; 90 mib[2] = KERN_PROC_PGRP; 91 mib[4] = sizeof *buf; 92 93retry: 94 mib[5] = 0; 95 96 if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1) 97 return (NULL); 98 99 if ((newbuf = realloc(buf, len)) == NULL) 100 goto error; 101 buf = newbuf; 102 103 mib[5] = len / (sizeof *buf); 104 if (sysctl(mib, __arraycount(mib), buf, &len, NULL, 0) == -1) { 105 if (errno == ENOMEM) 106 goto retry; 107 goto error; 108 } 109 110 bestp = NULL; 111 for (i = 0; i < len / (sizeof *buf); i++) { 112 if (buf[i].p_tdev != sb.st_rdev) 113 continue; 114 if (bestp == NULL) 115 bestp = &buf[i]; 116 else 117 bestp = cmp_procs(&buf[i], bestp); 118 } 119 120 name = NULL; 121 if (bestp != NULL) 122 name = strdup(bestp->p_comm); 123 124 free(buf); 125 return (name); 126 127error: 128 free(buf); 129 return (NULL); 130} 131 132char * 133osdep_get_cwd(int fd) 134{ 135 static char target[PATH_MAX + 1]; 136 pid_t pgrp; 137#ifdef KERN_PROC_CWD 138 int mib[4]; 139 size_t len; 140#else 141 char *path; 142 ssize_t n; 143#endif 144 145 if ((pgrp = tcgetpgrp(fd)) == -1) 146 return (NULL); 147 148#ifdef KERN_PROC_CWD 149 mib[0] = CTL_KERN; 150 mib[1] = KERN_PROC_ARGS; 151 mib[2] = pgrp; 152 mib[3] = KERN_PROC_CWD; 153 len = sizeof(target); 154 if (sysctl(mib, __arraycount(mib), target, &len, NULL, 0) == 0) 155 return (target); 156#else 157 xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp); 158 n = readlink(path, target, sizeof(target) - 1); 159 free(path); 160 if (n > 0) { 161 target[n] = '\0'; 162 return (target); 163 } 164#endif 165 166 return (NULL); 167} 168 169struct event_base * 170osdep_event_init(void) 171{ 172 return (event_init()); 173} 174