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