1 /* $NetBSD: ibcs2_misc.c,v 1.104.6.1 2010/03/17 02:59:51 snj Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
10 *
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
41 *
42 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
43 */
44
45 /*
46 * Copyright (c) 1994, 1995, 1998 Scott Bartram
47 *
48 * This software was developed by the Computer Systems Engineering group
49 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
50 * contributed to Berkeley.
51 *
52 * All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by the University of
55 * California, Lawrence Berkeley Laboratory.
56 *
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
59 * are met:
60 * 1. Redistributions of source code must retain the above copyright
61 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
65 * 3. All advertising materials mentioning features or use of this software
66 * must display the following acknowledgement:
67 * This product includes software developed by the University of
68 * California, Berkeley and its contributors.
69 * 4. Neither the name of the University nor the names of its contributors
70 * may be used to endorse or promote products derived from this software
71 * without specific prior written permission.
72 *
73 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83 * SUCH DAMAGE.
84 *
85 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
86 *
87 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
88 */
89
90 /*
91 * IBCS2 compatibility module.
92 *
93 * IBCS2 system calls that are implemented differently in BSD are
94 * handled here.
95 */
96
97 #include <sys/cdefs.h>
98 __KERNEL_RCSID(0, "$NetBSD: ibcs2_misc.c,v 1.104.6.1 2010/03/17 02:59:51 snj Exp $");
99
100 #include <sys/param.h>
101 #include <sys/systm.h>
102 #include <sys/namei.h>
103 #include <sys/dirent.h>
104 #include <sys/proc.h>
105 #include <sys/file.h>
106 #include <sys/filedesc.h>
107 #include <sys/ioctl.h>
108 #include <sys/kernel.h>
109 #include <sys/malloc.h>
110 #include <sys/mbuf.h>
111 #include <sys/mman.h>
112 #include <sys/mount.h>
113 #include <sys/prot.h>
114 #include <sys/reboot.h>
115 #include <sys/resource.h>
116 #include <sys/resourcevar.h>
117 #include <sys/socket.h>
118 #include <sys/stat.h>
119 #include <sys/syslog.h>
120 #include <sys/time.h>
121 #include <sys/times.h>
122 #include <sys/vnode.h>
123 #include <sys/uio.h>
124 #include <sys/wait.h>
125 #include <sys/utsname.h>
126 #include <sys/unistd.h>
127 #include <sys/kauth.h>
128 #include <sys/vfs_syscalls.h>
129
130 #include <netinet/in.h>
131 #include <sys/syscallargs.h>
132
133 #include <miscfs/specfs/specdev.h>
134
135 #include <uvm/uvm_extern.h>
136 #include <sys/sysctl.h>
137
138 #if defined(__i386__)
139 #include <i386/include/reg.h>
140 #endif
141
142 #include <compat/ibcs2/ibcs2_types.h>
143 #include <compat/ibcs2/ibcs2_dirent.h>
144 #include <compat/ibcs2/ibcs2_fcntl.h>
145 #include <compat/ibcs2/ibcs2_mman.h>
146 #include <compat/ibcs2/ibcs2_time.h>
147 #include <compat/ibcs2/ibcs2_signal.h>
148 #include <compat/ibcs2/ibcs2_timeb.h>
149 #include <compat/ibcs2/ibcs2_unistd.h>
150 #include <compat/ibcs2/ibcs2_utsname.h>
151 #include <compat/ibcs2/ibcs2_util.h>
152 #include <compat/ibcs2/ibcs2_utime.h>
153 #include <compat/ibcs2/ibcs2_syscallargs.h>
154 #include <compat/ibcs2/ibcs2_sysi86.h>
155 #include <compat/ibcs2/ibcs2_exec.h>
156
157 #include <compat/sys/mount.h>
158
159 int
160 ibcs2_sys_ulimit(struct lwp *l, const struct ibcs2_sys_ulimit_args *uap, register_t *retval)
161 {
162 /* {
163 syscallarg(int) cmd;
164 syscallarg(int) newlimit;
165 } */
166 struct proc *p = l->l_proc;
167 struct ibcs2_sys_sysconf_args sysconf_ua;
168 #ifdef notyet
169 int error;
170 struct rlimit rl;
171 struct sys_setrlimit_args sra;
172 #endif
173 #define IBCS2_GETFSIZE 1
174 #define IBCS2_SETFSIZE 2
175 #define IBCS2_GETPSIZE 3
176 #define IBCS2_GETDTABLESIZE 4
177
178 switch (SCARG(uap, cmd)) {
179 case IBCS2_GETFSIZE:
180 *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
181 return 0;
182 case IBCS2_SETFSIZE: /* XXX - fix this */
183 #ifdef notyet
184 rl.rlim_cur = SCARG(uap, newlimit);
185 SCARG(&sra, which) = RLIMIT_FSIZE;
186 SCARG(&sra, rlp) = &rl;
187 error = setrlimit(p, &sra, retval);
188 if (!error)
189 *retval = p->p_rlimit[RLIMIT_FSIZE].rlim_cur;
190 else
191 DPRINTF(("failed "));
192 return error;
193 #else
194 *retval = SCARG(uap, newlimit);
195 return 0;
196 #endif
197 case IBCS2_GETPSIZE:
198 *retval = p->p_rlimit[RLIMIT_RSS].rlim_cur; /* XXX */
199 return 0;
200 case IBCS2_GETDTABLESIZE:
201 SCARG(&sysconf_ua, name) = IBCS2_SC_OPEN_MAX;
202 return ibcs2_sys_sysconf(l, &sysconf_ua, retval);
203 default:
204 return ENOSYS;
205 }
206 }
207
208 int
209 ibcs2_sys_waitsys(struct lwp *l, const struct ibcs2_sys_waitsys_args *uap, register_t *retval)
210 {
211 #if defined(__i386__)
212 /* {
213 syscallarg(int) a1;
214 syscallarg(int) a2;
215 syscallarg(int) a3;
216 } */
217 #endif
218 int error;
219 int pid, options, status, was_zombie;
220
221 #if defined(__i386__)
222 #define WAITPID_EFLAGS 0x8c4 /* OF, SF, ZF, PF */
223 if ((l->l_md.md_regs->tf_eflags & WAITPID_EFLAGS) == WAITPID_EFLAGS) {
224 /* waitpid */
225 pid = SCARG(uap, a1);
226 options = SCARG(uap, a3);
227 } else {
228 #endif
229 /* wait */
230 pid = WAIT_ANY;
231 options = 0;
232 #if defined(__i386__)
233 }
234 #endif
235
236 error = do_sys_wait(l, &pid, &status, options, NULL, &was_zombie);
237 retval[0] = pid;
238 retval[1] = status;
239 return error;
240 }
241
242 int
243 ibcs2_sys_execv(struct lwp *l, const struct ibcs2_sys_execv_args *uap, register_t *retval)
244 {
245 /* {
246 syscallarg(const char *) path;
247 syscallarg(char **) argp;
248 } */
249 struct sys_execve_args ap;
250
251 SCARG(&ap, path) = SCARG(uap, path);
252 SCARG(&ap, argp) = SCARG(uap, argp);
253 SCARG(&ap, envp) = NULL;
254
255 return sys_execve(l, &ap, retval);
256 }
257
258 int
259 ibcs2_sys_execve(struct lwp *l, const struct ibcs2_sys_execve_args *uap, register_t *retval)
260 {
261 /* {
262 syscallarg(const char *) path;
263 syscallarg(char **) argp;
264 syscallarg(char **) envp;
265 } */
266 struct sys_execve_args ap;
267
268 SCARG(&ap, path) = SCARG(uap, path);
269 SCARG(&ap, argp) = SCARG(uap, argp);
270 SCARG(&ap, envp) = SCARG(uap, envp);
271
272 return sys_execve(l, &ap, retval);
273 }
274
275 int
276 ibcs2_sys_umount(struct lwp *l, const struct ibcs2_sys_umount_args *uap, register_t *retval)
277 {
278 /* {
279 syscallarg(char *) name;
280 } */
281 struct sys_unmount_args um;
282
283 SCARG(&um, path) = SCARG(uap, name);
284 SCARG(&um, flags) = 0;
285 return sys_unmount(l, &um, retval);
286 }
287
288 int
289 ibcs2_sys_mount(struct lwp *l, const struct ibcs2_sys_mount_args *uap, register_t *retval)
290 {
291 #ifdef notyet
292 /* {
293 syscallarg(char *) special;
294 syscallarg(char *) dir;
295 syscallarg(int) flags;
296 syscallarg(int) fstype;
297 syscallarg(char *) data;
298 syscallarg(int) len;
299 } */
300 int oflags = SCARG(uap, flags), nflags, error;
301 char fsname[MFSNAMELEN];
302
303 if (oflags & (IBCS2_MS_NOSUB | IBCS2_MS_SYS5))
304 return EINVAL;
305 if ((oflags & IBCS2_MS_NEWTYPE) == 0)
306 return EINVAL;
307 nflags = 0;
308 if (oflags & IBCS2_MS_RDONLY)
309 nflags |= MNT_RDONLY;
310 if (oflags & IBCS2_MS_NOSUID)
311 nflags |= MNT_NOSUID;
312 if (oflags & IBCS2_MS_REMOUNT)
313 nflags |= MNT_UPDATE;
314 SCARG(uap, flags) = nflags;
315
316 if (error = copyinstr(SCARG(uap, type), fsname, sizeof fsname, NULL))
317 return error;
318
319 if (strncmp(fsname, "4.2", sizeof fsname) == 0) {
320 SCARG(uap, type) = (void *)STACK_ALLOC();
321 if (error = copyout("ffs", SCARG(uap, type), sizeof("ffs")))
322 return error;
323 } else if (strncmp(fsname, "nfs", sizeof fsname) == 0) {
324 struct ibcs2_nfs_args sna;
325 struct sockaddr_in sain;
326 struct nfs_args na;
327 struct sockaddr sa;
328
329 if (error = copyin(SCARG(uap, data), &sna, sizeof sna))
330 return error;
331 if (error = copyin(sna.addr, &sain, sizeof sain))
332 return error;
333 memcpy(&sa, &sain, sizeof sa);
334 sa.sa_len = sizeof(sain);
335 SCARG(uap, data) = STACK_ALLOC();
336 na.addr = (void *)((unsigned long)SCARG(uap, data) + sizeof na);
337 na.sotype = SOCK_DGRAM;
338 na.proto = IPPROTO_UDP;
339 na.fh = (nfsv2fh_t *)sna.fh;
340 na.flags = sna.flags;
341 na.wsize = sna.wsize;
342 na.rsize = sna.rsize;
343 na.timeo = sna.timeo;
344 na.retrans = sna.retrans;
345 na.hostname = sna.hostname;
346
347 if (error = copyout(&sa, na.addr, sizeof sa))
348 return error;
349 if (error = copyout(&na, SCARG(uap, data), sizeof na))
350 return error;
351 }
352 return sys_mount(p, uap, retval);
353 #else
354 return EINVAL;
355 #endif
356 }
357
358 /*
359 * Read iBCS2-style directory entries. We suck them into kernel space so
360 * that they can be massaged before being copied out to user code. Like
361 * SunOS, we squish out `empty' entries.
362 *
363 * This is quite ugly, but what do you expect from compatibility code?
364 */
365
366 int
367 ibcs2_sys_getdents(struct lwp *l, const struct ibcs2_sys_getdents_args *uap, register_t *retval)
368 {
369 /* {
370 syscallarg(int) fd;
371 syscallarg(char *) buf;
372 syscallarg(int) nbytes;
373 } */
374 struct dirent *bdp;
375 struct vnode *vp;
376 char *inp, *tbuf; /* BSD-format */
377 int len, reclen; /* BSD-format */
378 char *outp; /* iBCS2-format */
379 int resid, ibcs2_reclen;/* iBCS2-format */
380 file_t *fp;
381 struct uio auio;
382 struct iovec aiov;
383 struct ibcs2_dirent idb;
384 off_t off; /* true file offset */
385 size_t buflen;
386 int error, eofflag;
387 off_t *cookiebuf = NULL, *cookie;
388 int ncookies;
389
390 /* fd_getvnode() will use the descriptor for us */
391 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
392 return (error);
393 if ((fp->f_flag & FREAD) == 0) {
394 error = EBADF;
395 goto out1;
396 }
397 vp = fp->f_data;
398 if (vp->v_type != VDIR) {
399 error = EINVAL;
400 goto out1;
401 }
402 buflen = min(MAXBSIZE, (size_t)SCARG(uap, nbytes));
403 tbuf = malloc(buflen, M_TEMP, M_WAITOK);
404 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
405 off = fp->f_offset;
406 again:
407 aiov.iov_base = tbuf;
408 aiov.iov_len = buflen;
409 auio.uio_iov = &aiov;
410 auio.uio_iovcnt = 1;
411 auio.uio_rw = UIO_READ;
412 auio.uio_resid = buflen;
413 auio.uio_offset = off;
414 UIO_SETUP_SYSSPACE(&auio);
415 /*
416 * First we read into the malloc'ed buffer, then
417 * we massage it into user space, one record at a time.
418 */
419 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
420 &ncookies);
421 if (error)
422 goto out;
423 inp = tbuf;
424 outp = SCARG(uap, buf);
425 resid = SCARG(uap, nbytes);
426 if ((len = buflen - auio.uio_resid) == 0)
427 goto eof;
428 for (cookie = cookiebuf; len > 0; len -= reclen) {
429 bdp = (struct dirent *)inp;
430 reclen = bdp->d_reclen;
431 if (reclen & 3)
432 panic("ibcs2_getdents: bad reclen");
433 if (cookie && (*cookie >> 32) != 0) {
434 compat_offseterr(vp, "ibcs2_getdents");
435 error = EINVAL;
436 goto out;
437 }
438 if (bdp->d_fileno == 0) {
439 inp += reclen; /* it is a hole; squish it out */
440 if (cookie)
441 off = *cookie++;
442 else
443 off += reclen;
444 continue;
445 }
446 ibcs2_reclen = IBCS2_RECLEN(&idb, bdp->d_namlen);
447 if (reclen > len || resid < ibcs2_reclen) {
448 /* entry too big for buffer, so just stop */
449 outp++;
450 break;
451 }
452 if (cookie)
453 off = *cookie++; /* each entry points to the next */
454 else
455 off += reclen;
456 /*
457 * Massage in place to make a iBCS2-shaped dirent (otherwise
458 * we have to worry about touching user memory outside of
459 * the copyout() call).
460 */
461 idb.d_ino = (ibcs2_ino_t)bdp->d_fileno;
462 idb.d_off = (ibcs2_off_t)off;
463 idb.d_reclen = (u_short)ibcs2_reclen;
464 strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
465 error = copyout(&idb, outp, ibcs2_reclen);
466 if (error)
467 goto out;
468 /* advance past this real entry */
469 inp += reclen;
470 /* advance output past iBCS2-shaped entry */
471 outp += ibcs2_reclen;
472 resid -= ibcs2_reclen;
473 }
474
475 /* if we squished out the whole block, try again */
476 if (outp == SCARG(uap, buf)) {
477 if (cookiebuf)
478 free(cookiebuf, M_TEMP);
479 cookiebuf = NULL;
480 goto again;
481 }
482 fp->f_offset = off; /* update the vnode offset */
483
484 eof:
485 *retval = SCARG(uap, nbytes) - resid;
486 out:
487 VOP_UNLOCK(vp, 0);
488 if (cookiebuf)
489 free(cookiebuf, M_TEMP);
490 free(tbuf, M_TEMP);
491 out1:
492 fd_putfile(SCARG(uap, fd));
493 return (error);
494 }
495
496 int
497 ibcs2_sys_read(struct lwp *l, const struct ibcs2_sys_read_args *uap, register_t *retval)
498 {
499 /* {
500 syscallarg(int) fd;
501 syscallarg(char *) buf;
502 syscallarg(u_int) nbytes;
503 } */
504 struct dirent *bdp;
505 struct vnode *vp;
506 char *inp, *tbuf; /* BSD-format */
507 int len, reclen; /* BSD-format */
508 char *outp; /* iBCS2-format */
509 int resid, ibcs2_reclen;/* iBCS2-format */
510 file_t *fp;
511 struct uio auio;
512 struct iovec aiov;
513 struct ibcs2_direct {
514 ibcs2_ino_t ino;
515 char name[14];
516 } idb;
517 size_t buflen;
518 int error, eofflag;
519 size_t size;
520 off_t *cookiebuf = NULL, *cookie;
521 off_t off; /* true file offset */
522 int ncookies;
523
524 /* fd_getvnode() will use the descriptor for us */
525 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) {
526 if (error == EINVAL)
527 return sys_read(l, (const void *)uap, retval);
528 else
529 return error;
530 }
531 if ((fp->f_flag & FREAD) == 0) {
532 error = EBADF;
533 goto out1;
534 }
535 vp = fp->f_data;
536 if (vp->v_type != VDIR) {
537 fd_putfile(SCARG(uap, fd));
538 return sys_read(l, (const void *)uap, retval);
539 }
540 buflen = min(MAXBSIZE, max(DEV_BSIZE, (size_t)SCARG(uap, nbytes)));
541 tbuf = malloc(buflen, M_TEMP, M_WAITOK);
542 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
543 off = fp->f_offset;
544 again:
545 aiov.iov_base = tbuf;
546 aiov.iov_len = buflen;
547 auio.uio_iov = &aiov;
548 auio.uio_iovcnt = 1;
549 auio.uio_rw = UIO_READ;
550 auio.uio_resid = buflen;
551 auio.uio_offset = off;
552 UIO_SETUP_SYSSPACE(&auio);
553 /*
554 * First we read into the malloc'ed buffer, then
555 * we massage it into user space, one record at a time.
556 */
557 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
558 &ncookies);
559 if (error)
560 goto out;
561 inp = tbuf;
562 outp = SCARG(uap, buf);
563 resid = SCARG(uap, nbytes);
564 if ((len = buflen - auio.uio_resid) == 0)
565 goto eof;
566 for (cookie = cookiebuf; len > 0 && resid > 0; len -= reclen) {
567 bdp = (struct dirent *)inp;
568 reclen = bdp->d_reclen;
569 if (reclen & 3)
570 panic("ibcs2_sys_read");
571 if (cookie)
572 off = *cookie++; /* each entry points to the next */
573 else
574 off += reclen;
575 if ((off >> 32) != 0) {
576 error = EINVAL;
577 goto out;
578 }
579 if (bdp->d_fileno == 0) {
580 inp += reclen; /* it is a hole; squish it out */
581 continue;
582 }
583 ibcs2_reclen = 16;
584 if (reclen > len || resid < ibcs2_reclen) {
585 /* entry too big for buffer, so just stop */
586 outp++;
587 break;
588 }
589 /*
590 * Massage in place to make a iBCS2-shaped dirent (otherwise
591 * we have to worry about touching user memory outside of
592 * the copyout() call).
593 *
594 * TODO: if length(filename) > 14, then break filename into
595 * multiple entries and set inode = 0xffff except last
596 */
597 idb.ino = (bdp->d_fileno > 0xfffe) ? 0xfffe : bdp->d_fileno;
598 (void)copystr(bdp->d_name, idb.name, 14, &size);
599 memset(idb.name + size, 0, 14 - size);
600 error = copyout(&idb, outp, ibcs2_reclen);
601 if (error)
602 goto out;
603 /* advance past this real entry */
604 inp += reclen;
605 /* advance output past iBCS2-shaped entry */
606 outp += ibcs2_reclen;
607 resid -= ibcs2_reclen;
608 }
609 /* if we squished out the whole block, try again */
610 if (outp == SCARG(uap, buf)) {
611 if (cookiebuf)
612 free(cookiebuf, M_TEMP);
613 cookiebuf = NULL;
614 goto again;
615 }
616 fp->f_offset = off; /* update the vnode offset */
617 eof:
618 *retval = SCARG(uap, nbytes) - resid;
619 out:
620 VOP_UNLOCK(vp, 0);
621 if (cookiebuf)
622 free(cookiebuf, M_TEMP);
623 free(tbuf, M_TEMP);
624 out1:
625 fd_putfile(SCARG(uap, fd));
626 return (error);
627 }
628
629 int
630 ibcs2_sys_mknod(struct lwp *l, const struct ibcs2_sys_mknod_args *uap, register_t *retval)
631 {
632 /* {
633 syscallarg(const char *) path;
634 syscallarg(int) mode;
635 syscallarg(int) dev;
636 } */
637
638 if (S_ISFIFO(SCARG(uap, mode))) {
639 struct sys_mkfifo_args ap;
640 SCARG(&ap, path) = SCARG(uap, path);
641 SCARG(&ap, mode) = SCARG(uap, mode);
642 return sys_mkfifo(l, &ap, retval);
643 } else {
644 struct sys_mknod_args ap;
645 SCARG(&ap, path) = SCARG(uap, path);
646 SCARG(&ap, mode) = SCARG(uap, mode);
647 SCARG(&ap, dev) = SCARG(uap, dev);
648 return sys_mknod(l, &ap, retval);
649 }
650 }
651
652 int
653 ibcs2_sys_getgroups(struct lwp *l, const struct ibcs2_sys_getgroups_args *uap, register_t *retval)
654 {
655 /* {
656 syscallarg(int) gidsetsize;
657 syscallarg(ibcs2_gid_t *) gidset;
658 } */
659 ibcs2_gid_t iset[16];
660 ibcs2_gid_t *gidset;
661 unsigned int ngrps;
662 int i, n, j;
663 int error;
664
665 ngrps = kauth_cred_ngroups(l->l_cred);
666 *retval = ngrps;
667 if (SCARG(uap, gidsetsize) == 0)
668 return 0;
669 if (SCARG(uap, gidsetsize) < ngrps)
670 return EINVAL;
671
672 gidset = SCARG(uap, gidset);
673 for (i = 0; i < (n = ngrps); i += n, gidset += n) {
674 n -= i;
675 if (n > __arraycount(iset))
676 n = __arraycount(iset);
677 for (j = 0; j < n; j++)
678 iset[j] = kauth_cred_group(l->l_cred, i + j);
679 error = copyout(iset, gidset, n * sizeof(iset[0]));
680 if (error != 0)
681 return error;
682 }
683
684 return 0;
685 }
686
687 /*
688 * It is very unlikly that any problem using 16bit groups is written
689 * to allow for more than 16 of them, so don't bother trying to
690 * support that.
691 */
692 #define COMPAT_NGROUPS16 16
693
694 int
695 ibcs2_sys_setgroups(struct lwp *l, const struct ibcs2_sys_setgroups_args *uap, register_t *retval)
696 {
697 /* {
698 syscallarg(int) gidsetsize;
699 syscallarg(ibcs2_gid_t *) gidset;
700 } */
701
702 ibcs2_gid_t iset[COMPAT_NGROUPS16];
703 kauth_cred_t ncred;
704 int error;
705 gid_t grbuf[COMPAT_NGROUPS16];
706 unsigned int i, ngroups = SCARG(uap, gidsetsize);
707
708 if (ngroups > COMPAT_NGROUPS16)
709 return EINVAL;
710 error = copyin(SCARG(uap, gidset), iset, ngroups);
711 if (error != 0)
712 return error;
713
714 for (i = 0; i < ngroups; i++)
715 grbuf[i] = iset[i];
716
717 ncred = kauth_cred_alloc();
718 error = kauth_cred_setgroups(ncred, grbuf, SCARG(uap, gidsetsize),
719 -1, UIO_SYSSPACE);
720 if (error != 0) {
721 kauth_cred_free(ncred);
722 return error;
723 }
724
725 return kauth_proc_setgroups(l, ncred);
726 }
727
728 int
729 ibcs2_sys_setuid(struct lwp *l, const struct ibcs2_sys_setuid_args *uap, register_t *retval)
730 {
731 /* {
732 syscallarg(int) uid;
733 } */
734 struct sys_setuid_args sa;
735
736 SCARG(&sa, uid) = (uid_t)SCARG(uap, uid);
737 return sys_setuid(l, &sa, retval);
738 }
739
740 int
741 ibcs2_sys_setgid(struct lwp *l, const struct ibcs2_sys_setgid_args *uap, register_t *retval)
742 {
743 /* {
744 syscallarg(int) gid;
745 } */
746 struct sys_setgid_args sa;
747
748 SCARG(&sa, gid) = (gid_t)SCARG(uap, gid);
749 return sys_setgid(l, &sa, retval);
750 }
751
752 int
753 xenix_sys_ftime(struct lwp *l, const struct xenix_sys_ftime_args *uap, register_t *retval)
754 {
755 /* {
756 syscallarg(struct xenix_timeb *) tp;
757 } */
758 struct timeval tv;
759 struct xenix_timeb itb;
760
761 microtime(&tv);
762 itb.time = tv.tv_sec;
763 itb.millitm = (tv.tv_usec / 1000);
764 /* NetBSD has no kernel notion of timezone -- fake it. */
765 itb.timezone = 0;
766 itb.dstflag = 0;
767 return copyout(&itb, SCARG(uap, tp), xenix_timeb_len);
768 }
769
770 int
771 ibcs2_sys_time(struct lwp *l, const struct ibcs2_sys_time_args *uap, register_t *retval)
772 {
773 /* {
774 syscallarg(ibcs2_time_t *) tp;
775 } */
776 struct proc *p = l->l_proc;
777 struct timeval tv;
778
779 microtime(&tv);
780 *retval = tv.tv_sec;
781 if (p->p_emuldata == IBCS2_EXEC_XENIX && SCARG(uap, tp))
782 return copyout(&tv.tv_sec, SCARG(uap, tp),
783 sizeof(ibcs2_time_t));
784 else
785 return 0;
786 }
787
788 int
789 ibcs2_sys_pathconf(struct lwp *l, const struct ibcs2_sys_pathconf_args *uap, register_t *retval)
790 {
791 /* {
792 syscallarg(char *) path;
793 syscallarg(int) name;
794 } */
795 struct sys_pathconf_args bsd_ua;
796
797 SCARG(&bsd_ua, path) = SCARG(uap, path);
798 /* iBCS2 _PC_* defines are offset by one */
799 SCARG(&bsd_ua, name) = SCARG(uap, name) + 1;
800 return sys_pathconf(l, &bsd_ua, retval);
801 }
802
803 int
804 ibcs2_sys_fpathconf(struct lwp *l, const struct ibcs2_sys_fpathconf_args *uap, register_t *retval)
805 {
806 /* {
807 syscallarg(int) fd;
808 syscallarg(int) name;
809 } */
810 struct sys_fpathconf_args bsd_ua;
811
812 SCARG(&bsd_ua, fd) = SCARG(uap, fd);
813 /* iBCS2 _PC_* defines are offset by one */
814 SCARG(&bsd_ua, name) = SCARG(uap, name) + 1;
815 return sys_fpathconf(l, &bsd_ua, retval);
816 }
817
818 int
819 ibcs2_sys_sysconf(struct lwp *l, const struct ibcs2_sys_sysconf_args *uap, register_t *retval)
820 {
821 /* {
822 syscallarg(int) name;
823 } */
824 struct proc *p = l->l_proc;
825 int mib[2], value, error;
826 size_t len;
827
828 switch(SCARG(uap, name)) {
829 case IBCS2_SC_ARG_MAX:
830 mib[1] = KERN_ARGMAX;
831 break;
832
833 case IBCS2_SC_CHILD_MAX:
834 *retval = p->p_rlimit[RLIMIT_NPROC].rlim_cur;
835 return 0;
836
837 case IBCS2_SC_CLK_TCK:
838 *retval = hz;
839 return 0;
840
841 case IBCS2_SC_NGROUPS_MAX:
842 mib[1] = KERN_NGROUPS;
843 break;
844
845 case IBCS2_SC_OPEN_MAX:
846 *retval = p->p_rlimit[RLIMIT_NPROC].rlim_cur;
847 return 0;
848
849 case IBCS2_SC_JOB_CONTROL:
850 mib[1] = KERN_JOB_CONTROL;
851 break;
852
853 case IBCS2_SC_SAVED_IDS:
854 mib[1] = KERN_SAVED_IDS;
855 break;
856
857 case IBCS2_SC_VERSION:
858 mib[1] = KERN_POSIX1;
859 break;
860
861 case IBCS2_SC_PASS_MAX:
862 *retval = 128; /* XXX - should we create PASS_MAX ? */
863 return 0;
864
865 case IBCS2_SC_XOPEN_VERSION:
866 *retval = 2; /* XXX: What should that be? */
867 return 0;
868
869 default:
870 return EINVAL;
871 }
872
873 mib[0] = CTL_KERN;
874 len = sizeof(value);
875 /*
876 * calling into sysctl with superuser privs, but we don't mind,
877 * 'cause we're only querying a value.
878 */
879 error = old_sysctl(&mib[0], 2, &value, &len, NULL, 0, NULL);
880 if (error)
881 return (error);
882 *retval = value;
883 return 0;
884 }
885
886 int
887 ibcs2_sys_alarm(struct lwp *l, const struct ibcs2_sys_alarm_args *uap, register_t *retval)
888 {
889 /* {
890 syscallarg(unsigned) sec;
891 } */
892 struct proc *p = l->l_proc;
893 struct itimerval it, oit;
894 int error;
895
896 error = dogetitimer(p, ITIMER_REAL, &oit);
897 if (error != 0)
898 return error;
899
900 timerclear(&it.it_interval);
901 it.it_value.tv_sec = SCARG(uap, sec);
902 it.it_value.tv_usec = 0;
903
904 error = dosetitimer(p, ITIMER_REAL, &it);
905 if (error)
906 return error;
907
908 if (oit.it_value.tv_usec)
909 oit.it_value.tv_sec++;
910 *retval = oit.it_value.tv_sec;
911 return 0;
912 }
913
914 int
915 ibcs2_sys_getmsg(struct lwp *l, const struct ibcs2_sys_getmsg_args *uap, register_t *retval)
916 {
917 #ifdef notyet
918 /* {
919 syscallarg(int) fd;
920 syscallarg(struct ibcs2_stropts *) ctl;
921 syscallarg(struct ibcs2_stropts *) dat;
922 syscallarg(int *) flags;
923 } */
924 #endif
925
926 return 0;
927 }
928
929 int
930 ibcs2_sys_putmsg(struct lwp *l, const struct ibcs2_sys_putmsg_args *uap, register_t *retval)
931 {
932 #ifdef notyet
933 /* {
934 syscallarg(int) fd;
935 syscallarg(struct ibcs2_stropts *) ctl;
936 syscallarg(struct ibcs2_stropts *) dat;
937 syscallarg(int) flags;
938 } */
939 #endif
940
941 return 0;
942 }
943
944 int
945 ibcs2_sys_times(struct lwp *l, const struct ibcs2_sys_times_args *uap, register_t *retval)
946 {
947 /* {
948 syscallarg(struct tms *) tp;
949 } */
950 struct tms tms;
951 struct timeval t;
952 struct rusage ru, *rup;
953 #define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz))
954
955 ru = l->l_proc->p_stats->p_ru;
956 mutex_enter(l->l_proc->p_lock);
957 calcru(l->l_proc, &ru.ru_utime, &ru.ru_stime, NULL, NULL);
958 rulwps(l->l_proc, &ru);
959 mutex_exit(l->l_proc->p_lock);
960 tms.tms_utime = CONVTCK(ru.ru_utime);
961 tms.tms_stime = CONVTCK(ru.ru_stime);
962
963 rup = &l->l_proc->p_stats->p_cru;
964 tms.tms_cutime = CONVTCK(rup->ru_utime);
965 tms.tms_cstime = CONVTCK(rup->ru_stime);
966
967 microtime(&t);
968 *retval = CONVTCK(t);
969
970 return copyout(&tms, SCARG(uap, tp), sizeof(tms));
971 }
972
973 int
974 ibcs2_sys_stime(struct lwp *l, const struct ibcs2_sys_stime_args *uap, register_t *retval)
975 {
976 /* {
977 syscallarg(long *) timep;
978 } */
979 struct timeval tv;
980 int error;
981
982 error = copyin(SCARG(uap, timep), &tv.tv_sec, sizeof(long));
983 if (error)
984 return error;
985 tv.tv_usec = 0;
986 return settimeofday1(&tv, false, NULL, l, true);
987 }
988
989 int
990 ibcs2_sys_utime(struct lwp *l, const struct ibcs2_sys_utime_args *uap, register_t *retval)
991 {
992 /* {
993 syscallarg(const char *) path;
994 syscallarg(struct ibcs2_utimbuf *) buf;
995 } */
996 int error;
997 struct timeval *tptr;
998 struct timeval tp[2];
999
1000 if (SCARG(uap, buf)) {
1001 struct ibcs2_utimbuf ubuf;
1002
1003 error = copyin(SCARG(uap, buf), &ubuf, sizeof(ubuf));
1004 if (error)
1005 return error;
1006 tp[0].tv_sec = ubuf.actime;
1007 tp[0].tv_usec = 0;
1008 tp[1].tv_sec = ubuf.modtime;
1009 tp[1].tv_usec = 0;
1010 tptr = tp;
1011 } else
1012 tptr = NULL;
1013
1014 return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
1015 tptr, UIO_SYSSPACE);
1016 }
1017
1018 int
1019 ibcs2_sys_nice(struct lwp *l, const struct ibcs2_sys_nice_args *uap, register_t *retval)
1020 {
1021 /* {
1022 syscallarg(int) incr;
1023 } */
1024 struct proc *p = l->l_proc;
1025 struct sys_setpriority_args sa;
1026
1027 SCARG(&sa, which) = PRIO_PROCESS;
1028 SCARG(&sa, who) = 0;
1029 SCARG(&sa, prio) = p->p_nice - NZERO + SCARG(uap, incr);
1030 if (sys_setpriority(l, &sa, retval) != 0)
1031 return EPERM;
1032 *retval = p->p_nice - NZERO;
1033 return 0;
1034 }
1035
1036 /*
1037 * iBCS2 getpgrp, setpgrp, setsid, and setpgid
1038 */
1039
1040 int
1041 ibcs2_sys_pgrpsys(struct lwp *l, const struct ibcs2_sys_pgrpsys_args *uap, register_t *retval)
1042 {
1043 /* {
1044 syscallarg(int) type;
1045 syscallarg(void *) dummy;
1046 syscallarg(int) pid;
1047 syscallarg(int) pgid;
1048 } */
1049 struct proc *p = l->l_proc;
1050
1051 switch (SCARG(uap, type)) {
1052 case 0: /* getpgrp */
1053 mutex_enter(proc_lock);
1054 *retval = p->p_pgrp->pg_id;
1055 mutex_exit(proc_lock);
1056 return 0;
1057
1058 case 1: /* setpgrp */
1059 {
1060 struct sys_setpgid_args sa;
1061
1062 SCARG(&sa, pid) = 0;
1063 SCARG(&sa, pgid) = 0;
1064 sys_setpgid(l, &sa, retval);
1065 mutex_enter(proc_lock);
1066 *retval = p->p_pgrp->pg_id;
1067 mutex_exit(proc_lock);
1068 return 0;
1069 }
1070
1071 case 2: /* setpgid */
1072 {
1073 struct sys_setpgid_args sa;
1074
1075 SCARG(&sa, pid) = SCARG(uap, pid);
1076 SCARG(&sa, pgid) = SCARG(uap, pgid);
1077 return sys_setpgid(l, &sa, retval);
1078 }
1079
1080 case 3: /* setsid */
1081 return sys_setsid(l, NULL, retval);
1082
1083 default:
1084 return EINVAL;
1085 }
1086 }
1087
1088 /*
1089 * XXX - need to check for nested calls
1090 */
1091
1092 int
1093 ibcs2_sys_plock(struct lwp *l, const struct ibcs2_sys_plock_args *uap, register_t *retval)
1094 {
1095 /* {
1096 syscallarg(int) cmd;
1097 } */
1098 #define IBCS2_UNLOCK 0
1099 #define IBCS2_PROCLOCK 1
1100 #define IBCS2_TEXTLOCK 2
1101 #define IBCS2_DATALOCK 4
1102
1103 if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
1104 NULL) != 0)
1105 return EPERM;
1106 switch(SCARG(uap, cmd)) {
1107 case IBCS2_UNLOCK:
1108 case IBCS2_PROCLOCK:
1109 case IBCS2_TEXTLOCK:
1110 case IBCS2_DATALOCK:
1111 return 0; /* XXX - TODO */
1112 }
1113 return EINVAL;
1114 }
1115
1116 int
1117 ibcs2_sys_uadmin(struct lwp *l, const struct ibcs2_sys_uadmin_args *uap, register_t *retval)
1118 {
1119 /* {
1120 syscallarg(int) cmd;
1121 syscallarg(int) func;
1122 syscallarg(void *) data;
1123 } */
1124 int error;
1125
1126 #define SCO_A_REBOOT 1
1127 #define SCO_A_SHUTDOWN 2
1128 #define SCO_A_REMOUNT 4
1129 #define SCO_A_CLOCK 8
1130 #define SCO_A_SETCONFIG 128
1131 #define SCO_A_GETDEV 130
1132
1133 #define SCO_AD_HALT 0
1134 #define SCO_AD_BOOT 1
1135 #define SCO_AD_IBOOT 2
1136 #define SCO_AD_PWRDOWN 3
1137 #define SCO_AD_PWRNAP 4
1138
1139 #define SCO_AD_PANICBOOT 1
1140
1141 #define SCO_AD_GETBMAJ 0
1142 #define SCO_AD_GETCMAJ 1
1143
1144
1145 switch(SCARG(uap, cmd)) {
1146 case SCO_A_REBOOT:
1147 case SCO_A_SHUTDOWN:
1148 error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_REBOOT,
1149 0, NULL, NULL, NULL);
1150 if (error)
1151 return (error);
1152
1153 switch(SCARG(uap, func)) {
1154 case SCO_AD_HALT:
1155 case SCO_AD_PWRDOWN:
1156 case SCO_AD_PWRNAP:
1157 cpu_reboot(RB_HALT, NULL);
1158 case SCO_AD_BOOT:
1159 case SCO_AD_IBOOT:
1160 cpu_reboot(RB_AUTOBOOT, NULL);
1161 }
1162 return EINVAL;
1163 case SCO_A_REMOUNT:
1164 case SCO_A_CLOCK:
1165 case SCO_A_SETCONFIG:
1166 case SCO_A_GETDEV:
1167 /* XXX Use proper kauth(9) requests when updating this. */
1168 error = kauth_authorize_generic(l->l_cred,
1169 KAUTH_GENERIC_ISSUSER, NULL);
1170 if (error)
1171 return (error);
1172
1173 if (SCARG(uap, cmd) != SCO_A_GETDEV)
1174 return 0;
1175 else
1176 return EINVAL; /* XXX - TODO */
1177 }
1178 return EINVAL;
1179 }
1180
1181 int
1182 ibcs2_sys_sysfs(struct lwp *l, const struct ibcs2_sys_sysfs_args *uap, register_t *retval)
1183 {
1184 /* {
1185 syscallarg(int) cmd;
1186 syscallarg(void *) d1;
1187 syscallarg(char *) buf;
1188 } */
1189
1190 #define IBCS2_GETFSIND 1
1191 #define IBCS2_GETFSTYP 2
1192 #define IBCS2_GETNFSTYP 3
1193
1194 switch(SCARG(uap, cmd)) {
1195 case IBCS2_GETFSIND:
1196 case IBCS2_GETFSTYP:
1197 case IBCS2_GETNFSTYP:
1198 break;
1199 }
1200 return EINVAL; /* XXX - TODO */
1201 }
1202
1203 int
1204 xenix_sys_rdchk(struct lwp *l, const struct xenix_sys_rdchk_args *uap, register_t *retval)
1205 {
1206 /* {
1207 syscallarg(int) fd;
1208 } */
1209 file_t *fp;
1210 int nbytes;
1211 int error;
1212
1213 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
1214 return (EBADF);
1215 error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD, &nbytes);
1216 fd_putfile(SCARG(uap, fd));
1217
1218 if (error != 0)
1219 return error;
1220
1221 *retval = nbytes ? 1 : 0;
1222 return 0;
1223 }
1224
1225 int
1226 xenix_sys_chsize(struct lwp *l, const struct xenix_sys_chsize_args *uap, register_t *retval)
1227 {
1228 /* {
1229 syscallarg(int) fd;
1230 syscallarg(long) size;
1231 } */
1232 struct sys_ftruncate_args sa;
1233
1234 SCARG(&sa, fd) = SCARG(uap, fd);
1235 SCARG(&sa, pad) = 0;
1236 SCARG(&sa, length) = SCARG(uap, size);
1237 return sys_ftruncate(l, &sa, retval);
1238 }
1239
1240 int
1241 xenix_sys_nap(struct lwp *l, const struct xenix_sys_nap_args *uap, register_t *retval)
1242 {
1243 /* {
1244 syscallarg(long) millisec;
1245 } */
1246 int error;
1247 struct timespec rqt;
1248 struct timespec rmt;
1249
1250 rqt.tv_sec = 0;
1251 rqt.tv_nsec = SCARG(uap, millisec) * 1000;
1252 error = nanosleep1(l, &rqt, &rmt);
1253 /* If interrupted we can either report EINTR, or the time left */
1254 if (error != 0 && error != EINTR)
1255 return error;
1256 *retval = rmt.tv_nsec / 1000;
1257 return 0;
1258 }
1259
1260 /*
1261 * mmap compat code borrowed from svr4/svr4_misc.c
1262 */
1263
1264 int
1265 ibcs2_sys_mmap(struct lwp *l, const struct ibcs2_sys_mmap_args *uap, register_t *retval)
1266 {
1267 /* {
1268 syscallarg(ibcs2_void *) addr;
1269 syscallarg(ibcs2_size_t) len;
1270 syscallarg(int) prot;
1271 syscallarg(int) flags;
1272 syscallarg(int) fd;
1273 syscallarg(ibcs2_off_t) off;
1274 } */
1275 struct sys_mmap_args mm;
1276
1277 #define _MAP_NEW 0x80000000 /* XXX why? */
1278
1279 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
1280 return EINVAL;
1281 if (SCARG(uap, len) == 0)
1282 return EINVAL;
1283
1284 SCARG(&mm, prot) = SCARG(uap, prot);
1285 SCARG(&mm, len) = SCARG(uap, len);
1286 SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
1287 SCARG(&mm, fd) = SCARG(uap, fd);
1288 SCARG(&mm, addr) = SCARG(uap, addr);
1289 SCARG(&mm, pos) = SCARG(uap, off);
1290
1291 return sys_mmap(l, &mm, retval);
1292 }
1293
1294 int
1295 ibcs2_sys_memcntl(struct lwp *l, const struct ibcs2_sys_memcntl_args *uap, register_t *retval)
1296 {
1297 /* {
1298 syscallarg(ibcs2_void *) addr;
1299 syscallarg(ibcs2_size_t) len;
1300 syscallarg(int) cmd;
1301 syscallarg(ibcs2_void *) arg;
1302 syscallarg(int) attr;
1303 syscallarg(int) mask;
1304 } */
1305
1306 switch (SCARG(uap, cmd)) {
1307 case IBCS2_MC_SYNC:
1308 {
1309 struct sys___msync13_args msa;
1310
1311 SCARG(&msa, addr) = SCARG(uap, addr);
1312 SCARG(&msa, len) = SCARG(uap, len);
1313 SCARG(&msa, flags) = (int)SCARG(uap, arg);
1314
1315 return sys___msync13(l, &msa, retval);
1316 }
1317 #ifdef IBCS2_MC_ADVISE /* supported? */
1318 case IBCS2_MC_ADVISE:
1319 {
1320 struct sys_madvise_args maa;
1321
1322 SCARG(&maa, addr) = SCARG(uap, addr);
1323 SCARG(&maa, len) = SCARG(uap, len);
1324 SCARG(&maa, behav) = (int)SCARG(uap, arg);
1325
1326 return sys_madvise(l, &maa, retval);
1327 }
1328 #endif
1329 case IBCS2_MC_LOCK:
1330 case IBCS2_MC_UNLOCK:
1331 case IBCS2_MC_LOCKAS:
1332 case IBCS2_MC_UNLOCKAS:
1333 return EOPNOTSUPP;
1334 default:
1335 return ENOSYS;
1336 }
1337 }
1338
1339 int
1340 ibcs2_sys_gettimeofday(struct lwp *l, const struct ibcs2_sys_gettimeofday_args *uap, register_t *retval)
1341 {
1342 /* {
1343 syscallarg(struct timeval *) tp;
1344 } */
1345
1346 if (SCARG(uap, tp)) {
1347 struct timeval atv;
1348
1349 microtime(&atv);
1350 return copyout(&atv, SCARG(uap, tp), sizeof (atv));
1351 }
1352
1353 return 0;
1354 }
1355
1356 int
1357 ibcs2_sys_settimeofday(struct lwp *l, const struct ibcs2_sys_settimeofday_args *uap, register_t *retval)
1358 {
1359 /* {
1360 syscallarg(struct timeval *) tp;
1361 } */
1362 struct sys_settimeofday_args ap;
1363
1364 SCARG(&ap, tv) = SCARG(uap, tp);
1365 SCARG(&ap, tzp) = NULL;
1366 return sys_settimeofday(l, &ap, retval);
1367 }
1368
1369 int
1370 ibcs2_sys_scoinfo(struct lwp *l, const struct ibcs2_sys_scoinfo_args *uap, register_t *retval)
1371 {
1372 /* {
1373 syscallarg(struct scoutsname *) bp;
1374 syscallarg(int) len;
1375 } */
1376 struct scoutsname uts;
1377
1378 (void)memset(&uts, 0, sizeof(uts));
1379 (void)strncpy(uts.sysname, ostype, 8);
1380 (void)strncpy(uts.nodename, hostname, 8);
1381 (void)strncpy(uts.release, osrelease, 15);
1382 (void)strncpy(uts.kid, "kernel id 1", 19);
1383 (void)strncpy(uts.machine, machine, 8);
1384 (void)strncpy(uts.bustype, "pci", 8);
1385 (void)strncpy(uts.serial, "1234", 9);
1386 uts.origin = 0;
1387 uts.oem = 0;
1388 (void)strncpy(uts.nusers, "unlim", 8);
1389 uts.ncpu = 1;
1390
1391 return copyout(&uts, SCARG(uap, bp), sizeof(uts));
1392 }
1393
1394 #define X_LK_UNLCK 0
1395 #define X_LK_LOCK 1
1396 #define X_LK_NBLCK 20
1397 #define X_LK_RLCK 3
1398 #define X_LK_NBRLCK 4
1399 #define X_LK_GETLK 5
1400 #define X_LK_SETLK 6
1401 #define X_LK_SETLKW 7
1402 #define X_LK_TESTLK 8
1403
1404 int
1405 xenix_sys_locking(struct lwp *l, const struct xenix_sys_locking_args *uap, register_t *retval)
1406 {
1407 /* {
1408 syscallarg(int) fd;
1409 syscallarg(int) blk;
1410 syscallarg(int) size;
1411 } */
1412 struct flock fl;
1413 int cmd;
1414
1415 switch SCARG(uap, blk) {
1416 case X_LK_GETLK:
1417 case X_LK_SETLK:
1418 case X_LK_SETLKW:
1419 return ibcs2_sys_fcntl(l, (const void *)uap, retval);
1420 }
1421
1422 switch SCARG(uap, blk) {
1423 case X_LK_UNLCK:
1424 cmd = F_SETLK;
1425 fl.l_type = F_UNLCK;
1426 break;
1427 case X_LK_LOCK:
1428 cmd = F_SETLKW;
1429 fl.l_type = F_WRLCK;
1430 break;
1431 case X_LK_RLCK:
1432 cmd = F_SETLKW;
1433 fl.l_type = F_RDLCK;
1434 break;
1435 case X_LK_NBRLCK:
1436 cmd = F_SETLK;
1437 fl.l_type = F_RDLCK;
1438 break;
1439 case X_LK_NBLCK:
1440 cmd = F_SETLK;
1441 fl.l_type = F_WRLCK;
1442 break;
1443 default:
1444 return EINVAL;
1445 }
1446 fl.l_len = SCARG(uap, size);
1447 fl.l_start = 0;
1448 fl.l_whence = SEEK_CUR;
1449
1450 return do_fcntl_lock(SCARG(uap, fd), cmd, &fl);
1451 }
Cache object: aa371be5fc169a3488461ec15a1b3ed2
|