1 /* $MirOS: src/sys/compat/openbsd/openbsd_timet.c,v 1.3 2008/11/08 23:04:15 tg Exp $ */
2 
3 /*-
4  * Copyright (c) 2004
5  *	Thorsten "mirabilos" Glaser <tg@mirbsd.org>
6  *
7  * Licensee is hereby permitted to deal in this work without restric-
8  * tion, including unlimited rights to use, publicly perform, modify,
9  * merge, distribute, sell, give away or sublicence, provided all co-
10  * pyright notices above, these terms and the disclaimer are retained
11  * in all redistributions or reproduced in accompanying documentation
12  * or other materials provided with binary redistributions.
13  *
14  * All advertising materials mentioning features or use of this soft-
15  * ware must display the following acknowledgement:
16  *	This product includes material provided by Thorsten Glaser.
17  *
18  * Licensor offers the work "AS IS" and WITHOUT WARRANTY of any kind,
19  * express, or implied, to the maximum extent permitted by applicable
20  * law, without malicious intent or gross negligence; in no event may
21  * licensor, an author or contributor be held liable for any indirect
22  * or other damage, or direct damage except proven a consequence of a
23  * direct error of said person and intended use of this work, loss or
24  * other issues arising in any way out of its use, even if advised of
25  * the possibility of such damage or existence of a nontrivial bug.
26  */
27 
28 #include <sys/param.h>
29 #include <sys/syscall.h>
30 #include <sys/signalvar.h>
31 #include <sys/mount.h>
32 #include <sys/fcntl.h>
33 #include <sys/exec.h>
34 #include <sys/exec_olf.h>
35 #include <sys/malloc.h>
36 #include <compat/common/compat_util.h>
37 #include <compat/common/kern_gen.h>
38 #include <compat/openbsd/compat_openbsd.h>
39 #include <compat/openbsd/openbsd_syscallargs.h>
40 
41 
42 extern int sys_select(struct proc *, void *, register_t *);
43 extern int sys_utimes(struct proc *, void *, register_t *);
44 extern int sys_adjtime(struct proc *, void *, register_t *);
45 extern int sys_futimes(struct proc *, void *, register_t *);
46 
47 
48 int
compat_35_sys_select(struct proc * p,void * v,register_t * retval)49 compat_35_sys_select(struct proc *p, void *v, register_t *retval)
50 {
51 	struct compat_35_sys_select_args /* {
52 		syscallarg(int) nd;
53 		syscallarg(fd_set *) in;
54 		syscallarg(fd_set *) ou;
55 		syscallarg(fd_set *) ex;
56 		syscallarg(struct timeval_compat *) tv;
57 	} */ *uap = v;
58 	struct sys_select_args {
59 		syscallarg(int) nd;
60 		syscallarg(fd_set *) in;
61 		syscallarg(fd_set *) ou;
62 		syscallarg(fd_set *) ex;
63 		syscallarg(struct timeval *) tv;
64 	} bap;
65 	struct timeval tv, *tvp = NULL;
66 	struct timeval_compat ctv;
67 	caddr_t sg;
68 	int error;
69 
70 	SCARG(&bap, nd) = SCARG(uap, nd);
71 	SCARG(&bap, in) = SCARG(uap, in);
72 	SCARG(&bap, ou) = SCARG(uap, ou);
73 	SCARG(&bap, ex) = SCARG(uap, ex);
74 
75 	if (SCARG(uap, tv) != NULL) {
76 		sg = stackgap_init(p->p_emul);
77 		tvp = stackgap_alloc(&sg, sizeof(tv));
78 
79 		if ((error = copyin((void *)SCARG(uap, tv),
80 		    (void *)&ctv, sizeof(ctv))))
81 			return error;
82 		tv.tv_sec = ctv.tv_sec;
83 		tv.tv_usec = ctv.tv_usec;
84 		if ((error = copyout(&tv, tvp, sizeof(tv))))
85 			return error;
86 	}
87 	SCARG(&bap, tv) = tvp;
88 
89 	return sys_select(p, &bap, retval);
90 }
91 
92 int
compat_35_openbsd_sys_utimes(struct proc * p,void * v,register_t * retval)93 compat_35_openbsd_sys_utimes(struct proc *p, void *v, register_t *retval)
94 {
95 	struct compat_35_openbsd_sys_utimes_args /* {
96 		syscallarg(const char *) path;
97 		syscallarg(const struct timeval_compat *) tptr;
98 	} */ *uap = v;
99 	struct sys_utimes_args {
100 		syscallarg(const char *) path;
101 		syscallarg(const struct timeval *) tptr;
102 	} bap;
103 	struct timeval tv[2], *tvp = NULL;
104 	struct timeval_compat ctv[2];
105 	caddr_t sg = stackgap_init(p->p_emul);
106 	int error;
107 
108 	OPENBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
109 	SCARG(&bap, path) = SCARG(uap, path);
110 	if (SCARG(uap, tptr) != NULL) {
111 		tvp = stackgap_alloc(&sg, sizeof(tv));
112 
113 		if ((error = copyin((void *)SCARG(uap, tptr),
114 		    (void *)ctv, sizeof(ctv))))
115 			return error;
116 		tv[0].tv_sec = ctv[0].tv_sec;
117 		tv[0].tv_usec = ctv[0].tv_usec;
118 		tv[1].tv_sec = ctv[1].tv_sec;
119 		tv[1].tv_usec = ctv[1].tv_usec;
120 		if ((error = copyout(tv, tvp, sizeof(tv))))
121 			return error;
122 	}
123 	SCARG(&bap, tptr) = tvp;
124 
125 	return sys_utimes(p, &bap, retval);
126 }
127 
128 int
compat_35_sys_adjtime(struct proc * p,void * v,register_t * retval)129 compat_35_sys_adjtime(struct proc *p, void *v, register_t *retval)
130 {
131 	struct compat_35_sys_adjtime_args /* {
132 		syscallarg(const struct timeval_compat *) delta;
133 		syscallarg(struct timeval_compat *) olddelta;
134 	} */ *uap = v;
135 	struct sys_adjtime_args {
136 		syscallarg(const struct timeval *) delta;
137 		syscallarg(struct timeval *) olddelta;
138 	} bap;
139 	struct timeval tv, *tvp1 = NULL, *tvp2 = NULL;
140 	struct timeval_compat ctv;
141 	caddr_t sg = stackgap_init(p->p_emul);
142 	int error;
143 
144 	if (SCARG(uap, olddelta) != NULL)
145 		tvp2 = stackgap_alloc(&sg, sizeof(tv));
146 	SCARG(&bap, olddelta) = tvp2;
147 
148 	if (SCARG(uap, delta) != NULL) {
149 		tvp1 = stackgap_alloc(&sg, sizeof(tv));
150 
151 		if ((error = copyin((void *)SCARG(uap, delta),
152 		    (void *)&ctv, sizeof(ctv))))
153 			return error;
154 		tv.tv_sec = ctv.tv_sec;
155 		tv.tv_usec = ctv.tv_usec;
156 		if ((error = copyout(&tv, tvp1, sizeof(tv))))
157 			return error;
158 	}
159 	SCARG(&bap, delta) = tvp1;
160 
161 	if ((error = sys_adjtime(p, &bap, retval)))
162 		return error;
163 
164 	if (SCARG(uap, olddelta) != NULL) {
165 		if ((error = copyin(tvp2, (void *)&tv, sizeof(tv))))
166 			return error;
167 		ctv.tv_sec = __BOUNDLONG(tv.tv_sec);
168 		ctv.tv_usec = tv.tv_usec;
169 		if ((error = copyout(&ctv, SCARG(uap, olddelta), sizeof(ctv))))
170 			return error;
171 	}
172 
173 	return error;
174 }
175 
176 int
compat_35_sys_futimes(struct proc * p,void * v,register_t * retval)177 compat_35_sys_futimes(struct proc *p, void *v, register_t *retval)
178 {
179 	struct compat_35_sys_futimes_args /* {
180 		syscallarg(int) fd;
181 		syscallarg(const struct timeval_compat *) tptr;
182 	} */ *uap = v;
183 	struct sys_futimes_args {
184 		syscallarg(int) fd;
185 		syscallarg(const struct timeval *) tptr;
186 	} bap;
187 	struct timeval tv[2], *tvp = NULL;
188 	struct timeval_compat ctv[2];
189 	caddr_t sg;
190 	int error;
191 
192 	SCARG(&bap, fd) = SCARG(uap, fd);
193 	if (SCARG(uap, tptr) != NULL) {
194 		sg = stackgap_init(p->p_emul);
195 		tvp = stackgap_alloc(&sg, sizeof(tv));
196 
197 		if ((error = copyin((void *)SCARG(uap, tptr),
198 		    (void *)ctv, sizeof(ctv))))
199 			return error;
200 		tv[0].tv_sec = ctv[0].tv_sec;
201 		tv[0].tv_usec = ctv[0].tv_usec;
202 		tv[1].tv_sec = ctv[1].tv_sec;
203 		tv[1].tv_usec = ctv[1].tv_usec;
204 		if ((error = copyout(tv, tvp, sizeof(tv))))
205 			return error;
206 	}
207 	SCARG(&bap, tptr) = tvp;
208 
209 	return sys_futimes(p, &bap, retval);
210 }
211