Annotation of sys/compat/sunos/sunos_misc.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: sunos_misc.c,v 1.46 2004/06/24 19:35:23 tholo Exp $ */
2: /* $NetBSD: sunos_misc.c,v 1.65 1996/04/22 01:44:31 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1992, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This software was developed by the Computer Systems Engineering group
9: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10: * contributed to Berkeley.
11: *
12: * All advertising materials mentioning features or use of this software
13: * must display the following acknowledgement:
14: * This product includes software developed by the University of
15: * California, Lawrence Berkeley Laboratory.
16: *
17: * Redistribution and use in source and binary forms, with or without
18: * modification, are permitted provided that the following conditions
19: * are met:
20: * 1. Redistributions of source code must retain the above copyright
21: * notice, this list of conditions and the following disclaimer.
22: * 2. Redistributions in binary form must reproduce the above copyright
23: * notice, this list of conditions and the following disclaimer in the
24: * documentation and/or other materials provided with the distribution.
25: * 3. Neither the name of the University nor the names of its contributors
26: * may be used to endorse or promote products derived from this software
27: * without specific prior written permission.
28: *
29: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39: * SUCH DAMAGE.
40: *
41: * @(#)sunos_misc.c 8.1 (Berkeley) 6/18/93
42: *
43: * Header: sunos_misc.c,v 1.16 93/04/07 02:46:27 torek Exp
44: */
45:
46: /*
47: * SunOS compatibility module.
48: *
49: * SunOS system calls that are implemented differently in BSD are
50: * handled here.
51: */
52:
53: #include <sys/param.h>
54: #include <sys/systm.h>
55: #include <sys/namei.h>
56: #include <sys/proc.h>
57: #include <sys/dirent.h>
58: #include <sys/file.h>
59: #include <sys/stat.h>
60: #include <sys/filedesc.h>
61: #include <sys/ioctl.h>
62: #include <sys/kernel.h>
63: #include <sys/reboot.h>
64: #include <sys/malloc.h>
65: #include <sys/mbuf.h>
66: #include <sys/mman.h>
67: #include <sys/mount.h>
68: #include <sys/ptrace.h>
69: #include <sys/resource.h>
70: #include <sys/resourcevar.h>
71: #include <sys/signal.h>
72: #include <sys/signalvar.h>
73: #include <sys/socket.h>
74: #include <sys/tty.h>
75: #include <sys/vnode.h>
76: #include <sys/uio.h>
77: #include <sys/wait.h>
78: #include <sys/utsname.h>
79: #include <sys/unistd.h>
80: #include <sys/syscallargs.h>
81: #include <sys/conf.h>
82: #include <sys/socketvar.h>
83: #include <sys/times.h>
84:
85: #include <compat/sunos/sunos.h>
86: #include <compat/sunos/sunos_syscallargs.h>
87: #include <compat/sunos/sunos_util.h>
88: #include <compat/sunos/sunos_dirent.h>
89:
90: #include <compat/common/compat_dir.h>
91:
92: #include <netinet/in.h>
93:
94: #include <miscfs/specfs/specdev.h>
95:
96: #include <nfs/rpcv2.h>
97: #include <nfs/nfsproto.h>
98: #include <nfs/nfs.h>
99:
100: #include <uvm/uvm_extern.h>
101:
102: #ifdef sun3
103: # include <machine/machdep.h> /* for prototype of reboot2() */
104: #endif
105:
106: static int sunstatfs(struct statfs *, caddr_t);
107:
108: int
109: sunos_sys_wait4(p, v, retval)
110: struct proc *p;
111: void *v;
112: register_t *retval;
113: {
114: struct sunos_sys_wait4_args *uap = v;
115: if (SCARG(uap, pid) == 0)
116: SCARG(uap, pid) = WAIT_ANY;
117: return (sys_wait4(p, uap, retval));
118: }
119:
120: int
121: sunos_sys_creat(p, v, retval)
122: struct proc *p;
123: void *v;
124: register_t *retval;
125: {
126: struct sunos_sys_creat_args *uap = v;
127: struct sys_open_args ouap;
128:
129: caddr_t sg = stackgap_init(p->p_emul);
130: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
131:
132: SCARG(&ouap, path) = SCARG(uap, path);
133: SCARG(&ouap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
134: SCARG(&ouap, mode) = SCARG(uap, mode);
135:
136: return (sys_open(p, &ouap, retval));
137: }
138:
139: int
140: sunos_sys_access(p, v, retval)
141: struct proc *p;
142: void *v;
143: register_t *retval;
144: {
145: struct sunos_sys_access_args *uap = v;
146: caddr_t sg = stackgap_init(p->p_emul);
147: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
148:
149: return (sys_access(p, uap, retval));
150: }
151:
152: int
153: sunos_sys_stat(p, v, retval)
154: struct proc *p;
155: void *v;
156: register_t *retval;
157: {
158: struct sunos_sys_stat_args *uap = v;
159: caddr_t sg = stackgap_init(p->p_emul);
160: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
161:
162: return (compat_43_sys_stat(p, uap, retval));
163: }
164:
165: int
166: sunos_sys_lstat(p, v, retval)
167: struct proc *p;
168: void *v;
169: register_t *retval;
170: {
171: struct sunos_sys_lstat_args *uap = v;
172: caddr_t sg = stackgap_init(p->p_emul);
173: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
174:
175: return (compat_43_sys_lstat(p, uap, retval));
176: }
177:
178: int
179: sunos_sys_execve(p, v, retval)
180: struct proc *p;
181: void *v;
182: register_t *retval;
183: {
184: struct sunos_sys_execve_args /* {
185: syscallarg(char *) path;
186: syscallarg(char **) argv;
187: syscallarg(char **) envp;
188: } */ *uap = v;
189: struct sys_execve_args ap;
190: caddr_t sg;
191:
192: sg = stackgap_init(p->p_emul);
193: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
194:
195: SCARG(&ap, path) = SCARG(uap, path);
196: SCARG(&ap, argp) = SCARG(uap, argp);
197: SCARG(&ap, envp) = SCARG(uap, envp);
198:
199: return (sys_execve(p, &ap, retval));
200: }
201:
202: int
203: sunos_sys_execv(p, v, retval)
204: struct proc *p;
205: void *v;
206: register_t *retval;
207: {
208: struct sunos_sys_execv_args *uap = v;
209: struct sys_execve_args ouap;
210:
211: caddr_t sg = stackgap_init(p->p_emul);
212: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
213:
214: SCARG(&ouap, path) = SCARG(uap, path);
215: SCARG(&ouap, argp) = SCARG(uap, argp);
216: SCARG(&ouap, envp) = NULL;
217:
218: return (sys_execve(p, &ouap, retval));
219: }
220:
221: int
222: sunos_sys_unmount(p, v, retval)
223: struct proc *p;
224: void *v;
225: register_t *retval;
226: {
227: struct sunos_sys_unmount_args *uap = v;
228: struct sys_unmount_args ouap;
229:
230: SCARG(&ouap, path) = SCARG(uap, path);
231: SCARG(&ouap, flags) = 0;
232:
233: return (sys_unmount(p, &ouap, retval));
234: }
235:
236: /*
237: * Conversion table for SunOS NFS mount flags.
238: */
239: static struct {
240: int sun_flg;
241: int bsd_flg;
242: } sunnfs_flgtab[] = {
243: { SUNNFS_SOFT, NFSMNT_SOFT },
244: { SUNNFS_WSIZE, NFSMNT_WSIZE },
245: { SUNNFS_RSIZE, NFSMNT_RSIZE },
246: { SUNNFS_TIMEO, NFSMNT_TIMEO },
247: { SUNNFS_RETRANS, NFSMNT_RETRANS },
248: { SUNNFS_HOSTNAME, 0 }, /* Ignored */
249: { SUNNFS_INT, NFSMNT_INT },
250: { SUNNFS_NOAC, 0 }, /* Ignored */
251: { SUNNFS_ACREGMIN, 0 }, /* Ignored */
252: { SUNNFS_ACREGMAX, 0 }, /* Ignored */
253: { SUNNFS_ACDIRMIN, 0 }, /* Ignored */
254: { SUNNFS_ACDIRMAX, 0 }, /* Ignored */
255: { SUNNFS_SECURE, 0 }, /* Ignored */
256: { SUNNFS_NOCTO, 0 }, /* Ignored */
257: { SUNNFS_POSIX, 0 } /* Ignored */
258: };
259:
260: int
261: sunos_sys_mount(p, v, retval)
262: struct proc *p;
263: void *v;
264: register_t *retval;
265: {
266: struct sunos_sys_mount_args *uap = v;
267: int oflags = SCARG(uap, flags), nflags, error;
268: char fsname[MFSNAMELEN];
269: caddr_t sg = stackgap_init(p->p_emul);
270:
271: if (oflags & (SUNM_NOSUB | SUNM_SYS5))
272: return (EINVAL);
273: if ((oflags & SUNM_NEWTYPE) == 0)
274: return (EINVAL);
275: nflags = 0;
276: if (oflags & SUNM_RDONLY)
277: nflags |= MNT_RDONLY;
278: if (oflags & SUNM_NOSUID)
279: nflags |= MNT_NOSUID;
280: if (oflags & SUNM_REMOUNT)
281: nflags |= MNT_UPDATE;
282: SCARG(uap, flags) = nflags;
283:
284: error = copyinstr((caddr_t)SCARG(uap, type), fsname,
285: sizeof fsname, (size_t *)0);
286: if (error)
287: return (error);
288:
289: if (strncmp(fsname, "4.2", sizeof fsname) == 0) {
290: SCARG(uap, type) = stackgap_alloc(&sg, sizeof("ffs"));
291: error = copyout("ffs", SCARG(uap, type), sizeof("ffs"));
292: if (error)
293: return (error);
294: } else if (strncmp(fsname, "nfs", sizeof fsname) == 0) {
295: struct sunos_nfs_args sna;
296: struct sockaddr_in sain;
297: struct nfs_args na;
298: struct sockaddr sa;
299: int n;
300:
301: error = copyin(SCARG(uap, data), &sna, sizeof sna);
302: if (error)
303: return (error);
304: error = copyin(sna.addr, &sain, sizeof sain);
305: if (error)
306: return (error);
307: bcopy(&sain, &sa, sizeof sa);
308: sa.sa_len = sizeof(sain);
309: SCARG(uap, data) = stackgap_alloc(&sg, sizeof(na));
310: na.version = NFS_ARGSVERSION;
311: na.addr = stackgap_alloc(&sg, sizeof(struct sockaddr));
312: na.addrlen = sizeof(struct sockaddr);
313: na.sotype = SOCK_DGRAM;
314: na.proto = IPPROTO_UDP;
315: na.fh = (void *)sna.fh;
316: na.fhsize = NFSX_V2FH;
317: na.flags = 0;
318: n = sizeof(sunnfs_flgtab) / sizeof(sunnfs_flgtab[0]);
319: while (--n >= 0)
320: if (sna.flags & sunnfs_flgtab[n].sun_flg)
321: na.flags |= sunnfs_flgtab[n].bsd_flg;
322: na.wsize = sna.wsize;
323: na.rsize = sna.rsize;
324: if (na.flags & NFSMNT_RSIZE) {
325: na.flags |= NFSMNT_READDIRSIZE;
326: na.readdirsize = na.rsize;
327: }
328: na.timeo = sna.timeo;
329: na.retrans = sna.retrans;
330: na.hostname = sna.hostname;
331:
332: error = copyout(&sa, na.addr, sizeof sa);
333: if (error)
334: return (error);
335: error = copyout(&na, SCARG(uap, data), sizeof na);
336: if (error)
337: return (error);
338: }
339: return (sys_mount(p, (struct sys_mount_args *)uap, retval));
340: }
341:
342: #if defined(NFSCLIENT)
343: int
344: async_daemon(p, v, retval)
345: struct proc *p;
346: void *v;
347: register_t *retval;
348: {
349: struct sys_nfssvc_args ouap;
350:
351: SCARG(&ouap, flag) = NFSSVC_BIOD;
352: SCARG(&ouap, argp) = NULL;
353:
354: return (sys_nfssvc(p, &ouap, retval));
355: }
356: #endif /* NFSCLIENT */
357:
358: int
359: sunos_sys_sigpending(p, v, retval)
360: struct proc *p;
361: void *v;
362: register_t *retval;
363: {
364: struct sunos_sys_sigpending_args *uap = v;
365: int mask = p->p_siglist & p->p_sigmask;
366:
367: return (copyout((caddr_t)&mask, (caddr_t)SCARG(uap, mask), sizeof(int)));
368: }
369:
370: /*
371: * Read Sun-style directory entries. We suck them into kernel space so
372: * that they can be massaged before being copied out to user code. Like
373: * SunOS, we squish out `empty' entries.
374: *
375: * This is quite ugly, but what do you expect from compatibility code?
376: */
377: int sunos_readdir_callback(void *, struct dirent *, off_t);
378:
379: struct sunos_readdir_callback_args {
380: caddr_t outp;
381: int resid;
382: };
383:
384: int
385: sunos_readdir_callback(arg, bdp, cookie)
386: void *arg;
387: struct dirent *bdp;
388: off_t cookie;
389: {
390: struct sunos_dirent idb;
391: struct sunos_readdir_callback_args *cb = arg;
392: int sunos_reclen;
393: int error;
394:
395: sunos_reclen = SUNOS_RECLEN(&idb, bdp->d_namlen);
396: if (cb->resid < sunos_reclen)
397: return (ENOMEM);
398:
399: idb.d_fileno = bdp->d_fileno;
400: idb.d_off = cookie;
401: idb.d_reclen = sunos_reclen;
402: idb.d_namlen = bdp->d_namlen;
403: strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name));
404:
405: if ((error = copyout((caddr_t)&idb, cb->outp, sunos_reclen)))
406: return (error);
407:
408: cb->outp += sunos_reclen;
409: cb->resid -= sunos_reclen;
410:
411: return (0);
412: }
413:
414: int
415: sunos_sys_getdents(p, v, retval)
416: struct proc *p;
417: void *v;
418: register_t *retval;
419: {
420: struct sunos_sys_getdents_args /* {
421: syscallarg(int) fd;
422: syscallarg(char *) buf;
423: syscallarg(int) nbytes;
424: } */ *uap = v;
425: struct vnode *vp;
426: struct file *fp;
427: int error;
428: struct sunos_readdir_callback_args args;
429:
430: if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
431: return (error);
432:
433: vp = (struct vnode *)fp->f_data;
434: /* SunOS returns ENOTDIR here, BSD would use EINVAL */
435: if (vp->v_type != VDIR) {
436: error = ENOTDIR;
437: goto bad;
438: }
439:
440: args.resid = SCARG(uap, nbytes);
441: args.outp = (caddr_t)SCARG(uap, buf);
442:
443: error = readdir_with_callback(fp, &fp->f_offset, args.resid,
444: sunos_readdir_callback, &args);
445: bad:
446: FRELE(fp);
447: if (error)
448: return (error);
449:
450: *retval = SCARG(uap, nbytes) - args.resid;
451:
452: return (0);
453: }
454:
455:
456: #define SUNOS__MAP_NEW 0x80000000 /* if not, old mmap & cannot handle */
457:
458: int
459: sunos_sys_mmap(p, v, retval)
460: struct proc *p;
461: void *v;
462: register_t *retval;
463: {
464: struct sunos_sys_mmap_args *uap = v;
465: struct sys_mmap_args ouap;
466:
467: /*
468: * Verify the arguments.
469: */
470: if (SCARG(uap, prot) & ~(PROT_READ|PROT_WRITE|PROT_EXEC))
471: return (EINVAL); /* XXX still needed? */
472:
473: if ((SCARG(uap, flags) & SUNOS__MAP_NEW) == 0)
474: return (EINVAL);
475:
476: SCARG(&ouap, flags) = SCARG(uap, flags) & ~SUNOS__MAP_NEW;
477: SCARG(&ouap, addr) = SCARG(uap, addr);
478:
479: if ((SCARG(&ouap, flags) & MAP_FIXED) == 0 &&
480: SCARG(&ouap, addr) != 0 &&
481: SCARG(&ouap, addr) < (void *)round_page((vaddr_t)p->p_vmspace->vm_daddr+MAXDSIZ))
482: SCARG(&ouap, addr) = (void *)round_page((vaddr_t)p->p_vmspace->vm_daddr+MAXDSIZ);
483:
484: SCARG(&ouap, len) = SCARG(uap, len);
485: SCARG(&ouap, prot) = SCARG(uap, prot);
486: SCARG(&ouap, fd) = SCARG(uap, fd);
487: SCARG(&ouap, pos) = SCARG(uap, pos);
488:
489: return (sys_mmap(p, &ouap, retval));
490: }
491:
492: #define MC_SYNC 1
493: #define MC_LOCK 2
494: #define MC_UNLOCK 3
495: #define MC_ADVISE 4
496: #define MC_LOCKAS 5
497: #define MC_UNLOCKAS 6
498:
499: int
500: sunos_sys_mctl(p, v, retval)
501: register struct proc *p;
502: void *v;
503: register_t *retval;
504: {
505: register struct sunos_sys_mctl_args *uap = v;
506:
507: switch (SCARG(uap, func)) {
508: case MC_ADVISE: /* ignore for now */
509: return (0);
510: case MC_SYNC: /* translate to msync */
511: return (sys_msync(p, uap, retval));
512: default:
513: return (EINVAL);
514: }
515: }
516:
517: int
518: sunos_sys_setsockopt(p, v, retval)
519: struct proc *p;
520: void *v;
521: register_t *retval;
522: {
523: struct sunos_sys_setsockopt_args *uap = v;
524: struct file *fp;
525: struct mbuf *m = NULL;
526: int error;
527:
528: if ((error = getsock(p->p_fd, SCARG(uap, s), &fp)) != 0)
529: return (error);
530: #define SO_DONTLINGER (~SO_LINGER)
531: if (SCARG(uap, name) == SO_DONTLINGER) {
532: m = m_get(M_WAIT, MT_SOOPTS);
533: mtod(m, struct linger *)->l_onoff = 0;
534: m->m_len = sizeof(struct linger);
535: error = (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
536: SO_LINGER, m));
537: goto bad;
538: }
539: if (SCARG(uap, level) == IPPROTO_IP) {
540: #define SUNOS_IP_MULTICAST_IF 2
541: #define SUNOS_IP_MULTICAST_TTL 3
542: #define SUNOS_IP_MULTICAST_LOOP 4
543: #define SUNOS_IP_ADD_MEMBERSHIP 5
544: #define SUNOS_IP_DROP_MEMBERSHIP 6
545: static int ipoptxlat[] = {
546: IP_MULTICAST_IF,
547: IP_MULTICAST_TTL,
548: IP_MULTICAST_LOOP,
549: IP_ADD_MEMBERSHIP,
550: IP_DROP_MEMBERSHIP
551: };
552: if (SCARG(uap, name) >= SUNOS_IP_MULTICAST_IF &&
553: SCARG(uap, name) <= SUNOS_IP_DROP_MEMBERSHIP) {
554: SCARG(uap, name) =
555: ipoptxlat[SCARG(uap, name) - SUNOS_IP_MULTICAST_IF];
556: }
557: }
558: if (SCARG(uap, valsize) > MLEN) {
559: error = EINVAL;
560: goto bad;
561: }
562: if (SCARG(uap, val)) {
563: m = m_get(M_WAIT, MT_SOOPTS);
564: error = copyin(SCARG(uap, val), mtod(m, caddr_t),
565: (u_int)SCARG(uap, valsize));
566: if (error) {
567: (void) m_free(m);
568: goto bad;
569: }
570: m->m_len = SCARG(uap, valsize);
571: }
572: error = (sosetopt((struct socket *)fp->f_data, SCARG(uap, level),
573: SCARG(uap, name), m));
574: bad:
575: FRELE(fp);
576: return (error);
577: }
578:
579: int
580: sunos_sys_fchroot(p, v, retval)
581: register struct proc *p;
582: void *v;
583: register_t *retval;
584: {
585: register struct sunos_sys_fchroot_args *uap = v;
586: register struct filedesc *fdp = p->p_fd;
587: register struct vnode *vp;
588: struct file *fp;
589: int error;
590:
591: if ((error = suser(p, 0)) != 0)
592: return (error);
593: if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
594: return (error);
595: vp = (struct vnode *)fp->f_data;
596: vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
597: if (vp->v_type != VDIR)
598: error = ENOTDIR;
599: else
600: error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
601: VOP_UNLOCK(vp, 0, p);
602: if (error) {
603: FRELE(fp);
604: return (error);
605: }
606: VREF(vp);
607: if (fdp->fd_rdir != NULL)
608: vrele(fdp->fd_rdir);
609: fdp->fd_rdir = vp;
610: FRELE(fp);
611: return (0);
612: }
613:
614: /*
615: * XXX: This needs cleaning up.
616: */
617: int
618: sunos_sys_auditsys(p, v, retval)
619: struct proc *p;
620: void *v;
621: register_t *retval;
622: {
623: return 0;
624: }
625:
626: int
627: sunos_sys_uname(p, v, retval)
628: struct proc *p;
629: void *v;
630: register_t *retval;
631: {
632: struct sunos_sys_uname_args *uap = v;
633: struct sunos_utsname sut;
634: extern char machine[];
635:
636: bzero(&sut, sizeof(sut));
637:
638: bcopy(ostype, sut.sysname, sizeof(sut.sysname) - 1);
639: bcopy(hostname, sut.nodename, sizeof(sut.nodename));
640: sut.nodename[sizeof(sut.nodename)-1] = '\0';
641: bcopy(osrelease, sut.release, sizeof(sut.release) - 1);
642: strlcpy(sut.version, "1", sizeof(sut.version));
643: bcopy(machine, sut.machine, sizeof(sut.machine) - 1);
644:
645: return copyout((caddr_t)&sut, (caddr_t)SCARG(uap, name),
646: sizeof(struct sunos_utsname));
647: }
648:
649: int
650: sunos_sys_setpgrp(p, v, retval)
651: struct proc *p;
652: void *v;
653: register_t *retval;
654: {
655: struct sunos_sys_setpgrp_args *uap = v;
656:
657: /*
658: * difference to our setpgid call is to include backwards
659: * compatibility to pre-setsid() binaries. Do setsid()
660: * instead of setpgid() in those cases where the process
661: * tries to create a new session the old way.
662: */
663: if (!SCARG(uap, pgid) &&
664: (!SCARG(uap, pid) || SCARG(uap, pid) == p->p_pid))
665: return sys_setsid(p, uap, retval);
666: else
667: return sys_setpgid(p, uap, retval);
668: }
669:
670: int
671: sunos_sys_open(p, v, retval)
672: struct proc *p;
673: void *v;
674: register_t *retval;
675: {
676: struct sunos_sys_open_args *uap = v;
677: int l, r;
678: int noctty;
679: int ret;
680:
681: caddr_t sg = stackgap_init(p->p_emul);
682: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
683:
684: /* convert mode into NetBSD mode */
685: l = SCARG(uap, flags);
686: noctty = l & 0x8000;
687: r = (l & (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800));
688: r |= ((l & (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK : 0);
689: r |= ((l & 0x0080) ? O_SHLOCK : 0);
690: r |= ((l & 0x0100) ? O_EXLOCK : 0);
691: r |= ((l & 0x2000) ? O_SYNC : 0);
692:
693: SCARG(uap, flags) = r;
694: ret = sys_open(p, (struct sys_open_args *)uap, retval);
695:
696: if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
697: struct filedesc *fdp = p->p_fd;
698: struct file *fp;
699:
700: if ((fp = fd_getfile(fdp, *retval)) == NULL)
701: return (EBADF);
702: FREF(fp);
703: /* ignore any error, just give it a try */
704: if (fp->f_type == DTYPE_VNODE)
705: (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t)0, p);
706: FRELE(fp);
707: }
708: return ret;
709: }
710:
711: #if defined (NFSSERVER)
712: int
713: sunos_sys_nfssvc(p, v, retval)
714: struct proc *p;
715: void *v;
716: register_t *retval;
717: {
718: #if 0
719: struct sunos_sys_nfssvc_args *uap = v;
720: struct emul *e = p->p_emul;
721: struct sys_nfssvc_args outuap;
722: struct sockaddr sa;
723: int error;
724:
725: bzero(&outuap, sizeof outuap);
726: SCARG(&outuap, fd) = SCARG(uap, fd);
727: SCARG(&outuap, mskval) = STACKGAPBASE;
728: SCARG(&outuap, msklen) = sizeof sa;
729: SCARG(&outuap, mtchval) = SCARG(&outuap, mskval) + sizeof sa;
730: SCARG(&outuap, mtchlen) = sizeof sa;
731:
732: bzero(&sa, sizeof sa);
733: if (error = copyout(&sa, SCARG(&outuap, mskval), SCARG(&outuap, msklen)))
734: return (error);
735: if (error = copyout(&sa, SCARG(&outuap, mtchval), SCARG(&outuap, mtchlen)))
736: return (error);
737:
738: return nfssvc(p, &outuap, retval);
739: #else
740: return (ENOSYS);
741: #endif
742: }
743: #endif /* NFSSERVER */
744:
745: int
746: sunos_sys_ustat(p, v, retval)
747: struct proc *p;
748: void *v;
749: register_t *retval;
750: {
751: struct sunos_sys_ustat_args *uap = v;
752: struct sunos_ustat us;
753: int error;
754:
755: bzero(&us, sizeof us);
756:
757: /*
758: * XXX: should set f_tfree and f_tinode at least
759: * How do we translate dev -> fstat? (and then to sunos_ustat)
760: */
761:
762: if ((error = copyout(&us, SCARG(uap, buf), sizeof us)) != 0)
763: return (error);
764: return 0;
765: }
766:
767: int
768: sunos_sys_quotactl(p, v, retval)
769: struct proc *p;
770: void *v;
771: register_t *retval;
772: {
773:
774: return EINVAL;
775: }
776:
777: int
778: sunos_sys_vhangup(p, v, retval)
779: struct proc *p;
780: void *v;
781: register_t *retval;
782: {
783: struct session *sp = p->p_session;
784:
785: if (sp->s_ttyvp == 0)
786: return 0;
787:
788: if (sp->s_ttyp && sp->s_ttyp->t_session == sp && sp->s_ttyp->t_pgrp)
789: pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
790:
791: (void) ttywait(sp->s_ttyp);
792: if (sp->s_ttyvp)
793: VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
794: if (sp->s_ttyvp)
795: vrele(sp->s_ttyvp);
796: sp->s_ttyvp = NULL;
797:
798: return 0;
799: }
800:
801: static int
802: sunstatfs(sp, buf)
803: struct statfs *sp;
804: caddr_t buf;
805: {
806: struct sunos_statfs ssfs;
807:
808: bzero(&ssfs, sizeof ssfs);
809: ssfs.f_type = 0;
810: ssfs.f_bsize = sp->f_bsize;
811: ssfs.f_blocks = sp->f_blocks;
812: ssfs.f_bfree = sp->f_bfree;
813: ssfs.f_bavail = sp->f_bavail;
814: ssfs.f_files = sp->f_files;
815: ssfs.f_ffree = sp->f_ffree;
816: ssfs.f_fsid = sp->f_fsid;
817: return copyout((caddr_t)&ssfs, buf, sizeof ssfs);
818: }
819:
820: int
821: sunos_sys_statfs(p, v, retval)
822: struct proc *p;
823: void *v;
824: register_t *retval;
825: {
826: struct sunos_sys_statfs_args *uap = v;
827: register struct mount *mp;
828: register struct statfs *sp;
829: int error;
830: struct nameidata nd;
831:
832: caddr_t sg = stackgap_init(p->p_emul);
833: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
834:
835: NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
836: if ((error = namei(&nd)) != 0)
837: return (error);
838: mp = nd.ni_vp->v_mount;
839: sp = &mp->mnt_stat;
840: vrele(nd.ni_vp);
841: if ((error = VFS_STATFS(mp, sp, p)) != 0)
842: return (error);
843: sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
844: return sunstatfs(sp, (caddr_t)SCARG(uap, buf));
845: }
846:
847: int
848: sunos_sys_fstatfs(p, v, retval)
849: struct proc *p;
850: void *v;
851: register_t *retval;
852: {
853: struct sunos_sys_fstatfs_args *uap = v;
854: struct file *fp;
855: struct mount *mp;
856: struct statfs *sp;
857: int error;
858:
859: if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
860: return (error);
861: mp = ((struct vnode *)fp->f_data)->v_mount;
862: sp = &mp->mnt_stat;
863: error = VFS_STATFS(mp, sp, p);
864: FRELE(fp);
865: if (error)
866: return (error);
867: sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
868: return sunstatfs(sp, (caddr_t)SCARG(uap, buf));
869: }
870:
871: int
872: sunos_sys_exportfs(p, v, retval)
873: struct proc *p;
874: void *v;
875: register_t *retval;
876: {
877: /*
878: * XXX: should perhaps translate into a mount(2)
879: * with MOUNT_EXPORT?
880: */
881: return 0;
882: }
883:
884: int
885: sunos_sys_mknod(p, v, retval)
886: struct proc *p;
887: void *v;
888: register_t *retval;
889: {
890: struct sunos_sys_mknod_args *uap = v;
891:
892: caddr_t sg = stackgap_init(p->p_emul);
893: SUNOS_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
894:
895: if (S_ISFIFO(SCARG(uap, mode)))
896: return sys_mkfifo(p, uap, retval);
897:
898: return sys_mknod(p, (struct sys_mknod_args *)uap, retval);
899: }
900:
901: #define SUNOS_SC_ARG_MAX 1
902: #define SUNOS_SC_CHILD_MAX 2
903: #define SUNOS_SC_CLK_TCK 3
904: #define SUNOS_SC_NGROUPS_MAX 4
905: #define SUNOS_SC_OPEN_MAX 5
906: #define SUNOS_SC_JOB_CONTROL 6
907: #define SUNOS_SC_SAVED_IDS 7
908: #define SUNOS_SC_VERSION 8
909:
910: int
911: sunos_sys_sysconf(p, v, retval)
912: struct proc *p;
913: void *v;
914: register_t *retval;
915: {
916: struct sunos_sys_sysconf_args *uap = v;
917: extern int maxfiles;
918:
919: switch(SCARG(uap, name)) {
920: case SUNOS_SC_ARG_MAX:
921: *retval = ARG_MAX;
922: break;
923: case SUNOS_SC_CHILD_MAX:
924: *retval = maxproc;
925: break;
926: case SUNOS_SC_CLK_TCK:
927: *retval = 60; /* should this be `hz', ie. 100? */
928: break;
929: case SUNOS_SC_NGROUPS_MAX:
930: *retval = NGROUPS_MAX;
931: break;
932: case SUNOS_SC_OPEN_MAX:
933: *retval = maxfiles;
934: break;
935: case SUNOS_SC_JOB_CONTROL:
936: *retval = 1;
937: break;
938: case SUNOS_SC_SAVED_IDS:
939: #ifdef _POSIX_SAVED_IDS
940: *retval = 1;
941: #else
942: *retval = 0;
943: #endif
944: break;
945: case SUNOS_SC_VERSION:
946: *retval = 198808;
947: break;
948: default:
949: return EINVAL;
950: }
951: return 0;
952: }
953:
954: #define SUNOS_RLIMIT_NOFILE 6 /* Other RLIMIT_* are the same */
955: #define SUNOS_RLIM_NLIMITS 7
956:
957: int
958: sunos_sys_getrlimit(p, v, retval)
959: struct proc *p;
960: void *v;
961: register_t *retval;
962: {
963: struct sunos_sys_getrlimit_args *uap = v;
964:
965: if (SCARG(uap, which) >= SUNOS_RLIM_NLIMITS)
966: return EINVAL;
967:
968: if (SCARG(uap, which) == SUNOS_RLIMIT_NOFILE)
969: SCARG(uap, which) = RLIMIT_NOFILE;
970:
971: return compat_43_sys_getrlimit(p, uap, retval);
972: }
973:
974: int
975: sunos_sys_setrlimit(p, v, retval)
976: struct proc *p;
977: void *v;
978: register_t *retval;
979: {
980: struct sunos_sys_getrlimit_args *uap = v;
981:
982: if (SCARG(uap, which) >= SUNOS_RLIM_NLIMITS)
983: return EINVAL;
984:
985: if (SCARG(uap, which) == SUNOS_RLIMIT_NOFILE)
986: SCARG(uap, which) = RLIMIT_NOFILE;
987:
988: return compat_43_sys_setrlimit(p, uap, retval);
989: }
990:
991: #ifdef PTRACE
992:
993: static int sreq2breq[] = {
994: PT_TRACE_ME, PT_READ_I, PT_READ_D, -1,
995: PT_WRITE_I, PT_WRITE_D, -1, PT_CONTINUE,
996: PT_KILL, -1, PT_ATTACH, PT_DETACH,
997: PT_GETREGS, PT_SETREGS, PT_GETFPREGS, PT_SETFPREGS
998: };
999: static int nreqs = sizeof(sreq2breq) / sizeof(sreq2breq[0]);
1000:
1001: int
1002: sunos_sys_ptrace(p, v, retval)
1003: struct proc *p;
1004: void *v;
1005: register_t *retval;
1006: {
1007: struct sunos_sys_ptrace_args *uap = v;
1008: struct sys_ptrace_args pa;
1009: int req;
1010:
1011: req = SCARG(uap, req);
1012:
1013: if (req < 0 || req >= nreqs)
1014: return (EINVAL);
1015:
1016: req = sreq2breq[req];
1017: if (req == -1)
1018: return (EINVAL);
1019:
1020: SCARG(&pa, req) = req;
1021: SCARG(&pa, pid) = (pid_t)SCARG(uap, pid);
1022: SCARG(&pa, addr) = (caddr_t)SCARG(uap, addr);
1023: SCARG(&pa, data) = SCARG(uap, data);
1024:
1025: return sys_ptrace(p, &pa, retval);
1026: }
1027:
1028: #endif /* PTRACE */
1029:
1030: /*
1031: * SunOS reboot system call (for compatibility).
1032: * Sun lets you pass in a boot string which the PROM
1033: * saves and provides to the next boot program.
1034: */
1035: static struct sunos_howto_conv {
1036: int sun_howto;
1037: int bsd_howto;
1038: } sunos_howto_conv[] = {
1039: { 0x001, RB_ASKNAME },
1040: { 0x002, RB_SINGLE },
1041: { 0x004, RB_NOSYNC },
1042: { 0x008, RB_HALT },
1043: { 0x080, RB_DUMP },
1044: { 0x000, 0 },
1045: };
1046: #define SUNOS_RB_STRING 0x200
1047:
1048: int
1049: sunos_sys_reboot(p, v, retval)
1050: struct proc *p;
1051: void *v;
1052: register_t *retval;
1053: {
1054: struct sunos_sys_reboot_args *uap = v;
1055: struct sunos_howto_conv *convp;
1056: int error, bsd_howto, sun_howto;
1057:
1058: if ((error = suser(p, 0)) != 0)
1059: return (error);
1060:
1061: /*
1062: * Convert howto bits to BSD format.
1063: */
1064: sun_howto = SCARG(uap, howto);
1065: bsd_howto = 0;
1066: convp = sunos_howto_conv;
1067: while (convp->sun_howto) {
1068: if (sun_howto & convp->sun_howto)
1069: bsd_howto |= convp->bsd_howto;
1070: convp++;
1071: }
1072:
1073: #ifdef sun3
1074: /*
1075: * Sun RB_STRING (Get user supplied bootstring.)
1076: * If the machine supports passing a string to the
1077: * next booted kernel, add the machine name above
1078: * and provide a reboot2() function (see sun3).
1079: */
1080: if (sun_howto & SUNOS_RB_STRING) {
1081: char bs[128];
1082:
1083: error = copyinstr(SCARG(uap, bootstr), bs, sizeof(bs), 0);
1084: if (error)
1085: return error;
1086:
1087: return (reboot2(bsd_howto, bs));
1088: }
1089: #endif /* sun3 */
1090:
1091: boot(bsd_howto);
1092: return 0;
1093: }
1094:
1095: /*
1096: * Generalized interface signal handler, 4.3-compatible.
1097: */
1098: /* ARGSUSED */
1099: int
1100: sunos_sys_sigvec(p, v, retval)
1101: struct proc *p;
1102: void *v;
1103: register_t *retval;
1104: {
1105: register struct sunos_sys_sigvec_args /* {
1106: syscallarg(int) signum;
1107: syscallarg(struct sigvec *) nsv;
1108: syscallarg(struct sigvec *) osv;
1109: } */ *uap = v;
1110: struct sigvec vec;
1111: register struct sigacts *ps = p->p_sigacts;
1112: register struct sigvec *sv;
1113: register int signum;
1114: int bit, error;
1115:
1116: signum = SCARG(uap, signum);
1117: if (signum <= 0 || signum >= NSIG ||
1118: signum == SIGKILL || signum == SIGSTOP)
1119: return (EINVAL);
1120: sv = &vec;
1121: if (SCARG(uap, osv)) {
1122: *(sig_t *)&sv->sv_handler = ps->ps_sigact[signum];
1123: sv->sv_mask = ps->ps_catchmask[signum];
1124: bit = sigmask(signum);
1125: sv->sv_flags = 0;
1126: if ((ps->ps_sigonstack & bit) != 0)
1127: sv->sv_flags |= SV_ONSTACK;
1128: if ((ps->ps_sigintr & bit) != 0)
1129: sv->sv_flags |= SV_INTERRUPT;
1130: if ((ps->ps_sigreset & bit) != 0)
1131: sv->sv_flags |= SA_RESETHAND;
1132: sv->sv_mask &= ~bit;
1133: error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, osv),
1134: sizeof (vec));
1135: if (error)
1136: return (error);
1137: }
1138: if (SCARG(uap, nsv)) {
1139: error = copyin((caddr_t)SCARG(uap, nsv), (caddr_t)sv,
1140: sizeof (vec));
1141: if (error)
1142: return (error);
1143: /*
1144: * SunOS uses the mask 0x0004 as SV_RESETHAND
1145: * meaning: `reset to SIG_DFL on delivery'.
1146: * We support only the bits in: 0xF
1147: * (those bits are the same as ours)
1148: */
1149: if (sv->sv_flags & ~0xF)
1150: return (EINVAL);
1151: /* SunOS binaries have a user-mode trampoline. */
1152: sv->sv_flags |= SA_USERTRAMP;
1153: /* Convert sigvec:SV_INTERRUPT to sigaction:SA_RESTART */
1154: sv->sv_flags ^= SA_RESTART; /* same bit, inverted */
1155: setsigvec(p, signum, (struct sigaction *)sv);
1156: }
1157: return (0);
1158: }
1159:
1160: int
1161: sunos_sys_ostime(p, v, retval)
1162: struct proc *p;
1163: void *v;
1164: register_t *retval;
1165: {
1166: struct sunos_sys_ostime_args /* {
1167: syscallarg(int) time;
1168: } */ *uap = v;
1169: struct timespec ts;
1170: int error;
1171:
1172: if ((error = suser(p, 0)) != 0)
1173: return (error);
1174:
1175: ts.tv_sec = SCARG(uap, time);
1176: ts.tv_nsec = 0;
1177: error = settime(&ts);
1178: return (error);
1179: }
1180:
1181: /*
1182: * This code is partly stolen from src/lib/libc/gen/times.c
1183: * XXX - CLK_TCK isn't declared in /sys, just in <time.h>, done here
1184: */
1185:
1186: #define CLK_TCK 100
1187: #define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
1188:
1189: int
1190: sunos_sys_otimes(p, v, retval)
1191: struct proc *p;
1192: void *v;
1193: register_t *retval;
1194: {
1195: struct sunos_sys_otimes_args /* {
1196: syscallarg(struct tms *) tp;
1197: } */ *uap = v;
1198: struct tms tms;
1199: struct rusage ru, *rup;
1200:
1201: /* RUSAGE_SELF */
1202: calcru(p, &ru.ru_utime, &ru.ru_stime, NULL);
1203: tms.tms_utime = CONVTCK(ru.ru_utime);
1204: tms.tms_stime = CONVTCK(ru.ru_stime);
1205:
1206: /* RUSAGE_CHILDREN */
1207: rup = &p->p_stats->p_cru;
1208: tms.tms_cutime = CONVTCK(rup->ru_utime);
1209: tms.tms_cstime = CONVTCK(rup->ru_stime);
1210:
1211: return copyout(&tms, SCARG(uap, tp), sizeof(*(SCARG(uap, tp))));
1212: }
CVSweb