Sync usage with man page.
[netbsd-mini2440.git] / sys / compat / ibcs2 / ibcs2_misc.c
blobfc79801b6e51609eb3560118df17b863569d048b
1 /* $NetBSD: ibcs2_misc.c,v 1.108 2009/08/09 22:49:00 haad Exp $ */
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
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.
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.
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.
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.
40 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
42 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
46 * Copyright (c) 1994, 1995, 1998 Scott Bartram
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.
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.
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.
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.
85 * from: Header: sun_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
87 * @(#)sun_misc.c 8.1 (Berkeley) 6/18/93
91 * IBCS2 compatibility module.
93 * IBCS2 system calls that are implemented differently in BSD are
94 * handled here.
97 #include <sys/cdefs.h>
98 __KERNEL_RCSID(0, "$NetBSD: ibcs2_misc.c,v 1.108 2009/08/09 22:49:00 haad Exp $");
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>
130 #include <netinet/in.h>
131 #include <sys/syscallargs.h>
133 #include <miscfs/specfs/specdev.h>
135 #include <uvm/uvm_extern.h>
136 #include <sys/sysctl.h>
138 #if defined(__i386__)
139 #include <i386/include/reg.h>
140 #endif
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>
157 #include <compat/sys/mount.h>
160 ibcs2_sys_ulimit(struct lwp *l, const struct ibcs2_sys_ulimit_args *uap, register_t *retval)
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
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;
209 ibcs2_sys_waitsys(struct lwp *l, const struct ibcs2_sys_waitsys_args *uap, register_t *retval)
211 #if defined(__i386__)
212 /* {
213 syscallarg(int) a1;
214 syscallarg(int) a2;
215 syscallarg(int) a3;
216 } */
217 #endif
218 int error, options, status, pid;
220 #if defined(__i386__)
221 #define WAITPID_EFLAGS 0x8c4 /* OF, SF, ZF, PF */
222 if ((l->l_md.md_regs->tf_eflags & WAITPID_EFLAGS) == WAITPID_EFLAGS) {
223 /* waitpid */
224 pid = SCARG(uap, a1);
225 options = SCARG(uap, a3);
226 } else {
227 #endif
228 /* wait */
229 pid = WAIT_ANY;
230 options = 0;
231 #if defined(__i386__)
233 #endif
235 error = do_sys_wait(&pid, &status, options, NULL);
236 retval[0] = pid;
237 retval[1] = status;
238 return error;
242 ibcs2_sys_execv(struct lwp *l, const struct ibcs2_sys_execv_args *uap, register_t *retval)
244 /* {
245 syscallarg(const char *) path;
246 syscallarg(char **) argp;
247 } */
248 struct sys_execve_args ap;
250 SCARG(&ap, path) = SCARG(uap, path);
251 SCARG(&ap, argp) = SCARG(uap, argp);
252 SCARG(&ap, envp) = NULL;
254 return sys_execve(l, &ap, retval);
258 ibcs2_sys_execve(struct lwp *l, const struct ibcs2_sys_execve_args *uap, register_t *retval)
260 /* {
261 syscallarg(const char *) path;
262 syscallarg(char **) argp;
263 syscallarg(char **) envp;
264 } */
265 struct sys_execve_args ap;
267 SCARG(&ap, path) = SCARG(uap, path);
268 SCARG(&ap, argp) = SCARG(uap, argp);
269 SCARG(&ap, envp) = SCARG(uap, envp);
271 return sys_execve(l, &ap, retval);
275 ibcs2_sys_umount(struct lwp *l, const struct ibcs2_sys_umount_args *uap, register_t *retval)
277 /* {
278 syscallarg(char *) name;
279 } */
280 struct sys_unmount_args um;
282 SCARG(&um, path) = SCARG(uap, name);
283 SCARG(&um, flags) = 0;
284 return sys_unmount(l, &um, retval);
288 ibcs2_sys_mount(struct lwp *l, const struct ibcs2_sys_mount_args *uap, register_t *retval)
290 #ifdef notyet
291 /* {
292 syscallarg(char *) special;
293 syscallarg(char *) dir;
294 syscallarg(int) flags;
295 syscallarg(int) fstype;
296 syscallarg(char *) data;
297 syscallarg(int) len;
298 } */
299 int oflags = SCARG(uap, flags), nflags, error;
300 char fsname[MFSNAMELEN];
302 if (oflags & (IBCS2_MS_NOSUB | IBCS2_MS_SYS5))
303 return EINVAL;
304 if ((oflags & IBCS2_MS_NEWTYPE) == 0)
305 return EINVAL;
306 nflags = 0;
307 if (oflags & IBCS2_MS_RDONLY)
308 nflags |= MNT_RDONLY;
309 if (oflags & IBCS2_MS_NOSUID)
310 nflags |= MNT_NOSUID;
311 if (oflags & IBCS2_MS_REMOUNT)
312 nflags |= MNT_UPDATE;
313 SCARG(uap, flags) = nflags;
315 if (error = copyinstr(SCARG(uap, type), fsname, sizeof fsname, NULL))
316 return error;
318 if (strncmp(fsname, "4.2", sizeof fsname) == 0) {
319 SCARG(uap, type) = (void *)STACK_ALLOC();
320 if (error = copyout("ffs", SCARG(uap, type), sizeof("ffs")))
321 return error;
322 } else if (strncmp(fsname, "nfs", sizeof fsname) == 0) {
323 struct ibcs2_nfs_args sna;
324 struct sockaddr_in sain;
325 struct nfs_args na;
326 struct sockaddr sa;
328 if (error = copyin(SCARG(uap, data), &sna, sizeof sna))
329 return error;
330 if (error = copyin(sna.addr, &sain, sizeof sain))
331 return error;
332 memcpy(&sa, &sain, sizeof sa);
333 sa.sa_len = sizeof(sain);
334 SCARG(uap, data) = STACK_ALLOC();
335 na.addr = (void *)((unsigned long)SCARG(uap, data) + sizeof na);
336 na.sotype = SOCK_DGRAM;
337 na.proto = IPPROTO_UDP;
338 na.fh = (nfsv2fh_t *)sna.fh;
339 na.flags = sna.flags;
340 na.wsize = sna.wsize;
341 na.rsize = sna.rsize;
342 na.timeo = sna.timeo;
343 na.retrans = sna.retrans;
344 na.hostname = sna.hostname;
346 if (error = copyout(&sa, na.addr, sizeof sa))
347 return error;
348 if (error = copyout(&na, SCARG(uap, data), sizeof na))
349 return error;
351 return sys_mount(p, uap, retval);
352 #else
353 return EINVAL;
354 #endif
358 * Read iBCS2-style directory entries. We suck them into kernel space so
359 * that they can be massaged before being copied out to user code. Like
360 * SunOS, we squish out `empty' entries.
362 * This is quite ugly, but what do you expect from compatibility code?
366 ibcs2_sys_getdents(struct lwp *l, const struct ibcs2_sys_getdents_args *uap, register_t *retval)
368 /* {
369 syscallarg(int) fd;
370 syscallarg(char *) buf;
371 syscallarg(int) nbytes;
372 } */
373 struct dirent *bdp;
374 struct vnode *vp;
375 char *inp, *tbuf; /* BSD-format */
376 int len, reclen; /* BSD-format */
377 char *outp; /* iBCS2-format */
378 int resid, ibcs2_reclen;/* iBCS2-format */
379 file_t *fp;
380 struct uio auio;
381 struct iovec aiov;
382 struct ibcs2_dirent idb;
383 off_t off; /* true file offset */
384 size_t buflen;
385 int error, eofflag;
386 off_t *cookiebuf = NULL, *cookie;
387 int ncookies;
389 /* fd_getvnode() will use the descriptor for us */
390 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
391 return (error);
392 if ((fp->f_flag & FREAD) == 0) {
393 error = EBADF;
394 goto out1;
396 vp = fp->f_data;
397 if (vp->v_type != VDIR) {
398 error = EINVAL;
399 goto out1;
401 buflen = min(MAXBSIZE, (size_t)SCARG(uap, nbytes));
402 tbuf = malloc(buflen, M_TEMP, M_WAITOK);
403 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
404 off = fp->f_offset;
405 again:
406 aiov.iov_base = tbuf;
407 aiov.iov_len = buflen;
408 auio.uio_iov = &aiov;
409 auio.uio_iovcnt = 1;
410 auio.uio_rw = UIO_READ;
411 auio.uio_resid = buflen;
412 auio.uio_offset = off;
413 UIO_SETUP_SYSSPACE(&auio);
415 * First we read into the malloc'ed buffer, then
416 * we massage it into user space, one record at a time.
418 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
419 &ncookies);
420 if (error)
421 goto out;
422 inp = tbuf;
423 outp = SCARG(uap, buf);
424 resid = SCARG(uap, nbytes);
425 if ((len = buflen - auio.uio_resid) == 0)
426 goto eof;
427 for (cookie = cookiebuf; len > 0; len -= reclen) {
428 bdp = (struct dirent *)inp;
429 reclen = bdp->d_reclen;
430 if (reclen & 3)
431 panic("ibcs2_getdents: bad reclen");
432 if (cookie && (*cookie >> 32) != 0) {
433 compat_offseterr(vp, "ibcs2_getdents");
434 error = EINVAL;
435 goto out;
437 if (bdp->d_fileno == 0) {
438 inp += reclen; /* it is a hole; squish it out */
439 if (cookie)
440 off = *cookie++;
441 else
442 off += reclen;
443 continue;
445 ibcs2_reclen = IBCS2_RECLEN(&idb, bdp->d_namlen);
446 if (reclen > len || resid < ibcs2_reclen) {
447 /* entry too big for buffer, so just stop */
448 outp++;
449 break;
451 if (cookie)
452 off = *cookie++; /* each entry points to the next */
453 else
454 off += reclen;
456 * Massage in place to make a iBCS2-shaped dirent (otherwise
457 * we have to worry about touching user memory outside of
458 * the copyout() call).
460 idb.d_ino = (ibcs2_ino_t)bdp->d_fileno;
461 idb.d_off = (ibcs2_off_t)off;
462 idb.d_reclen = (u_short)ibcs2_reclen;
463 strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
464 error = copyout(&idb, outp, ibcs2_reclen);
465 if (error)
466 goto out;
467 /* advance past this real entry */
468 inp += reclen;
469 /* advance output past iBCS2-shaped entry */
470 outp += ibcs2_reclen;
471 resid -= ibcs2_reclen;
474 /* if we squished out the whole block, try again */
475 if (outp == SCARG(uap, buf))
476 goto again;
477 fp->f_offset = off; /* update the vnode offset */
479 eof:
480 *retval = SCARG(uap, nbytes) - resid;
481 out:
482 VOP_UNLOCK(vp, 0);
483 if (cookiebuf)
484 free(cookiebuf, M_TEMP);
485 free(tbuf, M_TEMP);
486 out1:
487 fd_putfile(SCARG(uap, fd));
488 return (error);
492 ibcs2_sys_read(struct lwp *l, const struct ibcs2_sys_read_args *uap, register_t *retval)
494 /* {
495 syscallarg(int) fd;
496 syscallarg(char *) buf;
497 syscallarg(u_int) nbytes;
498 } */
499 struct dirent *bdp;
500 struct vnode *vp;
501 char *inp, *tbuf; /* BSD-format */
502 int len, reclen; /* BSD-format */
503 char *outp; /* iBCS2-format */
504 int resid, ibcs2_reclen;/* iBCS2-format */
505 file_t *fp;
506 struct uio auio;
507 struct iovec aiov;
508 struct ibcs2_direct {
509 ibcs2_ino_t ino;
510 char name[14];
511 } idb;
512 size_t buflen;
513 int error, eofflag;
514 size_t size;
515 off_t *cookiebuf = NULL, *cookie;
516 off_t off; /* true file offset */
517 int ncookies;
519 /* fd_getvnode() will use the descriptor for us */
520 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) {
521 if (error == EINVAL)
522 return sys_read(l, (const void *)uap, retval);
523 else
524 return error;
526 if ((fp->f_flag & FREAD) == 0) {
527 error = EBADF;
528 goto out1;
530 vp = fp->f_data;
531 if (vp->v_type != VDIR) {
532 fd_putfile(SCARG(uap, fd));
533 return sys_read(l, (const void *)uap, retval);
535 buflen = min(MAXBSIZE, max(DEV_BSIZE, (size_t)SCARG(uap, nbytes)));
536 tbuf = malloc(buflen, M_TEMP, M_WAITOK);
537 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
538 off = fp->f_offset;
539 again:
540 aiov.iov_base = tbuf;
541 aiov.iov_len = buflen;
542 auio.uio_iov = &aiov;
543 auio.uio_iovcnt = 1;
544 auio.uio_rw = UIO_READ;
545 auio.uio_resid = buflen;
546 auio.uio_offset = off;
547 UIO_SETUP_SYSSPACE(&auio);
549 * First we read into the malloc'ed buffer, then
550 * we massage it into user space, one record at a time.
552 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf,
553 &ncookies);
554 if (error)
555 goto out;
556 inp = tbuf;
557 outp = SCARG(uap, buf);
558 resid = SCARG(uap, nbytes);
559 if ((len = buflen - auio.uio_resid) == 0)
560 goto eof;
561 for (cookie = cookiebuf; len > 0 && resid > 0; len -= reclen) {
562 bdp = (struct dirent *)inp;
563 reclen = bdp->d_reclen;
564 if (reclen & 3)
565 panic("ibcs2_sys_read");
566 if (cookie)
567 off = *cookie++; /* each entry points to the next */
568 else
569 off += reclen;
570 if ((off >> 32) != 0) {
571 error = EINVAL;
572 goto out;
574 if (bdp->d_fileno == 0) {
575 inp += reclen; /* it is a hole; squish it out */
576 continue;
578 ibcs2_reclen = 16;
579 if (reclen > len || resid < ibcs2_reclen) {
580 /* entry too big for buffer, so just stop */
581 outp++;
582 break;
585 * Massage in place to make a iBCS2-shaped dirent (otherwise
586 * we have to worry about touching user memory outside of
587 * the copyout() call).
589 * TODO: if length(filename) > 14, then break filename into
590 * multiple entries and set inode = 0xffff except last
592 idb.ino = (bdp->d_fileno > 0xfffe) ? 0xfffe : bdp->d_fileno;
593 (void)copystr(bdp->d_name, idb.name, 14, &size);
594 memset(idb.name + size, 0, 14 - size);
595 error = copyout(&idb, outp, ibcs2_reclen);
596 if (error)
597 goto out;
598 /* advance past this real entry */
599 inp += reclen;
600 /* advance output past iBCS2-shaped entry */
601 outp += ibcs2_reclen;
602 resid -= ibcs2_reclen;
604 /* if we squished out the whole block, try again */
605 if (outp == SCARG(uap, buf))
606 goto again;
607 fp->f_offset = off; /* update the vnode offset */
608 eof:
609 *retval = SCARG(uap, nbytes) - resid;
610 out:
611 VOP_UNLOCK(vp, 0);
612 if (cookiebuf)
613 free(cookiebuf, M_TEMP);
614 free(tbuf, M_TEMP);
615 out1:
616 fd_putfile(SCARG(uap, fd));
617 return (error);
621 ibcs2_sys_mknod(struct lwp *l, const struct ibcs2_sys_mknod_args *uap, register_t *retval)
623 /* {
624 syscallarg(const char *) path;
625 syscallarg(int) mode;
626 syscallarg(int) dev;
627 } */
629 if (S_ISFIFO(SCARG(uap, mode))) {
630 struct sys_mkfifo_args ap;
631 SCARG(&ap, path) = SCARG(uap, path);
632 SCARG(&ap, mode) = SCARG(uap, mode);
633 return sys_mkfifo(l, &ap, retval);
634 } else {
635 return do_sys_mknod(l, SCARG(uap, path), SCARG(uap, mode),
636 SCARG(uap, dev), retval, UIO_USERSPACE);
641 ibcs2_sys_getgroups(struct lwp *l, const struct ibcs2_sys_getgroups_args *uap, register_t *retval)
643 /* {
644 syscallarg(int) gidsetsize;
645 syscallarg(ibcs2_gid_t *) gidset;
646 } */
647 ibcs2_gid_t iset[16];
648 ibcs2_gid_t *gidset;
649 unsigned int ngrps;
650 int i, n, j;
651 int error;
653 ngrps = kauth_cred_ngroups(l->l_cred);
654 *retval = ngrps;
655 if (SCARG(uap, gidsetsize) == 0)
656 return 0;
657 if (SCARG(uap, gidsetsize) < ngrps)
658 return EINVAL;
660 gidset = SCARG(uap, gidset);
661 for (i = 0; i < (n = ngrps); i += n, gidset += n) {
662 n -= i;
663 if (n > __arraycount(iset))
664 n = __arraycount(iset);
665 for (j = 0; j < n; j++)
666 iset[j] = kauth_cred_group(l->l_cred, i + j);
667 error = copyout(iset, gidset, n * sizeof(iset[0]));
668 if (error != 0)
669 return error;
672 return 0;
676 * It is very unlikly that any problem using 16bit groups is written
677 * to allow for more than 16 of them, so don't bother trying to
678 * support that.
680 #define COMPAT_NGROUPS16 16
683 ibcs2_sys_setgroups(struct lwp *l, const struct ibcs2_sys_setgroups_args *uap, register_t *retval)
685 /* {
686 syscallarg(int) gidsetsize;
687 syscallarg(ibcs2_gid_t *) gidset;
688 } */
690 ibcs2_gid_t iset[COMPAT_NGROUPS16];
691 kauth_cred_t ncred;
692 int error;
693 gid_t grbuf[COMPAT_NGROUPS16];
694 unsigned int i, ngroups = SCARG(uap, gidsetsize);
696 if (ngroups > COMPAT_NGROUPS16)
697 return EINVAL;
698 error = copyin(SCARG(uap, gidset), iset, ngroups);
699 if (error != 0)
700 return error;
702 for (i = 0; i < ngroups; i++)
703 grbuf[i] = iset[i];
705 ncred = kauth_cred_alloc();
706 error = kauth_cred_setgroups(ncred, grbuf, SCARG(uap, gidsetsize),
707 -1, UIO_SYSSPACE);
708 if (error != 0) {
709 kauth_cred_free(ncred);
710 return error;
713 return kauth_proc_setgroups(l, ncred);
717 ibcs2_sys_setuid(struct lwp *l, const struct ibcs2_sys_setuid_args *uap, register_t *retval)
719 /* {
720 syscallarg(int) uid;
721 } */
722 struct sys_setuid_args sa;
724 SCARG(&sa, uid) = (uid_t)SCARG(uap, uid);
725 return sys_setuid(l, &sa, retval);
729 ibcs2_sys_setgid(struct lwp *l, const struct ibcs2_sys_setgid_args *uap, register_t *retval)
731 /* {
732 syscallarg(int) gid;
733 } */
734 struct sys_setgid_args sa;
736 SCARG(&sa, gid) = (gid_t)SCARG(uap, gid);
737 return sys_setgid(l, &sa, retval);
741 xenix_sys_ftime(struct lwp *l, const struct xenix_sys_ftime_args *uap, register_t *retval)
743 /* {
744 syscallarg(struct xenix_timeb *) tp;
745 } */
746 struct timeval tv;
747 struct xenix_timeb itb;
749 microtime(&tv);
750 itb.time = tv.tv_sec;
751 itb.millitm = (tv.tv_usec / 1000);
752 /* NetBSD has no kernel notion of timezone -- fake it. */
753 itb.timezone = 0;
754 itb.dstflag = 0;
755 return copyout(&itb, SCARG(uap, tp), xenix_timeb_len);
759 ibcs2_sys_time(struct lwp *l, const struct ibcs2_sys_time_args *uap, register_t *retval)
761 /* {
762 syscallarg(ibcs2_time_t *) tp;
763 } */
764 struct proc *p = l->l_proc;
765 struct timeval tv;
767 microtime(&tv);
768 *retval = tv.tv_sec;
769 if (p->p_emuldata == IBCS2_EXEC_XENIX && SCARG(uap, tp))
770 return copyout(&tv.tv_sec, SCARG(uap, tp),
771 sizeof(ibcs2_time_t));
772 else
773 return 0;
777 ibcs2_sys_pathconf(struct lwp *l, const struct ibcs2_sys_pathconf_args *uap, register_t *retval)
779 /* {
780 syscallarg(char *) path;
781 syscallarg(int) name;
782 } */
783 struct sys_pathconf_args bsd_ua;
785 SCARG(&bsd_ua, path) = SCARG(uap, path);
786 /* iBCS2 _PC_* defines are offset by one */
787 SCARG(&bsd_ua, name) = SCARG(uap, name) + 1;
788 return sys_pathconf(l, &bsd_ua, retval);
792 ibcs2_sys_fpathconf(struct lwp *l, const struct ibcs2_sys_fpathconf_args *uap, register_t *retval)
794 /* {
795 syscallarg(int) fd;
796 syscallarg(int) name;
797 } */
798 struct sys_fpathconf_args bsd_ua;
800 SCARG(&bsd_ua, fd) = SCARG(uap, fd);
801 /* iBCS2 _PC_* defines are offset by one */
802 SCARG(&bsd_ua, name) = SCARG(uap, name) + 1;
803 return sys_fpathconf(l, &bsd_ua, retval);
807 ibcs2_sys_sysconf(struct lwp *l, const struct ibcs2_sys_sysconf_args *uap, register_t *retval)
809 /* {
810 syscallarg(int) name;
811 } */
812 struct proc *p = l->l_proc;
813 int mib[2], value, error;
814 size_t len;
816 switch(SCARG(uap, name)) {
817 case IBCS2_SC_ARG_MAX:
818 mib[1] = KERN_ARGMAX;
819 break;
821 case IBCS2_SC_CHILD_MAX:
822 *retval = p->p_rlimit[RLIMIT_NPROC].rlim_cur;
823 return 0;
825 case IBCS2_SC_CLK_TCK:
826 *retval = hz;
827 return 0;
829 case IBCS2_SC_NGROUPS_MAX:
830 mib[1] = KERN_NGROUPS;
831 break;
833 case IBCS2_SC_OPEN_MAX:
834 *retval = p->p_rlimit[RLIMIT_NPROC].rlim_cur;
835 return 0;
837 case IBCS2_SC_JOB_CONTROL:
838 mib[1] = KERN_JOB_CONTROL;
839 break;
841 case IBCS2_SC_SAVED_IDS:
842 mib[1] = KERN_SAVED_IDS;
843 break;
845 case IBCS2_SC_VERSION:
846 mib[1] = KERN_POSIX1;
847 break;
849 case IBCS2_SC_PASS_MAX:
850 *retval = 128; /* XXX - should we create PASS_MAX ? */
851 return 0;
853 case IBCS2_SC_XOPEN_VERSION:
854 *retval = 2; /* XXX: What should that be? */
855 return 0;
857 default:
858 return EINVAL;
861 mib[0] = CTL_KERN;
862 len = sizeof(value);
864 * calling into sysctl with superuser privs, but we don't mind,
865 * 'cause we're only querying a value.
867 error = old_sysctl(&mib[0], 2, &value, &len, NULL, 0, NULL);
868 if (error)
869 return (error);
870 *retval = value;
871 return 0;
875 ibcs2_sys_alarm(struct lwp *l, const struct ibcs2_sys_alarm_args *uap, register_t *retval)
877 /* {
878 syscallarg(unsigned) sec;
879 } */
880 struct proc *p = l->l_proc;
881 struct itimerval it, oit;
882 int error;
884 error = dogetitimer(p, ITIMER_REAL, &oit);
885 if (error != 0)
886 return error;
888 timerclear(&it.it_interval);
889 it.it_value.tv_sec = SCARG(uap, sec);
890 it.it_value.tv_usec = 0;
892 error = dosetitimer(p, ITIMER_REAL, &it);
893 if (error)
894 return error;
896 if (oit.it_value.tv_usec)
897 oit.it_value.tv_sec++;
898 *retval = oit.it_value.tv_sec;
899 return 0;
903 ibcs2_sys_getmsg(struct lwp *l, const struct ibcs2_sys_getmsg_args *uap, register_t *retval)
905 #ifdef notyet
906 /* {
907 syscallarg(int) fd;
908 syscallarg(struct ibcs2_stropts *) ctl;
909 syscallarg(struct ibcs2_stropts *) dat;
910 syscallarg(int *) flags;
911 } */
912 #endif
914 return 0;
918 ibcs2_sys_putmsg(struct lwp *l, const struct ibcs2_sys_putmsg_args *uap, register_t *retval)
920 #ifdef notyet
921 /* {
922 syscallarg(int) fd;
923 syscallarg(struct ibcs2_stropts *) ctl;
924 syscallarg(struct ibcs2_stropts *) dat;
925 syscallarg(int) flags;
926 } */
927 #endif
929 return 0;
933 ibcs2_sys_times(struct lwp *l, const struct ibcs2_sys_times_args *uap, register_t *retval)
935 /* {
936 syscallarg(struct tms *) tp;
937 } */
938 struct tms tms;
939 struct timeval t;
940 struct rusage ru, *rup;
941 #define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz))
943 ru = l->l_proc->p_stats->p_ru;
944 mutex_enter(l->l_proc->p_lock);
945 calcru(l->l_proc, &ru.ru_utime, &ru.ru_stime, NULL, NULL);
946 rulwps(l->l_proc, &ru);
947 mutex_exit(l->l_proc->p_lock);
948 tms.tms_utime = CONVTCK(ru.ru_utime);
949 tms.tms_stime = CONVTCK(ru.ru_stime);
951 rup = &l->l_proc->p_stats->p_cru;
952 tms.tms_cutime = CONVTCK(rup->ru_utime);
953 tms.tms_cstime = CONVTCK(rup->ru_stime);
955 microtime(&t);
956 *retval = CONVTCK(t);
958 return copyout(&tms, SCARG(uap, tp), sizeof(tms));
962 ibcs2_sys_stime(struct lwp *l, const struct ibcs2_sys_stime_args *uap, register_t *retval)
964 /* {
965 syscallarg(long *) timep;
966 } */
967 struct timeval tv;
968 int error;
970 error = copyin(SCARG(uap, timep), &tv.tv_sec, sizeof(long));
971 if (error)
972 return error;
973 tv.tv_usec = 0;
974 return settimeofday1(&tv, false, NULL, l, true);
978 ibcs2_sys_utime(struct lwp *l, const struct ibcs2_sys_utime_args *uap, register_t *retval)
980 /* {
981 syscallarg(const char *) path;
982 syscallarg(struct ibcs2_utimbuf *) buf;
983 } */
984 int error;
985 struct timeval *tptr;
986 struct timeval tp[2];
988 if (SCARG(uap, buf)) {
989 struct ibcs2_utimbuf ubuf;
991 error = copyin(SCARG(uap, buf), &ubuf, sizeof(ubuf));
992 if (error)
993 return error;
994 tp[0].tv_sec = ubuf.actime;
995 tp[0].tv_usec = 0;
996 tp[1].tv_sec = ubuf.modtime;
997 tp[1].tv_usec = 0;
998 tptr = tp;
999 } else
1000 tptr = NULL;
1002 return do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
1003 tptr, UIO_SYSSPACE);
1007 ibcs2_sys_nice(struct lwp *l, const struct ibcs2_sys_nice_args *uap, register_t *retval)
1009 /* {
1010 syscallarg(int) incr;
1011 } */
1012 struct proc *p = l->l_proc;
1013 struct sys_setpriority_args sa;
1015 SCARG(&sa, which) = PRIO_PROCESS;
1016 SCARG(&sa, who) = 0;
1017 SCARG(&sa, prio) = p->p_nice - NZERO + SCARG(uap, incr);
1018 if (sys_setpriority(l, &sa, retval) != 0)
1019 return EPERM;
1020 *retval = p->p_nice - NZERO;
1021 return 0;
1025 * iBCS2 getpgrp, setpgrp, setsid, and setpgid
1029 ibcs2_sys_pgrpsys(struct lwp *l, const struct ibcs2_sys_pgrpsys_args *uap, register_t *retval)
1031 /* {
1032 syscallarg(int) type;
1033 syscallarg(void *) dummy;
1034 syscallarg(int) pid;
1035 syscallarg(int) pgid;
1036 } */
1037 struct proc *p = l->l_proc;
1039 switch (SCARG(uap, type)) {
1040 case 0: /* getpgrp */
1041 mutex_enter(proc_lock);
1042 *retval = p->p_pgrp->pg_id;
1043 mutex_exit(proc_lock);
1044 return 0;
1046 case 1: /* setpgrp */
1048 struct sys_setpgid_args sa;
1050 SCARG(&sa, pid) = 0;
1051 SCARG(&sa, pgid) = 0;
1052 sys_setpgid(l, &sa, retval);
1053 mutex_enter(proc_lock);
1054 *retval = p->p_pgrp->pg_id;
1055 mutex_exit(proc_lock);
1056 return 0;
1059 case 2: /* setpgid */
1061 struct sys_setpgid_args sa;
1063 SCARG(&sa, pid) = SCARG(uap, pid);
1064 SCARG(&sa, pgid) = SCARG(uap, pgid);
1065 return sys_setpgid(l, &sa, retval);
1068 case 3: /* setsid */
1069 return sys_setsid(l, NULL, retval);
1071 default:
1072 return EINVAL;
1077 * See http://docsrv.sco.com:507/en/man/html.S/plock.S.html
1079 * XXX - need to check for nested calls
1083 ibcs2_sys_plock(struct lwp *l, const struct ibcs2_sys_plock_args *uap, register_t *retval)
1085 /* {
1086 syscallarg(int) cmd;
1087 } */
1088 #define IBCS2_UNLOCK 0
1089 #define IBCS2_PROCLOCK 1
1090 #define IBCS2_TEXTLOCK 2
1091 #define IBCS2_DATALOCK 4
1094 * NOTE: This is a privileged operation. Normally it would require root
1095 * access. When implementing, please make sure to use an appropriate
1096 * kauth(9) request. See the man-page for more information.
1099 switch(SCARG(uap, cmd)) {
1100 case IBCS2_UNLOCK:
1101 case IBCS2_PROCLOCK:
1102 case IBCS2_TEXTLOCK:
1103 case IBCS2_DATALOCK:
1104 return 0; /* XXX - TODO */
1106 return EINVAL;
1110 * See http://docsrv.sco.com:507/en/man/html.S/uadmin.S.html
1113 ibcs2_sys_uadmin(struct lwp *l, const struct ibcs2_sys_uadmin_args *uap, register_t *retval)
1115 /* {
1116 syscallarg(int) cmd;
1117 syscallarg(int) func;
1118 syscallarg(void *) data;
1119 } */
1120 int error;
1122 #define SCO_A_REBOOT 1
1123 #define SCO_A_SHUTDOWN 2
1124 #define SCO_A_REMOUNT 4
1125 #define SCO_A_CLOCK 8
1126 #define SCO_A_SETCONFIG 128
1127 #define SCO_A_GETDEV 130
1129 #define SCO_AD_HALT 0
1130 #define SCO_AD_BOOT 1
1131 #define SCO_AD_IBOOT 2
1132 #define SCO_AD_PWRDOWN 3
1133 #define SCO_AD_PWRNAP 4
1135 #define SCO_AD_PANICBOOT 1
1137 #define SCO_AD_GETBMAJ 0
1138 #define SCO_AD_GETCMAJ 1
1141 switch(SCARG(uap, cmd)) {
1142 case SCO_A_REBOOT:
1143 case SCO_A_SHUTDOWN:
1144 error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_REBOOT,
1145 0, NULL, NULL, NULL);
1146 if (error)
1147 return (error);
1149 switch(SCARG(uap, func)) {
1150 case SCO_AD_HALT:
1151 case SCO_AD_PWRDOWN:
1152 case SCO_AD_PWRNAP:
1153 cpu_reboot(RB_HALT, NULL);
1154 case SCO_AD_BOOT:
1155 case SCO_AD_IBOOT:
1156 cpu_reboot(RB_AUTOBOOT, NULL);
1158 return EINVAL;
1159 case SCO_A_REMOUNT:
1160 case SCO_A_CLOCK:
1161 case SCO_A_SETCONFIG:
1162 case SCO_A_GETDEV:
1164 * NOTE: These are all privileged operations, that otherwise
1165 * would require root access or similar. When implementing,
1166 * please use appropriate kauth(9) requests. See the man-page
1167 * for more information.
1170 if (SCARG(uap, cmd) != SCO_A_GETDEV)
1171 return 0;
1172 else
1173 return EINVAL; /* XXX - TODO */
1175 return EINVAL;
1179 ibcs2_sys_sysfs(struct lwp *l, const struct ibcs2_sys_sysfs_args *uap, register_t *retval)
1181 /* {
1182 syscallarg(int) cmd;
1183 syscallarg(void *) d1;
1184 syscallarg(char *) buf;
1185 } */
1187 #define IBCS2_GETFSIND 1
1188 #define IBCS2_GETFSTYP 2
1189 #define IBCS2_GETNFSTYP 3
1191 switch(SCARG(uap, cmd)) {
1192 case IBCS2_GETFSIND:
1193 case IBCS2_GETFSTYP:
1194 case IBCS2_GETNFSTYP:
1195 break;
1197 return EINVAL; /* XXX - TODO */
1201 xenix_sys_rdchk(struct lwp *l, const struct xenix_sys_rdchk_args *uap, register_t *retval)
1203 /* {
1204 syscallarg(int) fd;
1205 } */
1206 file_t *fp;
1207 int nbytes;
1208 int error;
1210 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
1211 return (EBADF);
1212 error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD, &nbytes);
1213 fd_putfile(SCARG(uap, fd));
1215 if (error != 0)
1216 return error;
1218 *retval = nbytes ? 1 : 0;
1219 return 0;
1223 xenix_sys_chsize(struct lwp *l, const struct xenix_sys_chsize_args *uap, register_t *retval)
1225 /* {
1226 syscallarg(int) fd;
1227 syscallarg(long) size;
1228 } */
1229 struct sys_ftruncate_args sa;
1231 SCARG(&sa, fd) = SCARG(uap, fd);
1232 SCARG(&sa, PAD) = 0;
1233 SCARG(&sa, length) = SCARG(uap, size);
1234 return sys_ftruncate(l, &sa, retval);
1238 xenix_sys_nap(struct lwp *l, const struct xenix_sys_nap_args *uap, register_t *retval)
1240 /* {
1241 syscallarg(long) millisec;
1242 } */
1243 int error;
1244 struct timespec rqt;
1245 struct timespec rmt;
1247 rqt.tv_sec = 0;
1248 rqt.tv_nsec = SCARG(uap, millisec) * 1000;
1249 error = nanosleep1(l, &rqt, &rmt);
1250 /* If interrupted we can either report EINTR, or the time left */
1251 if (error != 0 && error != EINTR)
1252 return error;
1253 *retval = rmt.tv_nsec / 1000;
1254 return 0;
1258 * mmap compat code borrowed from svr4/svr4_misc.c
1262 ibcs2_sys_mmap(struct lwp *l, const struct ibcs2_sys_mmap_args *uap, register_t *retval)
1264 /* {
1265 syscallarg(ibcs2_void *) addr;
1266 syscallarg(ibcs2_size_t) len;
1267 syscallarg(int) prot;
1268 syscallarg(int) flags;
1269 syscallarg(int) fd;
1270 syscallarg(ibcs2_off_t) off;
1271 } */
1272 struct sys_mmap_args mm;
1274 #define _MAP_NEW 0x80000000 /* XXX why? */
1276 if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
1277 return EINVAL;
1278 if (SCARG(uap, len) == 0)
1279 return EINVAL;
1281 SCARG(&mm, prot) = SCARG(uap, prot);
1282 SCARG(&mm, len) = SCARG(uap, len);
1283 SCARG(&mm, flags) = SCARG(uap, flags) & ~_MAP_NEW;
1284 SCARG(&mm, fd) = SCARG(uap, fd);
1285 SCARG(&mm, addr) = SCARG(uap, addr);
1286 SCARG(&mm, pos) = SCARG(uap, off);
1288 return sys_mmap(l, &mm, retval);
1292 ibcs2_sys_memcntl(struct lwp *l, const struct ibcs2_sys_memcntl_args *uap, register_t *retval)
1294 /* {
1295 syscallarg(ibcs2_void *) addr;
1296 syscallarg(ibcs2_size_t) len;
1297 syscallarg(int) cmd;
1298 syscallarg(ibcs2_void *) arg;
1299 syscallarg(int) attr;
1300 syscallarg(int) mask;
1301 } */
1303 switch (SCARG(uap, cmd)) {
1304 case IBCS2_MC_SYNC:
1306 struct sys___msync13_args msa;
1308 SCARG(&msa, addr) = SCARG(uap, addr);
1309 SCARG(&msa, len) = SCARG(uap, len);
1310 SCARG(&msa, flags) = (int)SCARG(uap, arg);
1312 return sys___msync13(l, &msa, retval);
1314 #ifdef IBCS2_MC_ADVISE /* supported? */
1315 case IBCS2_MC_ADVISE:
1317 struct sys_madvise_args maa;
1319 SCARG(&maa, addr) = SCARG(uap, addr);
1320 SCARG(&maa, len) = SCARG(uap, len);
1321 SCARG(&maa, behav) = (int)SCARG(uap, arg);
1323 return sys_madvise(l, &maa, retval);
1325 #endif
1326 case IBCS2_MC_LOCK:
1327 case IBCS2_MC_UNLOCK:
1328 case IBCS2_MC_LOCKAS:
1329 case IBCS2_MC_UNLOCKAS:
1330 return EOPNOTSUPP;
1331 default:
1332 return ENOSYS;
1337 ibcs2_sys_gettimeofday(struct lwp *l, const struct ibcs2_sys_gettimeofday_args *uap, register_t *retval)
1339 /* {
1340 syscallarg(struct timeval *) tp;
1341 } */
1343 if (SCARG(uap, tp)) {
1344 struct timeval atv;
1346 microtime(&atv);
1347 return copyout(&atv, SCARG(uap, tp), sizeof (atv));
1350 return 0;
1354 ibcs2_sys_settimeofday(struct lwp *l, const struct ibcs2_sys_settimeofday_args *uap, register_t *retval)
1356 /* {
1357 syscallarg(struct timeval *) tp;
1358 } */
1359 struct compat_50_sys_settimeofday_args ap;
1361 SCARG(&ap, tv) = SCARG(uap, tp);
1362 SCARG(&ap, tzp) = NULL;
1363 return compat_50_sys_settimeofday(l, &ap, retval);
1367 ibcs2_sys_scoinfo(struct lwp *l, const struct ibcs2_sys_scoinfo_args *uap, register_t *retval)
1369 /* {
1370 syscallarg(struct scoutsname *) bp;
1371 syscallarg(int) len;
1372 } */
1373 struct scoutsname uts;
1375 (void)memset(&uts, 0, sizeof(uts));
1376 (void)strncpy(uts.sysname, ostype, 8);
1377 (void)strncpy(uts.nodename, hostname, 8);
1378 (void)strncpy(uts.release, osrelease, 15);
1379 (void)strncpy(uts.kid, "kernel id 1", 19);
1380 (void)strncpy(uts.machine, machine, 8);
1381 (void)strncpy(uts.bustype, "pci", 8);
1382 (void)strncpy(uts.serial, "1234", 9);
1383 uts.origin = 0;
1384 uts.oem = 0;
1385 (void)strncpy(uts.nusers, "unlim", 8);
1386 uts.ncpu = 1;
1388 return copyout(&uts, SCARG(uap, bp), sizeof(uts));
1391 #define X_LK_UNLCK 0
1392 #define X_LK_LOCK 1
1393 #define X_LK_NBLCK 20
1394 #define X_LK_RLCK 3
1395 #define X_LK_NBRLCK 4
1396 #define X_LK_GETLK 5
1397 #define X_LK_SETLK 6
1398 #define X_LK_SETLKW 7
1399 #define X_LK_TESTLK 8
1402 xenix_sys_locking(struct lwp *l, const struct xenix_sys_locking_args *uap, register_t *retval)
1404 /* {
1405 syscallarg(int) fd;
1406 syscallarg(int) blk;
1407 syscallarg(int) size;
1408 } */
1409 struct flock fl;
1410 int cmd;
1412 switch SCARG(uap, blk) {
1413 case X_LK_GETLK:
1414 case X_LK_SETLK:
1415 case X_LK_SETLKW:
1416 return ibcs2_sys_fcntl(l, (const void *)uap, retval);
1419 switch SCARG(uap, blk) {
1420 case X_LK_UNLCK:
1421 cmd = F_SETLK;
1422 fl.l_type = F_UNLCK;
1423 break;
1424 case X_LK_LOCK:
1425 cmd = F_SETLKW;
1426 fl.l_type = F_WRLCK;
1427 break;
1428 case X_LK_RLCK:
1429 cmd = F_SETLKW;
1430 fl.l_type = F_RDLCK;
1431 break;
1432 case X_LK_NBRLCK:
1433 cmd = F_SETLK;
1434 fl.l_type = F_RDLCK;
1435 break;
1436 case X_LK_NBLCK:
1437 cmd = F_SETLK;
1438 fl.l_type = F_WRLCK;
1439 break;
1440 default:
1441 return EINVAL;
1443 fl.l_len = SCARG(uap, size);
1444 fl.l_start = 0;
1445 fl.l_whence = SEEK_CUR;
1447 return do_fcntl_lock(SCARG(uap, fd), cmd, &fl);