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
43static int
44compat_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
58int
59compat_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
83int
84compat_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
111int
112compat_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
146int
147compat_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