15494e770Schristos /* $OpenBSD$ */
2928fc495Schristos
3928fc495Schristos /*
4*ed4e6cd4Schristos * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
5928fc495Schristos *
6928fc495Schristos * Permission to use, copy, modify, and distribute this software for any
7928fc495Schristos * purpose with or without fee is hereby granted, provided that the above
8928fc495Schristos * copyright notice and this permission notice appear in all copies.
9928fc495Schristos *
10928fc495Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11928fc495Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12928fc495Schristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13928fc495Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14928fc495Schristos * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15928fc495Schristos * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16928fc495Schristos * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17928fc495Schristos */
18928fc495Schristos
19928fc495Schristos #include <sys/param.h>
20928fc495Schristos #include <sys/stat.h>
21928fc495Schristos #include <sys/sysctl.h>
22928fc495Schristos #include <sys/user.h>
23928fc495Schristos
24928fc495Schristos #include <err.h>
25928fc495Schristos #include <errno.h>
26928fc495Schristos #include <stdint.h>
27928fc495Schristos #include <stdlib.h>
28928fc495Schristos #include <string.h>
29928fc495Schristos #include <unistd.h>
30928fc495Schristos
31928fc495Schristos struct kinfo_proc *cmp_procs(struct kinfo_proc *, struct kinfo_proc *);
32928fc495Schristos char *osdep_get_name(int, char *);
33928fc495Schristos char *osdep_get_cwd(int);
34928fc495Schristos struct event_base *osdep_event_init(void);
35928fc495Schristos
36928fc495Schristos #ifndef nitems
37928fc495Schristos #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
38928fc495Schristos #endif
39928fc495Schristos
40928fc495Schristos #define is_runnable(p) \
41928fc495Schristos ((p)->kp_stat == SACTIVE || (p)->kp_stat == SIDL)
42928fc495Schristos #define is_stopped(p) \
43928fc495Schristos ((p)->kp_stat == SSTOP || (p)->kp_stat == SZOMB)
44928fc495Schristos
45928fc495Schristos struct kinfo_proc *
cmp_procs(struct kinfo_proc * p1,struct kinfo_proc * p2)46928fc495Schristos cmp_procs(struct kinfo_proc *p1, struct kinfo_proc *p2)
47928fc495Schristos {
48928fc495Schristos if (is_runnable(p1) && !is_runnable(p2))
49928fc495Schristos return (p1);
50928fc495Schristos if (!is_runnable(p1) && is_runnable(p2))
51928fc495Schristos return (p2);
52928fc495Schristos
53928fc495Schristos if (is_stopped(p1) && !is_stopped(p2))
54928fc495Schristos return (p1);
55928fc495Schristos if (!is_stopped(p1) && is_stopped(p2))
56928fc495Schristos return (p2);
57928fc495Schristos
58928fc495Schristos if (strcmp(p1->kp_comm, p2->kp_comm) < 0)
59928fc495Schristos return (p1);
60928fc495Schristos if (strcmp(p1->kp_comm, p2->kp_comm) > 0)
61928fc495Schristos return (p2);
62928fc495Schristos
63928fc495Schristos if (p1->kp_pid > p2->kp_pid)
64928fc495Schristos return (p1);
65928fc495Schristos return (p2);
66928fc495Schristos }
67928fc495Schristos
68928fc495Schristos char *
osdep_get_name(int fd,char * tty)69928fc495Schristos osdep_get_name(int fd, char *tty)
70928fc495Schristos {
71928fc495Schristos int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, 0 };
72928fc495Schristos struct stat sb;
73928fc495Schristos size_t len;
74928fc495Schristos struct kinfo_proc *buf, *newbuf, *bestp;
75928fc495Schristos u_int i;
76928fc495Schristos char *name;
77928fc495Schristos
78928fc495Schristos buf = NULL;
79928fc495Schristos
80928fc495Schristos if (stat(tty, &sb) == -1)
81928fc495Schristos return (NULL);
82928fc495Schristos if ((mib[3] = tcgetpgrp(fd)) == -1)
83928fc495Schristos return (NULL);
84928fc495Schristos
85928fc495Schristos retry:
86928fc495Schristos if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
87928fc495Schristos return (NULL);
88928fc495Schristos len = (len * 5) / 4;
89928fc495Schristos
90928fc495Schristos if ((newbuf = realloc(buf, len)) == NULL)
91928fc495Schristos goto error;
92928fc495Schristos buf = newbuf;
93928fc495Schristos
94928fc495Schristos if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) {
95928fc495Schristos if (errno == ENOMEM)
96928fc495Schristos goto retry;
97928fc495Schristos goto error;
98928fc495Schristos }
99928fc495Schristos
100928fc495Schristos bestp = NULL;
101928fc495Schristos for (i = 0; i < len / sizeof (struct kinfo_proc); i++) {
102928fc495Schristos if (buf[i].kp_tdev != sb.st_rdev)
103928fc495Schristos continue;
104928fc495Schristos if (bestp == NULL)
105928fc495Schristos bestp = &buf[i];
106928fc495Schristos else
107928fc495Schristos bestp = cmp_procs(&buf[i], bestp);
108928fc495Schristos }
109928fc495Schristos
110928fc495Schristos name = NULL;
111928fc495Schristos if (bestp != NULL)
112928fc495Schristos name = strdup(bestp->kp_comm);
113928fc495Schristos
114928fc495Schristos free(buf);
115928fc495Schristos return (name);
116928fc495Schristos
117928fc495Schristos error:
118928fc495Schristos free(buf);
119928fc495Schristos return (NULL);
120928fc495Schristos }
121928fc495Schristos
122928fc495Schristos char *
osdep_get_cwd(int fd)123928fc495Schristos osdep_get_cwd(int fd)
124928fc495Schristos {
125928fc495Schristos return (NULL);
126928fc495Schristos }
127928fc495Schristos
128928fc495Schristos struct event_base *
osdep_event_init(void)129928fc495Schristos osdep_event_init(void)
130928fc495Schristos {
131928fc495Schristos return (event_init());
132928fc495Schristos }
133