xref: /netbsd-src/sys/compat/common/kern_select_50.c (revision 6cf6fe02a981b55727c49c3d37b0d8191a98c0ee)
1 /*	$NetBSD: kern_select_50.c,v 1.1 2011/01/17 15:57:04 pooka Exp $	*/
2 
3 /*-
4  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Christos Zoulas.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: kern_select_50.c,v 1.1 2011/01/17 15:57:04 pooka Exp $");
33 
34 #include <sys/param.h>
35 #include <sys/event.h>
36 #include <sys/poll.h>
37 #include <sys/select.h>
38 #include <sys/time.h>
39 #include <sys/syscallargs.h>
40 
41 #include <compat/sys/time.h>
42 
43 static int
44 compat_50_kevent_fetch_timeout(const void *src, void *dest, size_t length)
45 {
46 	struct timespec50 ts50;
47 	int error;
48 
49 	KASSERT(length == sizeof(struct timespec));
50 
51 	error = copyin(src, &ts50, sizeof(ts50));
52 	if (error)
53 		return error;
54 	timespec50_to_timespec(&ts50, (struct timespec *)dest);
55 	return 0;
56 }
57 
58 int
59 compat_50_sys_kevent(struct lwp *l, const struct compat_50_sys_kevent_args *uap,
60     register_t *retval)
61 {
62 	/* {
63 		syscallarg(int) fd;
64 		syscallarg(keventp_t) changelist;
65 		syscallarg(size_t) nchanges;
66 		syscallarg(keventp_t) eventlist;
67 		syscallarg(size_t) nevents;
68 		syscallarg(struct timespec50) timeout;
69 	} */
70 	static const struct kevent_ops compat_50_kevent_ops = {
71 		.keo_private = NULL,
72 		.keo_fetch_timeout = compat_50_kevent_fetch_timeout,
73 		.keo_fetch_changes = kevent_fetch_changes,
74 		.keo_put_events = kevent_put_events,
75 	};
76 
77 	return kevent1(retval, SCARG(uap, fd), SCARG(uap, changelist),
78 	    SCARG(uap, nchanges), SCARG(uap, eventlist), SCARG(uap, nevents),
79 	    (const struct timespec *)(const void *)SCARG(uap, timeout),
80 	    &compat_50_kevent_ops);
81 }
82 
83 int
84 compat_50_sys_select(struct lwp *l,
85     const struct compat_50_sys_select_args *uap, register_t *retval)
86 {
87 	/* {
88 		syscallarg(int)			nd;
89 		syscallarg(fd_set *)		in;
90 		syscallarg(fd_set *)		ou;
91 		syscallarg(fd_set *)		ex;
92 		syscallarg(struct timeval50 *)	tv;
93 	} */
94 	struct timespec ats, *ts = NULL;
95 	struct timeval50 atv50;
96 	int error;
97 
98 	if (SCARG(uap, tv)) {
99 		error = copyin(SCARG(uap, tv), (void *)&atv50, sizeof(atv50));
100 		if (error)
101 			return error;
102 		ats.tv_sec = atv50.tv_sec;
103 		ats.tv_nsec = atv50.tv_usec * 1000;
104 		ts = &ats;
105 	}
106 
107 	return selcommon(retval, SCARG(uap, nd), SCARG(uap, in),
108 	    SCARG(uap, ou), SCARG(uap, ex), ts, NULL);
109 }
110 
111 int
112 compat_50_sys_pselect(struct lwp *l,
113     const struct compat_50_sys_pselect_args *uap, register_t *retval)
114 {
115 	/* {
116 		syscallarg(int)				nd;
117 		syscallarg(fd_set *)			in;
118 		syscallarg(fd_set *)			ou;
119 		syscallarg(fd_set *)			ex;
120 		syscallarg(const struct timespec50 *)	ts;
121 		syscallarg(sigset_t *)			mask;
122 	} */
123 	struct timespec50	ats50;
124 	struct timespec	ats, *ts = NULL;
125 	sigset_t	amask, *mask = NULL;
126 	int		error;
127 
128 	if (SCARG(uap, ts)) {
129 		error = copyin(SCARG(uap, ts), &ats50, sizeof(ats50));
130 		if (error)
131 			return error;
132 		timespec50_to_timespec(&ats50, &ats);
133 		ts = &ats;
134 	}
135 	if (SCARG(uap, mask) != NULL) {
136 		error = copyin(SCARG(uap, mask), &amask, sizeof(amask));
137 		if (error)
138 			return error;
139 		mask = &amask;
140 	}
141 
142 	return selcommon(retval, SCARG(uap, nd), SCARG(uap, in),
143 	    SCARG(uap, ou), SCARG(uap, ex), ts, mask);
144 }
145 
146 int
147 compat_50_sys_pollts(struct lwp *l, const struct compat_50_sys_pollts_args *uap,
148     register_t *retval)
149 {
150 	/* {
151 		syscallarg(struct pollfd *)		fds;
152 		syscallarg(u_int)			nfds;
153 		syscallarg(const struct timespec50 *)	ts;
154 		syscallarg(const sigset_t *)		mask;
155 	} */
156 	struct timespec	ats, *ts = NULL;
157 	struct timespec50 ats50;
158 	sigset_t	amask, *mask = NULL;
159 	int		error;
160 
161 	if (SCARG(uap, ts)) {
162 		error = copyin(SCARG(uap, ts), &ats50, sizeof(ats50));
163 		if (error)
164 			return error;
165 		timespec50_to_timespec(&ats50, &ats);
166 		ts = &ats;
167 	}
168 	if (SCARG(uap, mask)) {
169 		error = copyin(SCARG(uap, mask), &amask, sizeof(amask));
170 		if (error)
171 			return error;
172 		mask = &amask;
173 	}
174 
175 	return pollcommon(retval, SCARG(uap, fds), SCARG(uap, nfds), ts, mask);
176 }
177