15494e770Schristos /* $OpenBSD$ */
2698d5317Sjmmv
3698d5317Sjmmv /*
4ed4e6cd4Schristos * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
5698d5317Sjmmv *
6698d5317Sjmmv * Permission to use, copy, modify, and distribute this software for any
7698d5317Sjmmv * purpose with or without fee is hereby granted, provided that the above
8698d5317Sjmmv * copyright notice and this permission notice appear in all copies.
9698d5317Sjmmv *
10698d5317Sjmmv * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11698d5317Sjmmv * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12698d5317Sjmmv * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13698d5317Sjmmv * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14698d5317Sjmmv * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15698d5317Sjmmv * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16698d5317Sjmmv * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17698d5317Sjmmv */
18698d5317Sjmmv
19698d5317Sjmmv #include <sys/param.h>
20698d5317Sjmmv #include <sys/proc.h>
21698d5317Sjmmv #include <sys/stat.h>
22698d5317Sjmmv #include <sys/sysctl.h>
23698d5317Sjmmv
24698d5317Sjmmv #include <errno.h>
25ef36e747Schristos #include <limits.h>
26698d5317Sjmmv #include <stdlib.h>
27698d5317Sjmmv #include <string.h>
28698d5317Sjmmv #include <unistd.h>
29698d5317Sjmmv
30ef36e747Schristos #include "tmux.h"
31ef36e747Schristos
32698d5317Sjmmv #define is_runnable(p) \
33698d5317Sjmmv ((p)->p_stat == LSRUN || (p)->p_stat == SIDL)
34698d5317Sjmmv #define is_stopped(p) \
35698d5317Sjmmv ((p)->p_stat == SSTOP || (p)->p_stat == SZOMB)
36698d5317Sjmmv
37698d5317Sjmmv struct kinfo_proc2 *cmp_procs(struct kinfo_proc2 *, struct kinfo_proc2 *);
38698d5317Sjmmv
39698d5317Sjmmv struct kinfo_proc2 *
cmp_procs(struct kinfo_proc2 * p1,struct kinfo_proc2 * p2)40698d5317Sjmmv cmp_procs(struct kinfo_proc2 *p1, struct kinfo_proc2 *p2)
41698d5317Sjmmv {
42698d5317Sjmmv if (is_runnable(p1) && !is_runnable(p2))
43698d5317Sjmmv return (p1);
44698d5317Sjmmv if (!is_runnable(p1) && is_runnable(p2))
45698d5317Sjmmv return (p2);
46698d5317Sjmmv
47698d5317Sjmmv if (is_stopped(p1) && !is_stopped(p2))
48698d5317Sjmmv return (p1);
49698d5317Sjmmv if (!is_stopped(p1) && is_stopped(p2))
50698d5317Sjmmv return (p2);
51698d5317Sjmmv
52698d5317Sjmmv if (p1->p_estcpu > p2->p_estcpu)
53698d5317Sjmmv return (p1);
54698d5317Sjmmv if (p1->p_estcpu < p2->p_estcpu)
55698d5317Sjmmv return (p2);
56698d5317Sjmmv
57698d5317Sjmmv if (p1->p_slptime < p2->p_slptime)
58698d5317Sjmmv return (p1);
59698d5317Sjmmv if (p1->p_slptime > p2->p_slptime)
60698d5317Sjmmv return (p2);
61698d5317Sjmmv
62698d5317Sjmmv if (p1->p_pid > p2->p_pid)
63698d5317Sjmmv return (p1);
64698d5317Sjmmv return (p2);
65698d5317Sjmmv }
66698d5317Sjmmv
67698d5317Sjmmv char *
osdep_get_name(int fd,__unused char * tty)68698d5317Sjmmv osdep_get_name(int fd, __unused char *tty)
69698d5317Sjmmv {
70698d5317Sjmmv int mib[6];
71698d5317Sjmmv struct stat sb;
72698d5317Sjmmv size_t len, i;
73698d5317Sjmmv struct kinfo_proc2 *buf, *newbuf, *bestp;
74698d5317Sjmmv char *name;
75698d5317Sjmmv
76698d5317Sjmmv if (stat(tty, &sb) == -1)
77698d5317Sjmmv return (NULL);
78698d5317Sjmmv if ((mib[3] = tcgetpgrp(fd)) == -1)
79698d5317Sjmmv return (NULL);
80698d5317Sjmmv
81698d5317Sjmmv buf = NULL;
824e179ddaSchristos len = sizeof bestp;
834e179ddaSchristos
84698d5317Sjmmv mib[0] = CTL_KERN;
85698d5317Sjmmv mib[1] = KERN_PROC2;
86698d5317Sjmmv mib[2] = KERN_PROC_PGRP;
874e179ddaSchristos mib[4] = sizeof *buf;
88698d5317Sjmmv
89698d5317Sjmmv retry:
904e179ddaSchristos mib[5] = 0;
914e179ddaSchristos
92698d5317Sjmmv if (sysctl(mib, __arraycount(mib), NULL, &len, NULL, 0) == -1)
93698d5317Sjmmv return (NULL);
94698d5317Sjmmv
954e179ddaSchristos if ((newbuf = realloc(buf, len)) == NULL)
96698d5317Sjmmv goto error;
97698d5317Sjmmv buf = newbuf;
98698d5317Sjmmv
994e179ddaSchristos mib[5] = len / (sizeof *buf);
100698d5317Sjmmv if (sysctl(mib, __arraycount(mib), buf, &len, NULL, 0) == -1) {
101698d5317Sjmmv if (errno == ENOMEM)
1024e179ddaSchristos goto retry;
103698d5317Sjmmv goto error;
104698d5317Sjmmv }
105698d5317Sjmmv
106698d5317Sjmmv bestp = NULL;
1074e179ddaSchristos for (i = 0; i < len / (sizeof *buf); i++) {
108698d5317Sjmmv if (buf[i].p_tdev != sb.st_rdev)
109698d5317Sjmmv continue;
110698d5317Sjmmv if (bestp == NULL)
111698d5317Sjmmv bestp = &buf[i];
112698d5317Sjmmv else
113698d5317Sjmmv bestp = cmp_procs(&buf[i], bestp);
114698d5317Sjmmv }
115698d5317Sjmmv
116698d5317Sjmmv name = NULL;
117698d5317Sjmmv if (bestp != NULL)
118698d5317Sjmmv name = strdup(bestp->p_comm);
119698d5317Sjmmv
120698d5317Sjmmv free(buf);
121698d5317Sjmmv return (name);
122698d5317Sjmmv
123698d5317Sjmmv error:
124698d5317Sjmmv free(buf);
125698d5317Sjmmv return (NULL);
126698d5317Sjmmv }
127d530c4d0Sjmmv
128928fc495Schristos char *
osdep_get_cwd(int fd)129928fc495Schristos osdep_get_cwd(int fd)
130928fc495Schristos {
131ef36e747Schristos static char target[PATH_MAX + 1];
132ef36e747Schristos pid_t pgrp;
133*6483eba0Schristos #ifdef KERN_PROC_CWD
134*6483eba0Schristos int mib[4];
135*6483eba0Schristos size_t len;
136*6483eba0Schristos #else
137*6483eba0Schristos char *path;
138ef36e747Schristos ssize_t n;
139*6483eba0Schristos #endif
140ef36e747Schristos
141ef36e747Schristos if ((pgrp = tcgetpgrp(fd)) == -1)
142ef36e747Schristos return (NULL);
143ef36e747Schristos
144*6483eba0Schristos #ifdef KERN_PROC_CWD
145*6483eba0Schristos mib[0] = CTL_KERN;
146*6483eba0Schristos mib[1] = KERN_PROC_ARGS;
147*6483eba0Schristos mib[2] = pgrp;
148*6483eba0Schristos mib[3] = KERN_PROC_CWD;
149*6483eba0Schristos len = sizeof(target);
150*6483eba0Schristos if (sysctl(mib, __arraycount(mib), target, &len, NULL, 0) == 0)
151*6483eba0Schristos return (target);
152*6483eba0Schristos #else
153ef36e747Schristos xasprintf(&path, "/proc/%lld/cwd", (long long) pgrp);
154ef36e747Schristos n = readlink(path, target, sizeof(target) - 1);
155ef36e747Schristos free(path);
156ef36e747Schristos if (n > 0) {
157ef36e747Schristos target[n] = '\0';
158ef36e747Schristos return (target);
159ef36e747Schristos }
160*6483eba0Schristos #endif
161ef36e747Schristos
162928fc495Schristos return (NULL);
163928fc495Schristos }
164928fc495Schristos
165d530c4d0Sjmmv struct event_base *
osdep_event_init(void)166d530c4d0Sjmmv osdep_event_init(void)
167d530c4d0Sjmmv {
168d530c4d0Sjmmv return (event_init());
169d530c4d0Sjmmv }
170