xref: /netbsd-src/external/bsd/tmux/dist/osdep-dragonfly.c (revision 9fb66d812c00ebfb445c0b47dea128f32aa6fe96)
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