This source file includes following definitions.
- sunos_sys_wait4
- sunos_sys_creat
- sunos_sys_access
- sunos_sys_stat
- sunos_sys_lstat
- sunos_sys_execve
- sunos_sys_execv
- sunos_sys_unmount
- sunos_sys_mount
- async_daemon
- sunos_sys_sigpending
- sunos_readdir_callback
- sunos_sys_getdents
- sunos_sys_mmap
- sunos_sys_mctl
- sunos_sys_setsockopt
- sunos_sys_fchroot
- sunos_sys_auditsys
- sunos_sys_uname
- sunos_sys_setpgrp
- sunos_sys_open
- sunos_sys_nfssvc
- sunos_sys_ustat
- sunos_sys_quotactl
- sunos_sys_vhangup
- sunstatfs
- sunos_sys_statfs
- sunos_sys_fstatfs
- sunos_sys_exportfs
- sunos_sys_mknod
- sunos_sys_sysconf
- sunos_sys_getrlimit
- sunos_sys_setrlimit
- sunos_sys_ptrace
- sunos_sys_reboot
- sunos_sys_sigvec
- sunos_sys_ostime
- sunos_sys_otimes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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>
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
186
187
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
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 },
249 { SUNNFS_INT, NFSMNT_INT },
250 { SUNNFS_NOAC, 0 },
251 { SUNNFS_ACREGMIN, 0 },
252 { SUNNFS_ACREGMAX, 0 },
253 { SUNNFS_ACDIRMIN, 0 },
254 { SUNNFS_ACDIRMAX, 0 },
255 { SUNNFS_SECURE, 0 },
256 { SUNNFS_NOCTO, 0 },
257 { SUNNFS_POSIX, 0 }
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
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
372
373
374
375
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
422
423
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
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
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
469
470 if (SCARG(uap, prot) & ~(PROT_READ|PROT_WRITE|PROT_EXEC))
471 return (EINVAL);
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:
509 return (0);
510 case MC_SYNC:
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
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
659
660
661
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
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
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
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
759
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
879
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;
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
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
1029
1030
1031
1032
1033
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
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
1076
1077
1078
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
1090
1091 boot(bsd_howto);
1092 return 0;
1093 }
1094
1095
1096
1097
1098
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
1107
1108
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
1145
1146
1147
1148
1149 if (sv->sv_flags & ~0xF)
1150 return (EINVAL);
1151
1152 sv->sv_flags |= SA_USERTRAMP;
1153
1154 sv->sv_flags ^= SA_RESTART;
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
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
1183
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
1197 *uap = v;
1198 struct tms tms;
1199 struct rusage ru, *rup;
1200
1201
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
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 }