1 /* $NetBSD: osf1_misc.c,v 1.14 1998/05/20 16:34:29 chs Exp $ */
4 * Copyright (c) 1994, 1995 Carnegie-Mellon University.
7 * Author: Chris G. Demetriou
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 * Carnegie Mellon requests users of this software to return to
21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
31 * Additional Copyright (c) 1999 by Andrew Gallatin
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/namei.h>
42 #include <sys/filedesc.h>
43 #include <sys/kernel.h>
44 #include <sys/malloc.h>
46 #include <sys/mount.h>
47 #include <sys/signal.h>
48 #include <sys/signalvar.h>
49 #include <sys/reboot.h>
51 #include <sys/vnode.h>
52 #include <sys/socketvar.h>
53 #include <sys/sysproto.h>
54 #include <sys/sysent.h>
55 #include <sys/resource.h>
56 #include <sys/signalvar.h>
57 #include <sys/fcntl.h>
58 #include <sys/socket.h>
60 #include <alpha/osf1/osf1_signal.h>
61 #include <alpha/osf1/osf1_proto.h>
62 #include <alpha/osf1/osf1_syscall.h>
63 #include <alpha/osf1/osf1_util.h>
64 #include <alpha/osf1/osf1.h>
66 #include <sys/module.h>
69 #include <alpha/osf1/exec_ecoff.h>
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/resourcevar.h>
75 #include <sys/imgact.h>
77 #include <sys/kernel.h>
79 #include <sys/vnode.h>
80 #include <sys/unistd.h>
83 #include <vm/vm_kern.h>
84 #include <vm/vm_param.h>
86 #include <vm/vm_map.h>
87 #include <vm/vm_extern.h>
88 #include <alpha/osf1/exec_ecoff.h>
91 #include <machine/cpu.h>
92 #include <machine/fpu.h>
94 #include <sys/sysctl.h>
95 #include <sys/utsname.h>
96 #include <sys/dkstat.h>
98 #include <machine/rpb.h>
100 static void cvtstat2osf1 __P((struct stat *, struct osf1_stat *));
101 static int osf2bsd_pathconf __P((int *));
103 static const char osf1_emul_path[] = "/compat/osf1";
105 * [ taken from the linux emulator ]
106 * Search an alternate path before passing pathname arguments on
107 * to system calls. Useful for keeping a seperate 'emulation tree'.
109 * If cflag is set, we check if an attempt can be made to create
110 * the named file, i.e. we check if the directory it should
114 osf1_emul_find(p, sgp, prefix, path, pbuf, cflag)
116 caddr_t *sgp; /* Pointer to stackgap memory */
124 char *buf, *cp, *ptr;
126 struct nameidata ndroot;
128 struct vattr vatroot;
130 buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
133 for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
136 sz = MAXPATHLEN - (ptr - buf);
139 * If sgp is not given then the path is already in kernel space
142 error = copystr(path, ptr, sz, &len);
144 error = copyinstr(path, ptr, sz, &len);
157 * We know that there is a / somewhere in this pathname.
158 * Search backwards for it, to find the file's parent dir
159 * to see if it exists in the alternate tree. If it does,
160 * and we want to create a file (cflag is set). We don't
161 * need to worry about the root comparison in this case.
165 for (cp = &ptr[len] - 1; *cp != '/'; cp--)
169 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
171 if ((error = namei(&nd)) != 0) {
178 NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
180 if ((error = namei(&nd)) != 0) {
186 * We now compare the vnode of the osf1_root to the one
187 * vnode asked. If they resolve to be the same, then we
188 * ignore the match so that the real root gets used.
189 * This avoids the problem of traversing "../.." to find the
190 * root directory and never finding it, because "/" resolves
191 * to the emulation root directory. This is expensive :-(
193 NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, osf1_emul_path,
196 if ((error = namei(&ndroot)) != 0) {
203 if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) {
207 if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p))
212 if (vat.va_fsid == vatroot.va_fsid &&
213 vat.va_fileid == vatroot.va_fileid) {
222 sz = &ptr[len] - buf;
223 *pbuf = stackgap_alloc(sgp, sz + 1);
224 error = copyout(buf, *pbuf, sz);
245 struct osf1_open_args *uap;
247 struct open_args /* {
248 syscallarg(char *) path;
249 syscallarg(int) flags;
250 syscallarg(int) mode;
254 sg = stackgap_init();
255 CHECKALTEXIST(p, &sg, uap->path);
257 SCARG(&a, path) = SCARG(uap, path);
258 SCARG(&a, flags) = SCARG(uap, flags); /* XXX translate */
259 SCARG(&a, mode) = SCARG(uap, mode);
266 osf1_getsysinfo(p, uap)
268 struct osf1_getsysinfo_args *uap;
275 case OSF_GET_MAX_UPROCS:
276 error = copyout(&maxprocperuid, uap->buffer,
277 sizeof(maxprocperuid));
280 case OSF_GET_IEEE_FP_CONTROL:
281 error = copyout(&p->p_addr->u_pcb.pcb_fp_control,uap->buffer,
282 sizeof(p->p_addr->u_pcb.pcb_fp_control));
285 case OSF_GET_PROC_TYPE: {
290 if(uap->nbytes < sizeof(proctype))
293 unit = alpha_pal_whami();
294 proctype = LOCATE_PCS(hwrpb, unit)->pcs_proc_type;
295 error = copyout (&proctype, uap->buffer,
301 case OSF_GET_HWRPB: { /* note -- osf/1 doesn't have rpb_tbhint[8] */
302 unsigned long rpb_size;
303 rpb_size = (unsigned long)&hwrpb->rpb_tbhint -
304 (unsigned long)hwrpb;
305 if(uap->nbytes < rpb_size){
306 uprintf("nbytes = %ld, sizeof(struct rpb) = %ld\n",
307 uap->nbytes, rpb_size);
311 error = copyout(hwrpb, uap->buffer, rpb_size);
317 printf("osf1_getsysinfo called with unknown op=%ld\n", uap->op);
320 p->p_retval[0] = retval;
326 osf1_setsysinfo(p, uap)
328 struct osf1_setsysinfo_args *uap;
335 case OSF_SET_IEEE_FP_CONTROL:
337 u_int64_t temp, *fp_control;
339 if ((error = copyin(uap->buffer, &temp, sizeof(temp))))
341 fp_control = &p->p_addr->u_pcb.pcb_fp_control;
342 *fp_control = temp & IEEE_TRAP_ENABLE_MASK;
346 uprintf("osf1_setsysinfo called with op=%ld\n", uap->op);
354 osf1_getrlimit(p, uap)
356 struct osf1_getrlimit_args *uap;
358 struct __getrlimit_args /* {
359 syscallarg(u_int) which;
360 syscallarg(struct orlimit *) rlp;
363 if (SCARG(uap, which) >= OSF1_RLIMIT_NLIMITS)
366 if (SCARG(uap, which) <= OSF1_RLIMIT_LASTCOMMON)
367 SCARG(&a, which) = SCARG(uap, which);
368 else if (SCARG(uap, which) == OSF1_RLIMIT_NOFILE)
369 SCARG(&a, which) = RLIMIT_NOFILE;
372 SCARG(&a, rlp) = (struct orlimit *)SCARG(uap, rlp);
374 return getrlimit(p, &a);
379 osf1_setrlimit(p, uap)
381 struct osf1_setrlimit_args *uap;
383 struct __setrlimit_args /* {
384 syscallarg(u_int) which;
385 syscallarg(struct orlimit *) rlp;
388 if (SCARG(uap, which) >= OSF1_RLIMIT_NLIMITS)
391 if (SCARG(uap, which) <= OSF1_RLIMIT_LASTCOMMON)
392 SCARG(&a, which) = SCARG(uap, which);
393 else if (SCARG(uap, which) == OSF1_RLIMIT_NOFILE)
394 SCARG(&a, which) = RLIMIT_NOFILE;
397 SCARG(&a, rlp) = (struct orlimit *)SCARG(uap, rlp);
399 return setrlimit(p, &a);
404 * As linux says, this is a total guess.
408 osf1_set_program_attributes(p, uap)
410 struct osf1_set_program_attributes_args *uap;
412 struct vmspace *vm = p->p_vmspace;
414 vm->vm_taddr = (caddr_t)uap->text_start;
415 vm->vm_tsize = btoc(round_page(uap->text_len));
416 vm->vm_daddr = (caddr_t)uap->bss_start;
417 vm->vm_dsize = btoc(round_page(uap->bss_len));
419 return(KERN_SUCCESS);
426 struct osf1_mmap_args *uap;
428 struct mmap_args /* {
429 syscallarg(caddr_t) addr;
430 syscallarg(size_t) len;
431 syscallarg(int) prot;
432 syscallarg(int) flags;
434 syscallarg(long) pad;
435 syscallarg(off_t) pos;
439 vm_offset_t addr, len, newaddr;
441 SCARG(&a, addr) = SCARG(uap, addr);
442 SCARG(&a, len) = SCARG(uap, len);
443 SCARG(&a, prot) = SCARG(uap, prot);
444 SCARG(&a, fd) = SCARG(uap, fd);
446 SCARG(&a, pos) = SCARG(uap, pos);
448 SCARG(&a, flags) = 0;
451 * OSF/1's mmap, unlike FreeBSD's, does its best to map memory at the
452 * user's requested address, even if MAP_FIXED is not set. Here we
453 * try to replicate this behaviour as much as we can because some
454 * applications (like /sbin/loader) depend on having things put as
455 * close to where they've requested as possible.
458 if (SCARG(uap, addr) != NULL)
459 addr = round_page((vm_offset_t)SCARG(&a,addr));
462 * Try to use the apparent OSF/1 default placement of 0x10000 for
463 * NULL addrs, this helps to prevent non-64 bit clean binaries from
466 addr = round_page((vm_offset_t)0x10000UL);
467 len = (vm_offset_t)SCARG(&a, len);
468 map = &p->p_vmspace->vm_map;
469 if (!vm_map_findspace(map, addr, len, &newaddr)) {
470 SCARG(&a,addr) = (caddr_t) newaddr;
471 SCARG(&a, flags) |= (MAP_FIXED);
475 uprintf("osf1_mmap:vm_map_findspace failed for: %p 0x%lx\n",
479 if (SCARG(uap, flags) & OSF1_MAP_SHARED)
480 SCARG(&a, flags) |= MAP_SHARED;
481 if (SCARG(uap, flags) & OSF1_MAP_PRIVATE)
482 SCARG(&a, flags) |= MAP_PRIVATE;
484 switch (SCARG(uap, flags) & OSF1_MAP_TYPE) {
485 case OSF1_MAP_ANONYMOUS:
486 SCARG(&a, flags) |= MAP_ANON;
489 SCARG(&a, flags) |= MAP_FILE;
494 if (SCARG(uap, flags) & OSF1_MAP_FIXED)
495 SCARG(&a, flags) |= MAP_FIXED;
496 if (SCARG(uap, flags) & OSF1_MAP_HASSEMAPHORE)
497 SCARG(&a, flags) |= MAP_HASSEMAPHORE;
498 if (SCARG(uap, flags) & OSF1_MAP_INHERIT)
499 SCARG(&a, flags) |= MAP_INHERIT;
500 if (SCARG(uap, flags) & OSF1_MAP_UNALIGNED)
503 * Emulate an osf/1 bug: Apparently, mmap'ed segments are always
504 * readable even if the user doesn't or in PROT_READ. This causes
505 * some buggy programs to segv.
507 SCARG(&a, prot) |= PROT_READ;
510 retval = mmap(p, &a);
513 "\nosf1_mmap: addr=%p (%p), len = 0x%lx, prot=0x%x, fd=%d, pad=0, pos=0x%lx",
514 SCARG(uap, addr), SCARG(&a, addr),SCARG(uap, len), SCARG(uap, prot),
515 SCARG(uap, fd), SCARG(uap, pos));
516 printf(" flags = 0x%x\n",SCARG(uap, flags));
524 struct osf1_msync_args *uap;
528 a.addr = SCARG(uap, addr);
529 a.len = SCARG(uap, len);
531 if(SCARG(uap, flags) & OSF1_MS_ASYNC)
532 SCARG(&a, flags) |= MS_ASYNC;
533 if(SCARG(uap, flags) & OSF1_MS_SYNC)
534 SCARG(&a, flags) |= MS_SYNC;
535 if(SCARG(uap, flags) & OSF1_MS_INVALIDATE)
536 SCARG(&a, flags) |= MS_INVALIDATE;
537 return(msync(p, &a));
549 int32_t st_atime_sec;
551 int32_t st_mtime_sec;
553 int32_t st_ctime_sec;
555 u_int32_t st_blksize;
562 * Get file status; this version follows links.
568 struct osf1_stat_args *uap;
572 struct osf1_stat osb;
576 sg = stackgap_init();
578 CHECKALTEXIST(p, &sg, uap->path);
580 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
581 SCARG(uap, path), p);
582 if ((error = namei(&nd)))
584 error = vn_stat(nd.ni_vp, &sb, p);
588 cvtstat2osf1(&sb, &osb);
589 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
595 * Get file status; this version does not follow links.
601 register struct osf1_lstat_args *uap;
604 struct osf1_stat osb;
607 caddr_t sg = stackgap_init();
608 CHECKALTEXIST(p, &sg, uap->path);
610 NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
611 SCARG(uap, path), p);
612 if ((error = namei(&nd)))
614 error = vn_stat(nd.ni_vp, &sb, p);
618 cvtstat2osf1(&sb, &osb);
619 error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
625 * Return status information about a file descriptor.
630 register struct osf1_fstat_args *uap;
632 register struct filedesc *fdp = p->p_fd;
633 register struct file *fp;
635 struct osf1_stat oub;
638 if ((unsigned)SCARG(uap, fd) >= fdp->fd_nfiles ||
639 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
642 error = fo_stat(fp, &ub, p);
643 cvtstat2osf1(&ub, &oub);
645 error = copyout((caddr_t)&oub, (caddr_t)SCARG(uap, sb),
652 #define bsd2osf_dev(dev) (umajor(dev) << 20 | uminor(dev))
653 #define osf2bsd_dev(dev) umakedev((umajor(dev) >> 20) & 0xfff, uminor(dev) & 0xfffff)
655 #define minor(x) ((int)((x)&0xffff00ff))
656 #define major(x) ((int)(((u_int)(x) >> 8)&0xff))
657 #define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
658 #define bsd2osf_dev(dev) (major(dev) << 20 | minor(dev))
659 #define osf2bsd_dev(dev) makedev(((dev) >> 20) & 0xfff, (dev) & 0xfffff)
662 * Convert from a stat structure to an osf1 stat structure.
665 cvtstat2osf1(st, ost)
667 struct osf1_stat *ost;
670 ost->st_dev = bsd2osf_dev(st->st_dev);
671 ost->st_ino = st->st_ino;
672 ost->st_mode = st->st_mode;
673 ost->st_nlink = st->st_nlink;
674 ost->st_uid = st->st_uid == -2 ? (u_int16_t) -2 : st->st_uid;
675 ost->st_gid = st->st_gid == -2 ? (u_int16_t) -2 : st->st_gid;
676 ost->st_rdev = bsd2osf_dev(st->st_rdev);
677 ost->st_size = st->st_size;
678 ost->st_atime_sec = st->st_atime;
680 ost->st_mtime_sec = st->st_mtime;
682 ost->st_ctime_sec = st->st_ctime;
684 ost->st_blksize = st->st_blksize;
685 ost->st_blocks = st->st_blocks;
686 ost->st_flags = st->st_flags;
687 ost->st_gen = st->st_gen;
694 struct osf1_mknod_args *uap;
700 sg = stackgap_init();
701 CHECKALTEXIST(p, &sg, uap->path);
703 SCARG(&a, path) = SCARG(uap, path);
704 SCARG(&a, mode) = SCARG(uap, mode);
705 SCARG(&a, dev) = osf2bsd_dev(SCARG(uap, dev));
709 printf("osf1_mknod no longer implemented\n");
717 struct osf1_access_args *uap;
721 sg = stackgap_init();
722 CHECKALTEXIST(p, &sg, uap->path);
724 return access(p, (struct access_args *)uap);
739 struct osf1_fcntl_args *uap;
745 struct osf1_flock osf_flock;
746 struct flock bsd_flock;
747 struct flock *nflock;
751 switch (SCARG(uap, cmd)) {
754 SCARG(&a, fd) = SCARG(uap, fd);
755 SCARG(&a, cmd) = F_SETFL;
756 /* need to translate flags here */
758 if ((long)SCARG(uap, arg) & OSF1_FNONBLOCK)
760 if ((long)SCARG(uap, arg) & OSF1_FAPPEND)
762 if ((long)SCARG(uap, arg) & OSF1_FDEFER)
764 if ((long)SCARG(uap, arg) & OSF1_FASYNC)
766 if ((long)SCARG(uap, arg) & OSF1_FCREAT)
768 if ((long)SCARG(uap, arg) & OSF1_FTRUNC)
770 if ((long)SCARG(uap, arg) & OSF1_FEXCL)
772 if ((long)SCARG(uap, arg) & OSF1_FNDELAY)
774 if ((long)SCARG(uap, arg) & OSF1_FSYNC)
776 SCARG(&a, arg) = tmp;
777 error = fcntl(p, &a);
784 * The OSF/1 flock stucture has a different order than
785 * the BSD one, but all else is the same. We must
786 * reorder the one we've gotten so that flock() groks it.
788 if ((error = copyin(uap->arg, &osf_flock, sizeof(osf_flock))))
790 bsd_flock.l_type = osf_flock.l_type;
791 bsd_flock.l_whence = osf_flock.l_whence;
792 bsd_flock.l_start = osf_flock.l_start;
793 bsd_flock.l_len = osf_flock.l_len;
794 bsd_flock.l_pid = osf_flock.l_pid;
795 sg = stackgap_init();
796 nflock = stackgap_alloc(&sg, sizeof(struct flock));
797 if ((error = copyout(&bsd_flock, nflock, sizeof(bsd_flock))) != 0)
801 error = fcntl(p, (struct fcntl_args *) uap);
803 printf("fcntl called with cmd=%d, args=0x%lx\n returns %d\n",uap->cmd,(long)uap->arg,error);
804 printf("bsd_flock.l_type = 0x%x\n", bsd_flock.l_type);
805 printf("bsd_flock.l_whence = 0x%x\n", bsd_flock.l_whence);
806 printf("bsd_flock.l_start = 0x%lx\n", bsd_flock.l_start);
807 printf("bsd_flock.l_len = 0x%lx\n", bsd_flock.l_len);
808 printf("bsd_flock.l_pid = 0x%x\n", bsd_flock.l_pid);
811 if ((uap->cmd == F_GETLK) && !error) {
812 osf_flock.l_type = F_UNLCK;
813 if ((error = copyout(&osf_flock, oarg,
819 error = fcntl(p, (struct fcntl_args *) uap);
821 if ((uap->cmd == OSF1_F_GETFL) && !error ) {
822 tmp = p->p_retval[0] & O_ACCMODE;
823 if (p->p_retval[0] & FNONBLOCK)
824 tmp |= OSF1_FNONBLOCK;
825 if (p->p_retval[0] & FAPPEND)
827 if (p->p_retval[0] & FDEFER)
829 if (p->p_retval[0] & FASYNC)
831 if (p->p_retval[0] & O_CREAT)
833 if (p->p_retval[0] & O_TRUNC)
835 if (p->p_retval[0] & O_EXCL)
837 if (p->p_retval[0] & FNDELAY)
839 if (p->p_retval[0] & FFSYNC)
841 p->p_retval[0] = tmp;
853 struct osf1_fcntl_args *uap;
859 SCARG(&a, fd) = SCARG(uap, fd);
861 switch (SCARG(uap, cmd)) {
864 SCARG(&a, cmd) = F_DUPFD;
865 SCARG(&a, arg) = (long)SCARG(uap, arg);
869 SCARG(&a, cmd) = F_GETFD;
870 SCARG(&a, arg) = (long)SCARG(uap, arg);
874 SCARG(&a, cmd) = F_SETFD;
875 SCARG(&a, arg) = (long)SCARG(uap, arg);
879 SCARG(&a, cmd) = F_GETFL;
880 SCARG(&a, arg) = (long)SCARG(uap, arg); /* ignored */
884 SCARG(&a, cmd) = F_SETFL;
886 if ((long)SCARG(uap, arg) & OSF1_FAPPEND)
888 if ((long)SCARG(uap, arg) & OSF1_FNONBLOCK)
890 if ((long)SCARG(uap, arg) & OSF1_FASYNC)
892 if ((long)SCARG(uap, arg) & OSF1_FSYNC)
894 SCARG(&a, arg) = tmp;
897 default: /* XXX other cases */
901 error = fcntl(p, &a);
906 switch (SCARG(uap, cmd)) {
919 struct osf1_socket_args *uap;
921 struct socket_args a;
923 if (SCARG(uap, type) > AF_LINK)
924 return (EINVAL); /* XXX After AF_LINK, divergence. */
926 SCARG(&a, domain) = SCARG(uap, domain);
927 SCARG(&a, type) = SCARG(uap, type);
928 SCARG(&a, protocol) = SCARG(uap, protocol);
930 return socket(p, &a);
937 register struct osf1_sendto_args *uap;
939 struct sendto_args a;
941 if (SCARG(uap, flags) & ~0x7f) /* unsupported flags */
944 SCARG(&a, s) = SCARG(uap, s);
945 SCARG(&a, buf) = SCARG(uap, buf);
946 SCARG(&a, len) = SCARG(uap, len);
947 SCARG(&a, flags) = SCARG(uap, flags);
948 SCARG(&a, to) = (caddr_t)SCARG(uap, to);
949 SCARG(&a, tolen) = SCARG(uap, tolen);
951 return sendto(p, &a);
958 struct osf1_reboot_args *uap;
960 struct reboot_args a;
962 if (SCARG(uap, opt) & ~OSF1_RB_ALLFLAGS &&
963 SCARG(uap, opt) & (OSF1_RB_ALTBOOT|OSF1_RB_UNIPROC))
968 if (SCARG(uap, opt) & OSF1_RB_ASKNAME)
969 SCARG(&a, opt) |= RB_ASKNAME;
970 if (SCARG(uap, opt) & OSF1_RB_SINGLE)
971 SCARG(&a, opt) |= RB_SINGLE;
972 if (SCARG(uap, opt) & OSF1_RB_NOSYNC)
973 SCARG(&a, opt) |= RB_NOSYNC;
974 if (SCARG(uap, opt) & OSF1_RB_HALT)
975 SCARG(&a, opt) |= RB_HALT;
976 if (SCARG(uap, opt) & OSF1_RB_INITNAME)
977 SCARG(&a, opt) |= RB_INITNAME;
978 if (SCARG(uap, opt) & OSF1_RB_DFLTROOT)
979 SCARG(&a, opt) |= RB_DFLTROOT;
981 return reboot(p, &a);
988 struct osf1_lseek_args *uap;
992 SCARG(&a, fd) = SCARG(uap, fd);
994 SCARG(&a, offset) = SCARG(uap, offset);
995 SCARG(&a, whence) = SCARG(uap, whence);
1002 * OSF/1 defines _POSIX_SAVED_IDS, which means that our normal
1003 * setuid() won't work.
1005 * Instead, by P1003.1b-1993, setuid() is supposed to work like:
1006 * If the process has appropriate [super-user] priviledges, the
1007 * setuid() function sets the real user ID, effective user
1008 * ID, and the saved set-user-ID to uid.
1009 * If the process does not have appropriate priviledges, but uid
1010 * is equal to the real user ID or the saved set-user-ID, the
1011 * setuid() function sets the effective user ID to uid; the
1012 * real user ID and saved set-user-ID remain unchanged by
1013 * this function call.
1018 struct osf1_setuid_args *uap;
1022 register struct pcred *pc;
1024 uid = SCARG(uap, uid);
1027 if ((error = suser(p)) != 0 &&
1028 uid != pc->p_ruid && uid != pc->p_svuid)
1031 pc->pc_ucred = crcopy(pc->pc_ucred);
1032 pc->pc_ucred->cr_uid = uid;
1034 (void)chgproccnt(pc->p_ruid, -1);
1035 (void)chgproccnt(uid, 1);
1039 p->p_flag |= P_SUGID;
1045 * OSF/1 defines _POSIX_SAVED_IDS, which means that our normal
1046 * setgid() won't work.
1048 * If you change "uid" to "gid" in the discussion, above, about
1049 * setuid(), you'll get a correct description of setgid().
1054 struct osf1_setgid_args *uap;
1058 register struct pcred *pc;
1060 gid = SCARG(uap, gid);
1063 if (((error = suser(p)) != 0 ) &&
1064 gid != pc->p_rgid && gid != pc->p_svgid)
1067 pc->pc_ucred = crcopy(pc->pc_ucred);
1068 pc->pc_ucred->cr_gid = gid;
1073 p->p_flag |= P_SUGID;
1079 * The structures end up being the same... but we can't be sure that
1080 * the other word of our iov_len is zero!
1086 #define STACKGAPLEN 400
1090 struct osf1_readv_args *uap;
1092 int error, osize, nsize, i;
1094 struct readv_args /* {
1096 syscallarg(struct iovec *) iovp;
1097 syscallarg(u_int) iovcnt;
1099 struct osf1_iovec *oio;
1102 sg = stackgap_init();
1104 if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec)))
1107 osize = SCARG(uap, iovcnt) * sizeof (struct osf1_iovec);
1108 nsize = SCARG(uap, iovcnt) * sizeof (struct iovec);
1110 oio = malloc(osize, M_TEMP, M_WAITOK);
1111 nio = malloc(nsize, M_TEMP, M_WAITOK);
1114 if ((error = copyin(SCARG(uap, iovp), oio, osize)))
1116 for (i = 0; i < SCARG(uap, iovcnt); i++) {
1117 nio[i].iov_base = oio[i].iov_base;
1118 nio[i].iov_len = oio[i].iov_len;
1121 SCARG(&a, fd) = SCARG(uap, fd);
1122 SCARG(&a, iovp) = stackgap_alloc(&sg, nsize);
1123 SCARG(&a, iovcnt) = SCARG(uap, iovcnt);
1125 if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize)))
1127 error = readv(p, &a);
1139 struct osf1_writev_args *uap;
1141 int error, i, nsize, osize;
1143 struct writev_args /* {
1145 syscallarg(struct iovec *) iovp;
1146 syscallarg(u_int) iovcnt;
1148 struct osf1_iovec *oio;
1151 sg = stackgap_init();
1153 if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec)))
1156 osize = SCARG(uap, iovcnt) * sizeof (struct osf1_iovec);
1157 nsize = SCARG(uap, iovcnt) * sizeof (struct iovec);
1159 oio = malloc(osize, M_TEMP, M_WAITOK);
1160 nio = malloc(nsize, M_TEMP, M_WAITOK);
1163 if ((error = copyin(SCARG(uap, iovp), oio, osize)))
1165 for (i = 0; i < SCARG(uap, iovcnt); i++) {
1166 nio[i].iov_base = oio[i].iov_base;
1167 nio[i].iov_len = oio[i].iov_len;
1170 SCARG(&a, fd) = SCARG(uap, fd);
1171 SCARG(&a, iovp) = stackgap_alloc(&sg, nsize);
1172 SCARG(&a, iovcnt) = SCARG(uap, iovcnt);
1174 if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize)))
1176 error = writev(p, &a);
1186 * More of the stupid off_t padding!
1189 osf1_truncate(p, uap)
1191 struct osf1_truncate_args *uap;
1194 struct truncate_args a;
1196 sg = stackgap_init();
1197 CHECKALTEXIST(p, &sg, uap->path);
1199 SCARG(&a, path) = SCARG(uap, path);
1201 SCARG(&a, length) = SCARG(uap, length);
1203 return truncate(p, &a);
1208 osf1_ftruncate(p, uap)
1210 struct osf1_ftruncate_args *uap;
1212 struct ftruncate_args a;
1214 SCARG(&a, fd) = SCARG(uap, fd);
1216 SCARG(&a, length) = SCARG(uap, length);
1218 return ftruncate(p, &a);
1223 osf2bsd_pathconf(name)
1228 case _OSF1_PC_LINK_MAX:
1229 case _OSF1_PC_MAX_CANON:
1230 case _OSF1_PC_MAX_INPUT:
1231 case _OSF1_PC_NAME_MAX:
1235 case _OSF1_PC_PATH_MAX:
1236 case _OSF1_PC_PIPE_BUF:
1239 case _OSF1_PC_NO_TRUNC:
1240 *name = _PC_NO_TRUNC;
1243 case _OSF1_PC_CHOWN_RESTRICTED:
1244 *name = _PC_CHOWN_RESTRICTED;
1247 case _OSF1_PC_VDISABLE:
1248 *name = _PC_VDISABLE;
1259 osf1_pathconf(p, uap)
1261 struct osf1_pathconf_args *uap;
1264 if (osf2bsd_pathconf(&uap->name))
1267 return (pathconf(p, (void *)uap));
1272 osf1_fpathconf(p, uap)
1274 struct osf1_fpathconf_args *uap;
1277 if (osf2bsd_pathconf(&uap->name))
1280 return (fpathconf(p, (void *)uap));
1285 osf1_getrusage(p, uap)
1287 struct osf1_getrusage_args *uap;
1290 struct osf1_rusage oru;
1294 rup = &p->p_stats->p_ru;
1295 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL);
1298 case RUSAGE_CHILDREN:
1299 rup = &p->p_stats->p_cru;
1305 TV_CP(rup->ru_utime, oru.ru_utime);
1306 TV_CP(rup->ru_stime, oru.ru_stime);
1307 bcopy(&(rup->ru_first), &(oru.ru_first),
1308 (&(oru.ru_last) - &(oru.ru_first)));
1310 return (copyout((caddr_t)&oru, (caddr_t)uap->rusage,
1311 sizeof (struct osf1_rusage)));
1318 struct osf1_wait4_args *uap;
1322 struct osf1_rusage *orusage, oru;
1323 struct rusage *rusage = NULL, ru;
1325 orusage = SCARG(uap, rusage);
1327 sg = stackgap_init();
1328 rusage = stackgap_alloc(&sg, sizeof(struct rusage));
1329 SCARG(uap, rusage) = (struct osf1_rusage *)rusage;
1331 if ((error = wait4(p, (struct wait_args *)uap)))
1333 if (orusage && (error = copyin(rusage, &ru, sizeof(ru)) == 0)){
1334 TV_CP(ru.ru_utime, oru.ru_utime);
1335 TV_CP(ru.ru_stime, oru.ru_stime);
1336 bcopy(&ru.ru_first, &oru.ru_first,
1337 (&(oru.ru_last) - &(oru.ru_first)));
1338 copyout(&oru, orusage, sizeof (struct osf1_rusage));
1345 osf1_madvise(p, uap)
1347 struct osf1_madvise_args *uap;
1358 struct osf1_execve_args *uap;
1361 struct execve_args ap;
1363 sg = stackgap_init();
1364 CHECKALTEXIST(p, &sg, SCARG(uap, path));
1366 SCARG(&ap, fname) = SCARG(uap, path);
1367 SCARG(&ap, argv) = SCARG(uap, argp);
1368 SCARG(&ap, envv) = SCARG(uap, envp);
1370 return execve(p, &ap);
1375 osf1_usleep_thread(p, uap)
1377 struct osf1_usleep_thread_args *uap;
1380 struct osf1_timeval time;
1381 struct timeval difftv, endtv, sleeptv, tv;
1383 if ((error = copyin(SCARG(uap, sleep), &time, sizeof time)))
1386 sleeptv.tv_sec = (u_long)time.tv_sec;
1387 sleeptv.tv_usec = (u_long)time.tv_usec;
1388 timo = tvtohz(&sleeptv);
1391 * Some callers use usleep(0) as a sort of thread-yield so make
1392 * sure that the timeout is non-zero.
1401 tsleep(p, PUSER|PCATCH, "OSF/1", timo);
1403 if (SCARG(uap, slept) != NULL) {
1406 timersub(&time, &endtv, &difftv);
1408 if (tv.tv_sec < 0 || tv.tv_usec < 0)
1409 tv.tv_sec = tv.tv_usec = 0;
1411 error = copyout(&time, SCARG(uap, slept), sizeof time);
1417 int osf1_gettimeofday(p, uap)
1419 register struct osf1_gettimeofday_args *uap;
1423 struct osf1_timeval otv;
1429 otv.tv_sec = atv.tv_sec;
1430 otv.tv_usec = atv.tv_usec;
1431 if ((error = copyout((caddr_t)&otv, (caddr_t)uap->tp,
1436 error = copyout((caddr_t)&tz, (caddr_t)uap->tzp, sizeof (tz));
1441 int osf1_select(p, uap)
1443 register struct osf1_select_args *uap;
1448 struct osf1_timeval otv;
1451 sg = stackgap_init();
1453 if ((error=copyin((caddr_t)uap->tv,(caddr_t)&otv,sizeof(otv))))
1456 uap->tv = stackgap_alloc(&sg, sizeof(struct timeval));
1457 if ((error=copyout((caddr_t)&tv, (caddr_t)uap->tv,sizeof(tv))))
1460 return(select(p, (struct select_args *)uap));
1465 osf1_setitimer(p, uap)
1467 struct osf1_setitimer_args *uap;
1471 caddr_t old_oitv, sg;
1472 struct itimerval itv;
1473 struct osf1_itimerval otv;
1476 old_oitv = (caddr_t)uap->oitv;
1477 sg = stackgap_init();
1479 if ((error = copyin((caddr_t)uap->itv,(caddr_t)&otv,sizeof(otv)))) {
1480 printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
1483 TV_CP(otv.it_interval,itv.it_interval);
1484 TV_CP(otv.it_value,itv.it_value);
1485 uap->itv = stackgap_alloc(&sg, sizeof(struct itimerval));
1486 if ((error = copyout((caddr_t)&itv,(caddr_t)uap->itv,sizeof(itv)))) {
1487 printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
1490 uap->oitv = stackgap_alloc(&sg, sizeof(struct itimerval));
1491 if ((error = setitimer(p, (struct setitimer_args *)uap))) {
1492 printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
1495 if ((error = copyin((caddr_t)uap->oitv,(caddr_t)&itv,sizeof(itv)))) {
1496 printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
1499 TV_CP(itv.it_interval,otv.it_interval);
1500 TV_CP(itv.it_value,otv.it_value);
1502 && (error = copyout((caddr_t)&otv, old_oitv, sizeof(otv)))) {
1503 printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
1510 osf1_getitimer(p, uap)
1512 struct osf1_getitimer_args *uap;
1515 caddr_t old_itv, sg;
1516 struct itimerval itv;
1517 struct osf1_itimerval otv;
1520 old_itv = (caddr_t)uap->itv;
1521 sg = stackgap_init();
1523 uap->itv = stackgap_alloc(&sg, sizeof(struct itimerval));
1524 if ((error = getitimer(p, (struct getitimer_args *)uap))) {
1525 printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
1528 if ((error = copyin((caddr_t)uap->itv,(caddr_t)&itv,sizeof(itv)))) {
1529 printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
1532 TV_CP(itv.it_interval,otv.it_interval);
1533 TV_CP(itv.it_value,otv.it_value);
1534 if ((error = copyout((caddr_t)&otv, old_itv, sizeof(otv)))) {
1535 printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
1542 osf1_proplist_syscall(p, uap)
1544 struct osf1_proplist_syscall_args *uap;
1552 osf1_ntpgettime(p, uap)
1554 struct osf1_ntpgettime_args *uap;
1562 osf1_ntpadjtime(p, uap)
1564 struct osf1_ntpadjtime_args *uap;
1572 osf1_setpgrp(p, uap)
1574 struct osf1_setpgrp_args *uap;
1577 return(setpgid(p, (struct setpgid_args *)uap));
1582 osf1_uswitch(p, uap)
1584 struct osf1_uswitch_args *uap;
1587 vm_map_entry_t entry;
1592 if (uap->cmd == OSF1_USC_GET) {
1593 if (vm_map_lookup_entry(&(p->p_vmspace->vm_map),0, &entry))
1594 p->p_retval[0] = OSF1_USW_NULLP;
1597 return(KERN_SUCCESS);
1598 } else if (uap->cmd == OSF1_USC_SET)
1599 if (uap->mask & OSF1_USW_NULLP) {
1600 rv = vm_mmap(&(p->p_vmspace->vm_map), &zero, PAGE_SIZE,
1601 VM_PROT_READ, VM_PROT_ALL,
1602 MAP_PRIVATE | MAP_FIXED | MAP_ANON, NULL, 0);
1604 return(KERN_SUCCESS);
1607 "osf1_uswitch:vm_mmap of zero page failed with status %d\n",
1617 osf1_classcntl(p, uap)
1619 struct osf1_classcntl_args *uap;
1622 return(EACCES); /* class scheduling not enabled */
1626 struct osf1_tbl_loadavg
1633 long tl_mach_factor[3]; /* ???? */
1636 struct osf1_tbl_sysinfo {
1647 #define TBL_LOADAVG 3
1648 #define TBL_SYSINFO 12
1653 struct osf1_table_args /*{
1662 struct osf1_tbl_loadavg ld;
1663 struct osf1_tbl_sysinfo si;
1668 case TBL_LOADAVG: /* xemacs wants this */
1669 if ((uap->index != 0) || (uap->nel != 1))
1671 bcopy(&averunnable, &ld, sizeof(averunnable));
1672 ld.tl_lscale = (u_int)averunnable.fscale;
1673 retval = copyout(&ld, uap->addr, sizeof(ld));
1676 if ((uap->index != 0) || (uap->nel != 1))
1678 bzero(&si, sizeof(si));
1680 si.si_user = cp_time[CP_USER];
1681 si.si_nice = cp_time[CP_NICE];
1682 si.si_sys = cp_time[CP_SYS];
1683 si.si_idle = cp_time[CP_IDLE];
1684 si.wait = cp_time[CP_INTR];
1688 si.si_boottime = boottime.tv_sec;
1689 retval = copyout(&si, uap->addr, sizeof(si));
1692 printf("osf1_table: %ld, %ld, %p, %ld %ld\n",
1693 uap->id, uap->index, uap->addr, uap->nel, uap->lel);
1701 osf1_sysinfo(p, uap)
1703 struct osf1_sysinfo_args /*{
1709 int name[2], retval;
1719 case 2: /* hostname, from ogethostname */
1722 name[1] = KERN_HOSTNAME;
1723 retval = userland_sysctl(p, name, 2, uap->buf, &len,
1725 p->p_retval[0] = bytes;
1728 case 3: /* release of osf1 */
1731 case 4: /* minor version of osf1 */
1734 case 5: /* machine or arch */
1738 case 7: /* serial number, real osf1 returns 0! */
1741 case 8: /* HW vendor */
1744 case 9: /* dunno, this is what du does.. */
1750 bytes = min(uap->count, strlen(string)+1);
1751 copyout(string, uap->buf, bytes);
1752 p->p_retval[0] = bytes;