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
195494e770Schristos #include <sys/types.h>
20*6db26757Swiz #include <sys/signal.h>
21928fc495Schristos #include <sys/proc.h>
22698d5317Sjmmv #include <sys/sysctl.h>
23698d5317Sjmmv #include <sys/stat.h>
24698d5317Sjmmv
25698d5317Sjmmv #include <errno.h>
26698d5317Sjmmv #include <stdlib.h>
27698d5317Sjmmv #include <string.h>
28698d5317Sjmmv #include <unistd.h>
29698d5317Sjmmv
309fb66d81Schristos #include "compat.h"
319fb66d81Schristos
32698d5317Sjmmv #ifndef nitems
33698d5317Sjmmv #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
34698d5317Sjmmv #endif
35698d5317Sjmmv
36698d5317Sjmmv #define is_runnable(p) \
37698d5317Sjmmv ((p)->p_stat == SRUN || (p)->p_stat == SIDL || (p)->p_stat == SONPROC)
38698d5317Sjmmv #define is_stopped(p) \
395494e770Schristos ((p)->p_stat == SSTOP || (p)->p_stat == SDEAD)
40698d5317Sjmmv
414e179ddaSchristos static struct kinfo_proc *cmp_procs(struct kinfo_proc *, struct kinfo_proc *);
42698d5317Sjmmv char *osdep_get_name(int, char *);
43928fc495Schristos char *osdep_get_cwd(int);
44d530c4d0Sjmmv struct event_base *osdep_event_init(void);
45698d5317Sjmmv
464e179ddaSchristos static struct kinfo_proc *
cmp_procs(struct kinfo_proc * p1,struct kinfo_proc * p2)47d530c4d0Sjmmv cmp_procs(struct kinfo_proc *p1, struct kinfo_proc *p2)
48698d5317Sjmmv {
49698d5317Sjmmv if (is_runnable(p1) && !is_runnable(p2))
50698d5317Sjmmv return (p1);
51698d5317Sjmmv if (!is_runnable(p1) && is_runnable(p2))
52698d5317Sjmmv return (p2);
53698d5317Sjmmv
54698d5317Sjmmv if (is_stopped(p1) && !is_stopped(p2))
55698d5317Sjmmv return (p1);
56698d5317Sjmmv if (!is_stopped(p1) && is_stopped(p2))
57698d5317Sjmmv return (p2);
58698d5317Sjmmv
59698d5317Sjmmv if (p1->p_estcpu > p2->p_estcpu)
60698d5317Sjmmv return (p1);
61698d5317Sjmmv if (p1->p_estcpu < p2->p_estcpu)
62698d5317Sjmmv return (p2);
63698d5317Sjmmv
64698d5317Sjmmv if (p1->p_slptime < p2->p_slptime)
65698d5317Sjmmv return (p1);
66698d5317Sjmmv if (p1->p_slptime > p2->p_slptime)
67698d5317Sjmmv return (p2);
68698d5317Sjmmv
69698d5317Sjmmv if ((p1->p_flag & P_SINTR) && !(p2->p_flag & P_SINTR))
70698d5317Sjmmv return (p1);
71698d5317Sjmmv if (!(p1->p_flag & P_SINTR) && (p2->p_flag & P_SINTR))
72698d5317Sjmmv return (p2);
73698d5317Sjmmv
74698d5317Sjmmv if (strcmp(p1->p_comm, p2->p_comm) < 0)
75698d5317Sjmmv return (p1);
76698d5317Sjmmv if (strcmp(p1->p_comm, p2->p_comm) > 0)
77698d5317Sjmmv return (p2);
78698d5317Sjmmv
79698d5317Sjmmv if (p1->p_pid > p2->p_pid)
80698d5317Sjmmv return (p1);
81698d5317Sjmmv return (p2);
82698d5317Sjmmv }
83698d5317Sjmmv
84698d5317Sjmmv char *
osdep_get_name(int fd,char * tty)85698d5317Sjmmv osdep_get_name(int fd, char *tty)
86698d5317Sjmmv {
87d530c4d0Sjmmv int mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PGRP, 0,
88d530c4d0Sjmmv sizeof(struct kinfo_proc), 0 };
89698d5317Sjmmv struct stat sb;
90698d5317Sjmmv size_t len;
91d530c4d0Sjmmv struct kinfo_proc *buf, *newbuf, *bestp;
92698d5317Sjmmv u_int i;
93698d5317Sjmmv char *name;
94698d5317Sjmmv
95698d5317Sjmmv buf = NULL;
96698d5317Sjmmv
97698d5317Sjmmv if (stat(tty, &sb) == -1)
98698d5317Sjmmv return (NULL);
99698d5317Sjmmv if ((mib[3] = tcgetpgrp(fd)) == -1)
100698d5317Sjmmv return (NULL);
101698d5317Sjmmv
102698d5317Sjmmv retry:
103698d5317Sjmmv if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
1045494e770Schristos goto error;
105698d5317Sjmmv len = (len * 5) / 4;
106698d5317Sjmmv
107698d5317Sjmmv if ((newbuf = realloc(buf, len)) == NULL)
108698d5317Sjmmv goto error;
109698d5317Sjmmv buf = newbuf;
110698d5317Sjmmv
111d530c4d0Sjmmv mib[5] = (int)(len / sizeof(struct kinfo_proc));
112698d5317Sjmmv if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1) {
113698d5317Sjmmv if (errno == ENOMEM)
114698d5317Sjmmv goto retry;
115698d5317Sjmmv goto error;
116698d5317Sjmmv }
117698d5317Sjmmv
118698d5317Sjmmv bestp = NULL;
119d530c4d0Sjmmv for (i = 0; i < len / sizeof (struct kinfo_proc); i++) {
120698d5317Sjmmv if ((dev_t)buf[i].p_tdev != sb.st_rdev)
121698d5317Sjmmv continue;
122698d5317Sjmmv if (bestp == NULL)
123698d5317Sjmmv bestp = &buf[i];
124698d5317Sjmmv else
125698d5317Sjmmv bestp = cmp_procs(&buf[i], bestp);
126698d5317Sjmmv }
127698d5317Sjmmv
128698d5317Sjmmv name = NULL;
129698d5317Sjmmv if (bestp != NULL)
130698d5317Sjmmv name = strdup(bestp->p_comm);
131698d5317Sjmmv
132698d5317Sjmmv free(buf);
133698d5317Sjmmv return (name);
134698d5317Sjmmv
135698d5317Sjmmv error:
136698d5317Sjmmv free(buf);
137698d5317Sjmmv return (NULL);
138698d5317Sjmmv }
139d530c4d0Sjmmv
140928fc495Schristos char *
osdep_get_cwd(int fd)141928fc495Schristos osdep_get_cwd(int fd)
142928fc495Schristos {
143928fc495Schristos int name[] = { CTL_KERN, KERN_PROC_CWD, 0 };
144*6db26757Swiz static char path[PATH_MAX];
145928fc495Schristos size_t pathlen = sizeof path;
146928fc495Schristos
147928fc495Schristos if ((name[2] = tcgetpgrp(fd)) == -1)
148928fc495Schristos return (NULL);
149928fc495Schristos if (sysctl(name, 3, path, &pathlen, NULL, 0) != 0)
150928fc495Schristos return (NULL);
151928fc495Schristos return (path);
152928fc495Schristos }
153928fc495Schristos
154d530c4d0Sjmmv struct event_base *
osdep_event_init(void)155d530c4d0Sjmmv osdep_event_init(void)
156d530c4d0Sjmmv {
157d530c4d0Sjmmv return (event_init());
158d530c4d0Sjmmv }
159