141486Smckusick /* 241486Smckusick * Copyright (c) 1988 University of Utah. 341486Smckusick * Copyright (c) 1990 The Regents of the University of California. 441486Smckusick * All rights reserved. 541486Smckusick * 641486Smckusick * This code is derived from software contributed to Berkeley by 741486Smckusick * the Systems Programming Group of the University of Utah Computer 841486Smckusick * Science Department. 941486Smckusick * 1041486Smckusick * %sccs.include.redist.c% 1141486Smckusick * 1254857Shibler * from: Utah $Hdr: hpux_compat.c 1.43 92/04/23$ 1341486Smckusick * 14*56506Sbostic * @(#)hpux_compat.c 7.32 (Berkeley) 10/11/92 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1854857Shibler * Various HP-UX compatibility routines 1941486Smckusick */ 2041486Smckusick 2141486Smckusick #ifdef HPUXCOMPAT 2241486Smckusick 23*56506Sbostic #include <sys/param.h> 24*56506Sbostic #include <sys/systm.h> 25*56506Sbostic #include <sys/signalvar.h> 26*56506Sbostic #include <sys/kernel.h> 27*56506Sbostic #include <sys/filedesc.h> 28*56506Sbostic #include <sys/proc.h> 29*56506Sbostic #include <sys/buf.h> 30*56506Sbostic #include <sys/wait.h> 31*56506Sbostic #include <sys/file.h> 32*56506Sbostic #include <sys/namei.h> 33*56506Sbostic #include <sys/vnode.h> 34*56506Sbostic #include <sys/ioctl.h> 35*56506Sbostic #include <sys/ptrace.h> 36*56506Sbostic #include <sys/stat.h> 37*56506Sbostic #include <sys/syslog.h> 38*56506Sbostic #include <sys/malloc.h> 39*56506Sbostic #include <sys/mount.h> 40*56506Sbostic #include <sys/ipc.h> 41*56506Sbostic #include <sys/user.h> 4241486Smckusick 43*56506Sbostic #include <machine/cpu.h> 44*56506Sbostic #include <machine/reg.h> 45*56506Sbostic #include <machine/psl.h> 46*56506Sbostic #include <machine/vmparam.h> 4741486Smckusick 48*56506Sbostic #include <hp/hpux/hpux.h> 49*56506Sbostic #include <hp/hpux/hpux_termio.h> 50*56506Sbostic 5141486Smckusick #ifdef DEBUG 5241486Smckusick int unimpresponse = 0; 5341486Smckusick #endif 5441486Smckusick 5541486Smckusick /* SYS5 style UTSNAME info */ 5641486Smckusick struct hpuxutsname protoutsname = { 5741486Smckusick "4.4bsd", "", "2.0", "B", "9000/3?0", "" 5841486Smckusick }; 5941486Smckusick 6041486Smckusick /* 6.0 and later style context */ 6153922Shibler #if defined(HP380) 6253922Shibler char hpux040context[] = 6353922Shibler "standalone HP-MC68040 HP-MC68881 HP-MC68020 HP-MC68010 localroot default"; 6453922Shibler #endif 6541486Smckusick #ifdef FPCOPROC 6641486Smckusick char hpuxcontext[] = 6741486Smckusick "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default"; 6841486Smckusick #else 6941486Smckusick char hpuxcontext[] = 7041486Smckusick "standalone HP-MC68020 HP-MC68010 localroot default"; 7141486Smckusick #endif 7241486Smckusick 7341486Smckusick /* YP domainname */ 7441486Smckusick char domainname[MAXHOSTNAMELEN] = "unknown"; 7541486Smckusick int domainnamelen = 7; 7641486Smckusick 7741486Smckusick #define NERR 79 7841486Smckusick #define BERR 1000 7941486Smckusick 8041486Smckusick /* indexed by BSD errno */ 8141486Smckusick short bsdtohpuxerrnomap[NERR] = { 8241486Smckusick /*00*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8341486Smckusick /*10*/ 10, 45, 12, 13, 14, 15, 16, 17, 18, 19, 8441486Smckusick /*20*/ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 8541486Smckusick /*30*/ 30, 31, 32, 33, 34, 246, 245, 244, 216, 217, 8641486Smckusick /*40*/ 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 8741486Smckusick /*50*/ 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 8841486Smckusick /*60*/ 238, 239, 249, 248, 241, 242, 247,BERR,BERR,BERR, 8941486Smckusick /*70*/ 70, 71,BERR,BERR,BERR,BERR,BERR, 46,BERR 9041486Smckusick }; 9141486Smckusick 9243452Shibler notimp(p, uap, retval, code, nargs) 9343452Shibler struct proc *p; 9443452Shibler int *uap, *retval; 9543452Shibler int code, nargs; 9641486Smckusick { 9743452Shibler int error = 0; 9841486Smckusick #ifdef DEBUG 9943452Shibler register int *argp = uap; 10041486Smckusick extern char *hpuxsyscallnames[]; 10141486Smckusick 10254857Shibler printf("HP-UX %s(", hpuxsyscallnames[code]); 10341486Smckusick if (nargs) 10441486Smckusick while (nargs--) 10541486Smckusick printf("%x%c", *argp++, nargs? ',' : ')'); 10641486Smckusick else 10741486Smckusick printf(")"); 10841486Smckusick printf("\n"); 10941486Smckusick switch (unimpresponse) { 11041486Smckusick case 0: 11143452Shibler error = nosys(p, uap, retval); 11241486Smckusick break; 11341486Smckusick case 1: 11443452Shibler error = EINVAL; 11541486Smckusick break; 11641486Smckusick } 11741486Smckusick #else 11843452Shibler error = nosys(p, uap, retval); 11941486Smckusick #endif 12043452Shibler uprintf("HP-UX system call %d not implemented\n", code); 12144421Skarels return (error); 12241486Smckusick } 12341486Smckusick 12454917Storek struct hpuxexecv_args { 12554917Storek char *fname; 12654917Storek char **argp; 12754917Storek char **envp; 12854917Storek }; 12948478Skarels hpuxexecv(p, uap, retval) 13048478Skarels struct proc *p; 13154917Storek struct hpuxexecv_args *uap; 13248478Skarels int *retval; 13348478Skarels { 13448478Skarels extern int execve(); 13548478Skarels 13648478Skarels uap->envp = NULL; 13748478Skarels return (execve(p, uap, retval)); 13848478Skarels } 13948478Skarels 14041486Smckusick /* 14154857Shibler * HP-UX versions of wait and wait3 actually pass the parameters 14241486Smckusick * (status pointer, options, rusage) into the kernel rather than 14342352Smckusick * handling it in the C library stub. We also need to map any 14454857Shibler * termination signal from BSD to HP-UX. 14541486Smckusick */ 14654917Storek struct hpuxwait3_args { 14754917Storek int *status; 14854917Storek int options; 14954917Storek int rusage; 15054917Storek }; 15143452Shibler hpuxwait3(p, uap, retval) 15243452Shibler struct proc *p; 15354917Storek struct hpuxwait3_args *uap; 15443452Shibler int *retval; 15543452Shibler { 15641486Smckusick /* rusage pointer must be zero */ 15743452Shibler if (uap->rusage) 15844421Skarels return (EINVAL); 15952381Smckusick p->p_md.md_regs[PS] = PSL_ALLCC; 16052381Smckusick p->p_md.md_regs[R0] = uap->options; 16152381Smckusick p->p_md.md_regs[R1] = uap->rusage; 16244421Skarels return (hpuxwait(p, uap, retval)); 16341486Smckusick } 16441486Smckusick 16554917Storek struct hpuxwait_args { 16654917Storek int *status; 16754917Storek }; 16843452Shibler hpuxwait(p, uap, retval) 16943452Shibler struct proc *p; 17054917Storek struct hpuxwait_args *uap; 17143452Shibler int *retval; 17241486Smckusick { 17343452Shibler int sig, *statp, error; 17441486Smckusick 17541486Smckusick statp = uap->status; /* owait clobbers first arg */ 17643452Shibler error = owait(p, uap, retval); 17741486Smckusick /* 17841486Smckusick * HP-UX wait always returns EINTR when interrupted by a signal 17941486Smckusick * (well, unless its emulating a BSD process, but we don't bother...) 18041486Smckusick */ 18143452Shibler if (error == ERESTART) 18243452Shibler error = EINTR; 18343452Shibler if (error) 18444421Skarels return (error); 18543452Shibler sig = retval[1] & 0xFF; 18641486Smckusick if (sig == WSTOPPED) { 18743452Shibler sig = (retval[1] >> 8) & 0xFF; 18843452Shibler retval[1] = (bsdtohpuxsig(sig) << 8) | WSTOPPED; 18941486Smckusick } else if (sig) 19043452Shibler retval[1] = (retval[1] & 0xFF00) | 19141486Smckusick bsdtohpuxsig(sig & 0x7F) | (sig & 0x80); 19241486Smckusick if (statp) 19343452Shibler if (suword((caddr_t)statp, retval[1])) 19443452Shibler error = EFAULT; 19544421Skarels return (error); 19641486Smckusick } 19741486Smckusick 19854917Storek struct hpuxwaitpid_args { 19954917Storek int pid; 20054917Storek int *status; 20154917Storek int options; 20254917Storek struct rusage *rusage; /* wait4 arg */ 20354917Storek }; 20443452Shibler hpuxwaitpid(p, uap, retval) 20543452Shibler struct proc *p; 20654917Storek struct hpuxwaitpid_args *uap; 20743452Shibler int *retval; 20843452Shibler { 20955832Shibler int rv, sig, xstat, error; 21042352Smckusick 21142352Smckusick uap->rusage = 0; 21243452Shibler error = wait4(p, uap, retval); 21342352Smckusick /* 21442352Smckusick * HP-UX wait always returns EINTR when interrupted by a signal 21542352Smckusick * (well, unless its emulating a BSD process, but we don't bother...) 21642352Smckusick */ 21743452Shibler if (error == ERESTART) 21843452Shibler error = EINTR; 21943452Shibler if (error) 22044421Skarels return (error); 22155832Shibler if (uap->status) { 22255832Shibler /* 22355832Shibler * Wait4 already wrote the status out to user space, 22455832Shibler * pull it back, change the signal portion, and write 22555832Shibler * it back out. 22655832Shibler */ 22755832Shibler rv = fuword((caddr_t)uap->status); 22855832Shibler if (WIFSTOPPED(rv)) { 22955832Shibler sig = WSTOPSIG(rv); 23055832Shibler rv = W_STOPCODE(bsdtohpuxsig(sig)); 23155832Shibler } else if (WIFSIGNALED(rv)) { 23255832Shibler sig = WTERMSIG(rv); 23355832Shibler xstat = WEXITSTATUS(rv); 23455832Shibler rv = W_EXITCODE(xstat, bsdtohpuxsig(sig)) | 23555832Shibler WCOREDUMP(rv); 23655832Shibler } 23755832Shibler (void)suword((caddr_t)uap->status, rv); 23855832Shibler } 23944421Skarels return (error); 24042352Smckusick } 24142352Smckusick 24241486Smckusick /* 24341486Smckusick * Must remap some bits in the mode mask. 24441486Smckusick * O_CREAT, O_TRUNC, and O_EXCL must be remapped, 24541486Smckusick * O_SYNCIO (0100000) is removed entirely. 24641486Smckusick */ 24754917Storek struct hpuxopen_args { 24854917Storek char *fname; 24954917Storek int mode; 25054917Storek int crtmode; 25154917Storek }; 25243067Skarels hpuxopen(p, uap, retval) 25343067Skarels struct proc *p; 25454917Storek register struct hpuxopen_args *uap; 25543067Skarels int *retval; 25643067Skarels { 25741486Smckusick int mode; 25841486Smckusick 25941486Smckusick mode = uap->mode; 26041486Smckusick uap->mode &= ~(HPUXFSYNCIO|HPUXFEXCL|HPUXFTRUNC|HPUXFCREAT); 26141486Smckusick if (mode & HPUXFCREAT) { 26241486Smckusick /* 26341486Smckusick * simulate the pre-NFS behavior that opening a 26441486Smckusick * file for READ+CREATE ignores the CREATE (unless 26541486Smckusick * EXCL is set in which case we will return the 26641486Smckusick * proper error). 26741486Smckusick */ 26848478Skarels if ((mode & HPUXFEXCL) || (FFLAGS(mode) & FWRITE)) 26949950Smckusick uap->mode |= O_CREAT; 27041486Smckusick } 27141486Smckusick if (mode & HPUXFTRUNC) 27249950Smckusick uap->mode |= O_TRUNC; 27341486Smckusick if (mode & HPUXFEXCL) 27449950Smckusick uap->mode |= O_EXCL; 27544421Skarels return (open(p, uap, retval)); 27641486Smckusick } 27741486Smckusick 27855832Shibler /* 27955832Shibler * Old creat system call. 28055832Shibler */ 28155832Shibler struct hpuxcreat_args { 28255832Shibler char *fname; 28355832Shibler int fmode; 28455832Shibler }; 28555832Shibler hpuxcreat(p, uap, retval) 28655832Shibler struct proc *p; 28755832Shibler register struct hpuxcreat_args *uap; 28855832Shibler int *retval; 28955832Shibler { 29055832Shibler struct nargs { 29155832Shibler char *fname; 29255832Shibler int mode; 29355832Shibler int crtmode; 29455832Shibler } openuap; 29555832Shibler 29655832Shibler openuap.fname = uap->fname; 29755832Shibler openuap.crtmode = uap->fmode; 29855832Shibler openuap.mode = O_WRONLY | O_CREAT | O_TRUNC; 29955832Shibler return (open(p, &openuap, retval)); 30055832Shibler } 30155832Shibler 30249329Shibler /* XXX */ 30349329Shibler #define UF_FNDELAY_ON 0x20 30449329Shibler #define UF_FIONBIO_ON 0x40 30549329Shibler /* XXX */ 30649329Shibler 30754917Storek struct hpuxfcntl_args { 30854917Storek int fdes; 30954917Storek int cmd; 31054917Storek int arg; 31154917Storek }; 31243452Shibler hpuxfcntl(p, uap, retval) 31343452Shibler struct proc *p; 31454917Storek register struct hpuxfcntl_args *uap; 31543452Shibler int *retval; 31643452Shibler { 31743452Shibler int mode, error; 31849329Shibler char *fp; 31941486Smckusick 32049329Shibler if (uap->cmd == F_GETFL || uap->cmd == F_SETFL) { 32149329Shibler if ((unsigned)uap->fdes >= p->p_fd->fd_nfiles || 32249329Shibler p->p_fd->fd_ofiles[uap->fdes] == NULL) 32349329Shibler return (EBADF); 32449329Shibler fp = &p->p_fd->fd_ofileflags[uap->fdes]; 32549329Shibler } 32641486Smckusick switch (uap->cmd) { 32741486Smckusick case F_SETFL: 32849950Smckusick if (uap->arg & FNONBLOCK) 32949329Shibler *fp |= UF_FNDELAY_ON; 33049329Shibler else { 33149329Shibler *fp &= ~UF_FNDELAY_ON; 33249329Shibler if (*fp & UF_FIONBIO_ON) 33349950Smckusick uap->arg |= FNONBLOCK; 33449329Shibler } 33541486Smckusick uap->arg &= ~(HPUXFSYNCIO|HPUXFREMOTE|FUSECACHE); 33641486Smckusick break; 33741486Smckusick case F_GETFL: 33841486Smckusick case F_DUPFD: 33941486Smckusick case F_GETFD: 34041486Smckusick case F_SETFD: 34141486Smckusick break; 34241486Smckusick default: 34344421Skarels return (EINVAL); 34441486Smckusick } 34543452Shibler error = fcntl(p, uap, retval); 34649329Shibler if (error == 0 && uap->cmd == F_GETFL) { 34743452Shibler mode = *retval; 34849950Smckusick *retval &= ~(O_CREAT|O_TRUNC|O_EXCL|FUSECACHE); 34949950Smckusick if ((mode & FNONBLOCK) && (*fp & UF_FNDELAY_ON) == 0) 35049950Smckusick *retval &= ~FNONBLOCK; 35149950Smckusick if (mode & O_CREAT) 35243452Shibler *retval |= HPUXFCREAT; 35349950Smckusick if (mode & O_TRUNC) 35443452Shibler *retval |= HPUXFTRUNC; 35549950Smckusick if (mode & O_EXCL) 35643452Shibler *retval |= HPUXFEXCL; 35741486Smckusick } 35844421Skarels return (error); 35941486Smckusick } 36041486Smckusick 36141486Smckusick /* 36241486Smckusick * Read and write should return a 0 count when an operation 36349329Shibler * on a VNODE would block, not an error. 36449329Shibler * 36549329Shibler * In 6.2 and 6.5 sockets appear to return EWOULDBLOCK. 36649950Smckusick * In 7.0 the behavior for sockets depends on whether FNONBLOCK is in effect. 36741486Smckusick */ 36854917Storek struct hpuxread_args { 36954917Storek int fd; 37054917Storek }; 37143452Shibler hpuxread(p, uap, retval) 37243452Shibler struct proc *p; 37354917Storek struct hpuxread_args *uap; 37443452Shibler int *retval; 37541486Smckusick { 37643452Shibler int error; 37741486Smckusick 37843452Shibler error = read(p, uap, retval); 37943452Shibler if (error == EWOULDBLOCK && 38049329Shibler (p->p_fd->fd_ofiles[uap->fd]->f_type == DTYPE_VNODE || 38149329Shibler p->p_fd->fd_ofileflags[uap->fd] & UF_FNDELAY_ON)) { 38243452Shibler error = 0; 38343452Shibler *retval = 0; 38441486Smckusick } 38544421Skarels return (error); 38641486Smckusick } 38741486Smckusick 38854917Storek struct hpuxwrite_args { 38954917Storek int fd; 39054917Storek }; 39143452Shibler hpuxwrite(p, uap, retval) 39243452Shibler struct proc *p; 39354917Storek struct hpuxwrite_args *uap; 39443452Shibler int *retval; 39541486Smckusick { 39643452Shibler int error; 39741486Smckusick 39843452Shibler error = write(p, uap, retval); 39943452Shibler if (error == EWOULDBLOCK && 40049329Shibler (p->p_fd->fd_ofiles[uap->fd]->f_type == DTYPE_VNODE || 40149329Shibler p->p_fd->fd_ofileflags[uap->fd] & UF_FNDELAY_ON)) { 40243452Shibler error = 0; 40343452Shibler *retval = 0; 40441486Smckusick } 40544421Skarels return (error); 40641486Smckusick } 40741486Smckusick 40854917Storek struct hpuxreadv_args { 40954917Storek int fd; 41054917Storek }; 41143452Shibler hpuxreadv(p, uap, retval) 41243452Shibler struct proc *p; 41354917Storek struct hpuxreadv_args *uap; 41443452Shibler int *retval; 41541486Smckusick { 41643452Shibler int error; 41741486Smckusick 41843452Shibler error = readv(p, uap, retval); 41943452Shibler if (error == EWOULDBLOCK && 42049329Shibler (p->p_fd->fd_ofiles[uap->fd]->f_type == DTYPE_VNODE || 42149329Shibler p->p_fd->fd_ofileflags[uap->fd] & UF_FNDELAY_ON)) { 42243452Shibler error = 0; 42343452Shibler *retval = 0; 42441486Smckusick } 42544421Skarels return (error); 42641486Smckusick } 42741486Smckusick 42854917Storek struct hpuxwritev_args { 42954917Storek int fd; 43054917Storek }; 43143452Shibler hpuxwritev(p, uap, retval) 43243452Shibler struct proc *p; 43354917Storek struct hpuxwritev_args *uap; 43443452Shibler int *retval; 43541486Smckusick { 43643452Shibler int error; 43741486Smckusick 43843452Shibler error = writev(p, uap, retval); 43943452Shibler if (error == EWOULDBLOCK && 44049329Shibler (p->p_fd->fd_ofiles[uap->fd]->f_type == DTYPE_VNODE || 44149329Shibler p->p_fd->fd_ofileflags[uap->fd] & UF_FNDELAY_ON)) { 44243452Shibler error = 0; 44343452Shibler *retval = 0; 44441486Smckusick } 44544421Skarels return (error); 44641486Smckusick } 44741486Smckusick 44841486Smckusick /* 44941486Smckusick * 4.3bsd dup allows dup2 to come in on the same syscall entry 45054857Shibler * and hence allows two arguments. HP-UX dup has only one arg. 45141486Smckusick */ 45254917Storek struct hpuxdup_args { 45354917Storek int i; 45454917Storek }; 45543452Shibler hpuxdup(p, uap, retval) 45643452Shibler struct proc *p; 45754917Storek register struct hpuxdup_args *uap; 45843452Shibler int *retval; 45941486Smckusick { 46045923Smckusick register struct filedesc *fdp = p->p_fd; 46141486Smckusick struct file *fp; 46243452Shibler int fd, error; 46341486Smckusick 46448478Skarels if (((unsigned)uap->i) >= fdp->fd_nfiles || 46548478Skarels (fp = fdp->fd_ofiles[uap->i]) == NULL) 46644421Skarels return (EBADF); 46748478Skarels if (error = fdalloc(p, 0, &fd)) 46844421Skarels return (error); 46948478Skarels fdp->fd_ofiles[fd] = fp; 47048478Skarels fdp->fd_ofileflags[fd] = fdp->fd_ofileflags[uap->i] &~ UF_EXCLOSE; 47145923Smckusick fp->f_count++; 47245923Smckusick if (fd > fdp->fd_lastfile) 47345923Smckusick fdp->fd_lastfile = fd; 47443452Shibler *retval = fd; 47544421Skarels return (0); 47641486Smckusick } 47741486Smckusick 47854917Storek struct hpuxutssys_args { 47954917Storek struct hpuxutsname *uts; 48054917Storek int dev; 48154917Storek int request; 48254917Storek }; 48345753Smckusick hpuxutssys(p, uap, retval) 48443452Shibler struct proc *p; 48554917Storek register struct hpuxutssys_args *uap; 48643452Shibler int *retval; 48743452Shibler { 48841486Smckusick register int i; 48943452Shibler int error; 49041486Smckusick 49141486Smckusick switch (uap->request) { 49241486Smckusick /* uname */ 49341486Smckusick case 0: 49441486Smckusick /* fill in machine type */ 49541486Smckusick switch (machineid) { 49641486Smckusick case HP_320: 49741486Smckusick protoutsname.machine[6] = '2'; 49841486Smckusick break; 49941486Smckusick /* includes 318 and 319 */ 50041486Smckusick case HP_330: 50141486Smckusick protoutsname.machine[6] = '3'; 50241486Smckusick break; 50341486Smckusick case HP_340: 50441486Smckusick protoutsname.machine[6] = '4'; 50541486Smckusick break; 50641486Smckusick case HP_350: 50741486Smckusick protoutsname.machine[6] = '5'; 50841486Smckusick break; 50941486Smckusick case HP_360: 51041486Smckusick protoutsname.machine[6] = '6'; 51141486Smckusick break; 51241486Smckusick case HP_370: 51341486Smckusick protoutsname.machine[6] = '7'; 51441486Smckusick break; 51543452Shibler /* includes 345 */ 51643452Shibler case HP_375: 51743452Shibler protoutsname.machine[6] = '7'; 51843452Shibler protoutsname.machine[7] = '5'; 51943452Shibler break; 52054857Shibler /* includes 425 */ 52154857Shibler case HP_380: 52254857Shibler protoutsname.machine[6] = '8'; 52354857Shibler break; 52441486Smckusick } 52541486Smckusick /* copy hostname (sans domain) to nodename */ 52649329Shibler for (i = 0; i < 8 && hostname[i] != '.'; i++) 52741486Smckusick protoutsname.nodename[i] = hostname[i]; 52849329Shibler protoutsname.nodename[i] = '\0'; 52943452Shibler error = copyout((caddr_t)&protoutsname, (caddr_t)uap->uts, 53043452Shibler sizeof(struct hpuxutsname)); 53141486Smckusick break; 53245753Smckusick 53345753Smckusick /* gethostname */ 53445753Smckusick case 5: 53545753Smckusick /* uap->dev is length */ 53645753Smckusick if (uap->dev > hostnamelen + 1) 53745753Smckusick uap->dev = hostnamelen + 1; 53845753Smckusick error = copyout((caddr_t)hostname, (caddr_t)uap->uts, 53945753Smckusick uap->dev); 54045753Smckusick break; 54145753Smckusick 54245753Smckusick case 1: /* ?? */ 54345753Smckusick case 2: /* ustat */ 54445753Smckusick case 3: /* ?? */ 54545753Smckusick case 4: /* sethostname */ 54641486Smckusick default: 54743452Shibler error = EINVAL; 54841486Smckusick break; 54941486Smckusick } 55044421Skarels return (error); 55141486Smckusick } 55241486Smckusick 55354917Storek struct hpuxsysconf_args { 55454917Storek int name; 55554917Storek }; 55653922Shibler hpuxsysconf(p, uap, retval) 55753922Shibler struct proc *p; 55854917Storek struct hpuxsysconf_args *uap; 55953922Shibler int *retval; 56053922Shibler { 56153922Shibler switch (uap->name) { 56253922Shibler 56353922Shibler /* open files */ 56453922Shibler case HPUX_SYSCONF_OPENMAX: 56553922Shibler *retval = NOFILE; 56653922Shibler break; 56753922Shibler 56853922Shibler /* architecture */ 56953922Shibler case HPUX_SYSCONF_CPUTYPE: 57053922Shibler switch (machineid) { 57153922Shibler case HP_320: 57253922Shibler case HP_330: 57353922Shibler case HP_350: 57453922Shibler *retval = HPUX_SYSCONF_CPUM020; 57553922Shibler break; 57653922Shibler case HP_340: 57753922Shibler case HP_360: 57853922Shibler case HP_370: 57953922Shibler case HP_375: 58053922Shibler *retval = HPUX_SYSCONF_CPUM030; 58153922Shibler break; 58253922Shibler case HP_380: 58353922Shibler *retval = HPUX_SYSCONF_CPUM040; 58453922Shibler break; 58553922Shibler } 58653922Shibler break; 58753922Shibler default: 58854857Shibler uprintf("HP-UX sysconf(%d) not implemented\n", uap->name); 58953922Shibler return (EINVAL); 59053922Shibler } 59153922Shibler return (0); 59253922Shibler } 59353922Shibler 59454917Storek struct hpuxstat_args { 59554917Storek char *fname; 59654917Storek struct hpuxstat *hsb; 59754917Storek }; 59843452Shibler hpuxstat(p, uap, retval) 59943452Shibler struct proc *p; 60054917Storek struct hpuxstat_args *uap; 60143452Shibler int *retval; 60243452Shibler { 60355282Smckusick return (hpuxstat1(uap->fname, uap->hsb, FOLLOW, p)); 60441486Smckusick } 60541486Smckusick 60654917Storek struct hpuxlstat_args { 60754917Storek char *fname; 60854917Storek struct hpuxstat *hsb; 60954917Storek }; 61043452Shibler hpuxlstat(p, uap, retval) 61143452Shibler struct proc *p; 61254917Storek struct hpuxlstat_args *uap; 61343452Shibler int *retval; 61441486Smckusick { 61555282Smckusick return (hpuxstat1(uap->fname, uap->hsb, NOFOLLOW, p)); 61641486Smckusick } 61741486Smckusick 61854917Storek struct hpuxfstat_args { 61954917Storek int fdes; 62054917Storek struct hpuxstat *hsb; 62154917Storek }; 62243452Shibler hpuxfstat(p, uap, retval) 62343452Shibler struct proc *p; 62454917Storek register struct hpuxfstat_args *uap; 62543452Shibler int *retval; 62641486Smckusick { 62745923Smckusick register struct filedesc *fdp = p->p_fd; 62841486Smckusick register struct file *fp; 62941486Smckusick struct stat sb; 63043452Shibler int error; 63141486Smckusick 63248478Skarels if (((unsigned)uap->fdes) >= fdp->fd_nfiles || 63348478Skarels (fp = fdp->fd_ofiles[uap->fdes]) == NULL) 63444421Skarels return (EBADF); 63543452Shibler 63641486Smckusick switch (fp->f_type) { 63741486Smckusick 63841486Smckusick case DTYPE_VNODE: 63955282Smckusick error = vn_stat((struct vnode *)fp->f_data, &sb, p); 64041486Smckusick break; 64141486Smckusick 64241486Smckusick case DTYPE_SOCKET: 64355282Smckusick error = soo_stat((struct socket *)fp->f_data, &sb, p); 64441486Smckusick break; 64541486Smckusick 64641486Smckusick default: 64741486Smckusick panic("fstat"); 64841486Smckusick /*NOTREACHED*/ 64941486Smckusick } 65041486Smckusick /* is this right for sockets?? */ 65143452Shibler if (error == 0) 65243452Shibler error = bsdtohpuxstat(&sb, uap->hsb); 65344421Skarels return (error); 65441486Smckusick } 65541486Smckusick 65654917Storek struct hpuxulimit_args { 65754917Storek int cmd; 65854917Storek long newlimit; 65954917Storek }; 66043452Shibler hpuxulimit(p, uap, retval) 66143452Shibler struct proc *p; 66254917Storek register struct hpuxulimit_args *uap; 66353481Smckusick long *retval; 66443452Shibler { 66541486Smckusick struct rlimit *limp; 66643452Shibler int error = 0; 66741486Smckusick 66848478Skarels limp = &p->p_rlimit[RLIMIT_FSIZE]; 66941486Smckusick switch (uap->cmd) { 67041486Smckusick case 2: 67141486Smckusick uap->newlimit *= 512; 67241486Smckusick if (uap->newlimit > limp->rlim_max && 67348478Skarels (error = suser(p->p_ucred, &p->p_acflag))) 67441486Smckusick break; 67541486Smckusick limp->rlim_cur = limp->rlim_max = uap->newlimit; 67641486Smckusick /* else fall into... */ 67741486Smckusick 67841486Smckusick case 1: 67945753Smckusick *retval = limp->rlim_max / 512; 68041486Smckusick break; 68141486Smckusick 68241486Smckusick case 3: 68348478Skarels limp = &p->p_rlimit[RLIMIT_DATA]; 68448478Skarels *retval = ctob(p->p_vmspace->vm_tsize) + limp->rlim_max; 68541486Smckusick break; 68641486Smckusick 68741486Smckusick default: 68843452Shibler error = EINVAL; 68941486Smckusick break; 69041486Smckusick } 69144421Skarels return (error); 69241486Smckusick } 69341486Smckusick 69441486Smckusick /* 69541486Smckusick * Map "real time" priorities 0 (high) thru 127 (low) into nice 69641486Smckusick * values -16 (high) thru -1 (low). 69741486Smckusick */ 69854917Storek struct hpuxrtprio_args { 69954917Storek int pid; 70054917Storek int prio; 70154917Storek }; 70243452Shibler hpuxrtprio(cp, uap, retval) 70343452Shibler struct proc *cp; 70454917Storek register struct hpuxrtprio_args *uap; 70543452Shibler int *retval; 70643452Shibler { 70741486Smckusick struct proc *p; 70843452Shibler int nice, error; 70941486Smckusick 71041486Smckusick if (uap->prio < RTPRIO_MIN && uap->prio > RTPRIO_MAX && 71143452Shibler uap->prio != RTPRIO_NOCHG && uap->prio != RTPRIO_RTOFF) 71244421Skarels return (EINVAL); 71341486Smckusick if (uap->pid == 0) 71443452Shibler p = cp; 71543452Shibler else if ((p = pfind(uap->pid)) == 0) 71644421Skarels return (ESRCH); 71741486Smckusick nice = p->p_nice; 71841486Smckusick if (nice < NZERO) 71943452Shibler *retval = (nice + 16) << 3; 72041486Smckusick else 72143452Shibler *retval = RTPRIO_RTOFF; 72241486Smckusick switch (uap->prio) { 72341486Smckusick 72441486Smckusick case RTPRIO_NOCHG: 72544421Skarels return (0); 72641486Smckusick 72741486Smckusick case RTPRIO_RTOFF: 72841486Smckusick if (nice >= NZERO) 72944421Skarels return (0); 73041486Smckusick nice = NZERO; 73141486Smckusick break; 73241486Smckusick 73341486Smckusick default: 73441486Smckusick nice = (uap->prio >> 3) - 16; 73541486Smckusick break; 73641486Smckusick } 73743452Shibler error = donice(cp, p, nice); 73843452Shibler if (error == EACCES) 73943452Shibler error = EPERM; 74044421Skarels return (error); 74141486Smckusick } 74241486Smckusick 74354917Storek struct hpuxadvise_args { 74454917Storek int arg; 74554917Storek }; 74643452Shibler hpuxadvise(p, uap, retval) 74743452Shibler struct proc *p; 74854917Storek struct hpuxadvise_args *uap; 74943452Shibler int *retval; 75041486Smckusick { 75143452Shibler int error = 0; 75241486Smckusick 75341486Smckusick switch (uap->arg) { 75441486Smckusick case 0: 75549134Skarels p->p_addr->u_pcb.pcb_flags |= PCB_HPUXMMAP; 75641486Smckusick break; 75741486Smckusick case 1: 75841486Smckusick ICIA(); 75941486Smckusick break; 76041486Smckusick case 2: 76141486Smckusick DCIA(); 76241486Smckusick break; 76341486Smckusick default: 76443452Shibler error = EINVAL; 76541486Smckusick break; 76641486Smckusick } 76744421Skarels return (error); 76841486Smckusick } 76941486Smckusick 77054917Storek struct hpuxptrace_args { 77154917Storek int req; 77254917Storek int pid; 77354917Storek int *addr; 77454917Storek int data; 77554917Storek }; 77643452Shibler hpuxptrace(p, uap, retval) 77743452Shibler struct proc *p; 77854917Storek struct hpuxptrace_args *uap; 77943452Shibler int *retval; 78043452Shibler { 78143452Shibler int error; 78241486Smckusick 78341486Smckusick if (uap->req == PT_STEP || uap->req == PT_CONTINUE) { 78441486Smckusick if (uap->data) { 78541486Smckusick uap->data = hpuxtobsdsig(uap->data); 78641486Smckusick if (uap->data == 0) 78741486Smckusick uap->data = NSIG; 78841486Smckusick } 78941486Smckusick } 79043452Shibler error = ptrace(p, uap, retval); 79144421Skarels return (error); 79241486Smckusick } 79341486Smckusick 79454917Storek struct hpuxgetdomainname_args { 79554917Storek char *domainname; 79654917Storek u_int len; 79754917Storek }; 79843452Shibler hpuxgetdomainname(p, uap, retval) 79943452Shibler struct proc *p; 80054917Storek register struct hpuxgetdomainname_args *uap; 80143452Shibler int *retval; 80243452Shibler { 80341486Smckusick if (uap->len > domainnamelen + 1) 80441486Smckusick uap->len = domainnamelen + 1; 80544421Skarels return (copyout(domainname, uap->domainname, uap->len)); 80641486Smckusick } 80741486Smckusick 80854917Storek struct hpuxsetdomainname_args { 80954917Storek char *domainname; 81054917Storek u_int len; 81154917Storek }; 81243452Shibler hpuxsetdomainname(p, uap, retval) 81343452Shibler struct proc *p; 81454917Storek register struct hpuxsetdomainname_args *uap; 81543452Shibler int *retval; 81643452Shibler { 81743452Shibler int error; 81841486Smckusick 81948478Skarels if (error = suser(p->p_ucred, &p->p_acflag)) 82044421Skarels return (error); 82143452Shibler if (uap->len > sizeof (domainname) - 1) 82244421Skarels return (EINVAL); 82341486Smckusick domainnamelen = uap->len; 82443452Shibler error = copyin(uap->domainname, domainname, uap->len); 82541486Smckusick domainname[domainnamelen] = 0; 82644421Skarels return (error); 82741486Smckusick } 82841486Smckusick 82941486Smckusick #ifdef SYSVSHM 830*56506Sbostic #include <sys/shm.h> 83154857Shibler 83243452Shibler hpuxshmat(p, uap, retval) 83343452Shibler struct proc *p; 83443452Shibler int *uap, *retval; 83541486Smckusick { 83644421Skarels return (shmat(p, uap, retval)); 83741486Smckusick } 83841486Smckusick 83943452Shibler hpuxshmdt(p, uap, retval) 84043452Shibler struct proc *p; 84143452Shibler int *uap, *retval; 84241486Smckusick { 84344421Skarels return (shmdt(p, uap, retval)); 84441486Smckusick } 84541486Smckusick 84643452Shibler hpuxshmget(p, uap, retval) 84743452Shibler struct proc *p; 84843452Shibler int *uap, *retval; 84941486Smckusick { 85044421Skarels return (shmget(p, uap, retval)); 85141486Smckusick } 85254857Shibler 85354857Shibler /* 85454857Shibler * Handle HP-UX specific commands. 85554857Shibler */ 85654917Storek struct hpuxshmctl_args { 85754917Storek int shmid; 85854917Storek int cmd; 85954917Storek caddr_t buf; 86054917Storek }; 86154857Shibler hpuxshmctl(p, uap, retval) 86254857Shibler struct proc *p; 86354917Storek struct hpuxshmctl_args *uap; 86454857Shibler int *retval; 86554857Shibler { 86654857Shibler register struct shmid_ds *shp; 86754857Shibler register struct ucred *cred = p->p_ucred; 86854857Shibler int error; 86954857Shibler 87054857Shibler if (error = shmvalid(uap->shmid)) 87154857Shibler return (error); 87254857Shibler shp = &shmsegs[uap->shmid % SHMMMNI]; 87354857Shibler if (uap->cmd == SHM_LOCK || uap->cmd == SHM_UNLOCK) { 87454857Shibler /* don't really do anything, but make them think we did */ 87554857Shibler if (cred->cr_uid && cred->cr_uid != shp->shm_perm.uid && 87654857Shibler cred->cr_uid != shp->shm_perm.cuid) 87754857Shibler return (EPERM); 87854857Shibler return (0); 87954857Shibler } 88054857Shibler return (shmctl(p, uap, retval)); 88154857Shibler } 88241486Smckusick #endif 88341486Smckusick 88441486Smckusick /* 88541486Smckusick * Fake semaphore routines, just don't return an error. 88641486Smckusick * Should be adequate for starbase to run. 88741486Smckusick */ 88854917Storek struct hpuxsemctl_args { 88954917Storek int semid; 89054917Storek u_int semnum; 89154917Storek int cmd; 89254917Storek int arg; 89354917Storek }; 89443452Shibler hpuxsemctl(p, uap, retval) 89543452Shibler struct proc *p; 89654917Storek struct hpuxsemctl_args *uap; 89743452Shibler int *retval; 89843452Shibler { 89941486Smckusick /* XXX: should do something here */ 90044421Skarels return (0); 90141486Smckusick } 90241486Smckusick 90354917Storek struct hpuxsemget_args { 90454917Storek key_t key; 90554917Storek int nsems; 90654917Storek int semflg; 90754917Storek }; 90843452Shibler hpuxsemget(p, uap, retval) 90943452Shibler struct proc *p; 91054917Storek struct hpuxsemget_args *uap; 91143452Shibler int *retval; 91243452Shibler { 91341486Smckusick /* XXX: should do something here */ 91444421Skarels return (0); 91541486Smckusick } 91641486Smckusick 91754917Storek struct hpuxsemop_args { 91854917Storek int semid; 91954917Storek struct sembuf *sops; 92054917Storek u_int nsops; 92154917Storek }; 92243452Shibler hpuxsemop(p, uap, retval) 92343452Shibler struct proc *p; 92454917Storek struct hpuxsemop_args *uap; 92543452Shibler int *retval; 92643452Shibler { 92741486Smckusick /* XXX: should do something here */ 92844421Skarels return (0); 92941486Smckusick } 93041486Smckusick 93154857Shibler /* convert from BSD to HP-UX errno */ 93241486Smckusick bsdtohpuxerrno(err) 93341486Smckusick int err; 93441486Smckusick { 93541486Smckusick if (err < 0 || err >= NERR) 93641486Smckusick return(BERR); 93741486Smckusick return((int)bsdtohpuxerrnomap[err]); 93841486Smckusick } 93941486Smckusick 94055282Smckusick hpuxstat1(fname, hsb, follow, p) 94141486Smckusick char *fname; 94241486Smckusick struct hpuxstat *hsb; 94341486Smckusick int follow; 94455282Smckusick struct proc *p; 94541486Smckusick { 94648478Skarels int error; 94741486Smckusick struct stat sb; 94848478Skarels struct nameidata nd; 94941486Smckusick 95055282Smckusick NDINIT(&nd, LOOKUP, follow | LOCKLEAF, UIO_USERSPACE, fname, p); 95152330Smckusick if (error = namei(&nd)) 95241486Smckusick return (error); 95355282Smckusick error = vn_stat(nd.ni_vp, &sb, p); 95452330Smckusick vput(nd.ni_vp); 95541486Smckusick if (error == 0) 95641486Smckusick error = bsdtohpuxstat(&sb, hsb); 95741486Smckusick return (error); 95841486Smckusick } 95941486Smckusick 96041486Smckusick #include "grf.h" 96153922Shibler #if NGRF > 0 96253922Shibler #ifdef __STDC__ 96353922Shibler extern int grfopen(dev_t dev, int oflags, int devtype, struct proc *p); 96453922Shibler #else 96553922Shibler extern int grfopen(); 96653922Shibler #endif 96753922Shibler #endif 96841486Smckusick 96953922Shibler #define NHIL 1 /* XXX */ 97053922Shibler #if NHIL > 0 97153922Shibler #ifdef __STDC__ 97253922Shibler extern int hilopen(dev_t dev, int oflags, int devtype, struct proc *p); 97353922Shibler #else 97453922Shibler extern int hilopen(); 97553922Shibler #endif 97653922Shibler #endif 97753922Shibler 978*56506Sbostic #include <sys/conf.h> 97953922Shibler 98041486Smckusick bsdtohpuxstat(sb, hsb) 98141486Smckusick struct stat *sb; 98241486Smckusick struct hpuxstat *hsb; 98341486Smckusick { 98441486Smckusick struct hpuxstat ds; 98541486Smckusick 98641486Smckusick bzero((caddr_t)&ds, sizeof(ds)); 98753481Smckusick ds.hst_dev = (u_short)sb->st_dev; 98841486Smckusick ds.hst_ino = (u_long)sb->st_ino; 98941486Smckusick ds.hst_mode = sb->st_mode; 99041486Smckusick ds.hst_nlink = sb->st_nlink; 99141486Smckusick ds.hst_uid = (u_short)sb->st_uid; 99241486Smckusick ds.hst_gid = (u_short)sb->st_gid; 99353922Shibler /* XXX: I don't want to talk about it... */ 99453922Shibler if ((sb->st_mode & S_IFMT) == S_IFCHR) { 99541486Smckusick #if NGRF > 0 99653922Shibler if (cdevsw[major(sb->st_rdev)].d_open == grfopen) 99753922Shibler ds.hst_rdev = grfdevno(sb->st_rdev); 99841486Smckusick #endif 99953922Shibler #if NHIL > 0 100053922Shibler if (cdevsw[major(sb->st_rdev)].d_open == hilopen) 100153922Shibler ds.hst_rdev = hildevno(sb->st_rdev); 100253922Shibler #endif 100353922Shibler ; 100453922Shibler } else 100541486Smckusick ds.hst_rdev = bsdtohpuxdev(sb->st_rdev); 100653481Smckusick if (sb->st_size < (quad_t)1 << 32) 100753481Smckusick ds.hst_size = (long)sb->st_size; 100853481Smckusick else 100953481Smckusick ds.hst_size = -2; 101041486Smckusick ds.hst_atime = sb->st_atime; 101141486Smckusick ds.hst_mtime = sb->st_mtime; 101241486Smckusick ds.hst_ctime = sb->st_ctime; 101341486Smckusick ds.hst_blksize = sb->st_blksize; 101441486Smckusick ds.hst_blocks = sb->st_blocks; 101541486Smckusick return(copyout((caddr_t)&ds, (caddr_t)hsb, sizeof(ds))); 101641486Smckusick } 101741486Smckusick 101841486Smckusick hpuxtobsdioctl(com) 101941486Smckusick int com; 102041486Smckusick { 102141486Smckusick switch (com) { 102241486Smckusick case HPUXTIOCSLTC: 102341486Smckusick com = TIOCSLTC; break; 102441486Smckusick case HPUXTIOCGLTC: 102541486Smckusick com = TIOCGLTC; break; 102641486Smckusick case HPUXTIOCSPGRP: 102741486Smckusick com = TIOCSPGRP; break; 102841486Smckusick case HPUXTIOCGPGRP: 102941486Smckusick com = TIOCGPGRP; break; 103041486Smckusick case HPUXTIOCLBIS: 103141486Smckusick com = TIOCLBIS; break; 103241486Smckusick case HPUXTIOCLBIC: 103341486Smckusick com = TIOCLBIC; break; 103441486Smckusick case HPUXTIOCLSET: 103541486Smckusick com = TIOCLSET; break; 103641486Smckusick case HPUXTIOCLGET: 103741486Smckusick com = TIOCLGET; break; 103841486Smckusick } 103941486Smckusick return(com); 104041486Smckusick } 104141486Smckusick 104241486Smckusick /* 104354857Shibler * HP-UX ioctl system call. The differences here are: 104441486Smckusick * IOC_IN also means IOC_VOID if the size portion is zero. 104549329Shibler * no FIOCLEX/FIONCLEX/FIOASYNC/FIOGETOWN/FIOSETOWN 104641486Smckusick * the sgttyb struct is 2 bytes longer 104741486Smckusick */ 104854917Storek struct hpuxioctl_args { 104954917Storek int fdes; 105054917Storek int cmd; 105154917Storek caddr_t cmarg; 105254917Storek }; 105343452Shibler hpuxioctl(p, uap, retval) 105443452Shibler struct proc *p; 105554917Storek register struct hpuxioctl_args *uap; 105643452Shibler int *retval; 105743452Shibler { 105845923Smckusick register struct filedesc *fdp = p->p_fd; 105943452Shibler register struct file *fp; 106043452Shibler register int com, error; 106141486Smckusick register u_int size; 106241486Smckusick caddr_t memp = 0; 106341486Smckusick #define STK_PARAMS 128 106441486Smckusick char stkbuf[STK_PARAMS]; 106541486Smckusick caddr_t data = stkbuf; 106641486Smckusick 106741486Smckusick com = uap->cmd; 106841486Smckusick 106941486Smckusick /* XXX */ 107043452Shibler if (com == HPUXTIOCGETP || com == HPUXTIOCSETP) 107145923Smckusick return (getsettty(p, uap->fdes, com, uap->cmarg)); 107241486Smckusick 107348478Skarels if (((unsigned)uap->fdes) >= fdp->fd_nfiles || 107448478Skarels (fp = fdp->fd_ofiles[uap->fdes]) == NULL) 107544421Skarels return (EBADF); 107643452Shibler if ((fp->f_flag & (FREAD|FWRITE)) == 0) 107744421Skarels return (EBADF); 107841486Smckusick 107941486Smckusick /* 108041486Smckusick * Interpret high order word to find 108141486Smckusick * amount of data to be copied to/from the 108241486Smckusick * user's address space. 108341486Smckusick */ 108441486Smckusick size = IOCPARM_LEN(com); 108543452Shibler if (size > IOCPARM_MAX) 108644421Skarels return (ENOTTY); 108741486Smckusick if (size > sizeof (stkbuf)) { 108843452Shibler memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 108941486Smckusick data = memp; 109041486Smckusick } 109141486Smckusick if (com&IOC_IN) { 109241486Smckusick if (size) { 109343452Shibler error = copyin(uap->cmarg, data, (u_int)size); 109443452Shibler if (error) { 109541486Smckusick if (memp) 109641486Smckusick free(memp, M_IOCTLOPS); 109744421Skarels return (error); 109841486Smckusick } 109941486Smckusick } else 110041486Smckusick *(caddr_t *)data = uap->cmarg; 110141486Smckusick } else if ((com&IOC_OUT) && size) 110241486Smckusick /* 110343452Shibler * Zero the buffer so the user always 110443452Shibler * gets back something deterministic. 110541486Smckusick */ 110641486Smckusick bzero(data, size); 110741486Smckusick else if (com&IOC_VOID) 110841486Smckusick *(caddr_t *)data = uap->cmarg; 110941486Smckusick 111041486Smckusick switch (com) { 111141486Smckusick 111249329Shibler case HPUXFIOSNBIO: 111349329Shibler { 111449329Shibler char *ofp = &fdp->fd_ofileflags[uap->fdes]; 111549329Shibler int tmp; 111649329Shibler 111749329Shibler if (*(int *)data) 111849329Shibler *ofp |= UF_FIONBIO_ON; 111949329Shibler else 112049329Shibler *ofp &= ~UF_FIONBIO_ON; 112149329Shibler /* 112249950Smckusick * Only set/clear if FNONBLOCK not in effect 112349329Shibler */ 112449329Shibler if ((*ofp & UF_FNDELAY_ON) == 0) { 112549950Smckusick tmp = fp->f_flag & FNONBLOCK; 112649329Shibler error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, 112749329Shibler (caddr_t)&tmp, p); 112849329Shibler } 112949329Shibler break; 113049329Shibler } 113149329Shibler 113241486Smckusick case HPUXTIOCCONS: 113341486Smckusick *(int *)data = 1; 113448478Skarels error = (*fp->f_ops->fo_ioctl)(fp, TIOCCONS, data, p); 113541486Smckusick break; 113641486Smckusick 113741486Smckusick /* BSD-style job control ioctls */ 113841486Smckusick case HPUXTIOCLBIS: 113941486Smckusick case HPUXTIOCLBIC: 114041486Smckusick case HPUXTIOCLSET: 114141486Smckusick *(int *)data &= HPUXLTOSTOP; 114241486Smckusick if (*(int *)data & HPUXLTOSTOP) 114341486Smckusick *(int *)data = LTOSTOP; 114441486Smckusick /* fall into */ 114541486Smckusick case HPUXTIOCLGET: 114641486Smckusick case HPUXTIOCSLTC: 114741486Smckusick case HPUXTIOCGLTC: 114841486Smckusick case HPUXTIOCSPGRP: 114941486Smckusick case HPUXTIOCGPGRP: 115048478Skarels error = (*fp->f_ops->fo_ioctl) 115148478Skarels (fp, hpuxtobsdioctl(com), data, p); 115243452Shibler if (error == 0 && com == HPUXTIOCLGET) { 115341486Smckusick *(int *)data &= LTOSTOP; 115441486Smckusick if (*(int *)data & LTOSTOP) 115541486Smckusick *(int *)data = HPUXLTOSTOP; 115641486Smckusick } 115741486Smckusick break; 115841486Smckusick 115955832Shibler /* SYS 5 termio and POSIX termios */ 116041486Smckusick case HPUXTCGETA: 116141486Smckusick case HPUXTCSETA: 116241486Smckusick case HPUXTCSETAW: 116341486Smckusick case HPUXTCSETAF: 116455832Shibler case HPUXTCGETATTR: 116555832Shibler case HPUXTCSETATTR: 116655832Shibler case HPUXTCSETATTRD: 116755832Shibler case HPUXTCSETATTRF: 116848478Skarels error = hpuxtermio(fp, com, data, p); 116941486Smckusick break; 117041486Smckusick 117141486Smckusick default: 117248478Skarels error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); 117341486Smckusick break; 117441486Smckusick } 117541486Smckusick /* 117641486Smckusick * Copy any data to user, size was 117741486Smckusick * already set and checked above. 117841486Smckusick */ 117943452Shibler if (error == 0 && (com&IOC_OUT) && size) 118043452Shibler error = copyout(data, uap->cmarg, (u_int)size); 118141486Smckusick if (memp) 118241486Smckusick free(memp, M_IOCTLOPS); 118344421Skarels return (error); 118441486Smckusick } 118541486Smckusick 118641486Smckusick /* 118741486Smckusick * Man page lies, behaviour here is based on observed behaviour. 118841486Smckusick */ 118954917Storek struct hpuxgetcontext_args { 119054917Storek char *buf; 119154917Storek int len; 119254917Storek }; 119343452Shibler hpuxgetcontext(p, uap, retval) 119443452Shibler struct proc *p; 119554917Storek struct hpuxgetcontext_args *uap; 119643452Shibler int *retval; 119743452Shibler { 119841486Smckusick int error = 0; 119941486Smckusick register int len; 120041486Smckusick 120153922Shibler #if defined(HP380) 120253922Shibler if (machineid == HP_380) { 120355072Spendry len = min(uap->len, sizeof(hpux040context)); 120453922Shibler if (len) 120553922Shibler error = copyout(hpux040context, uap->buf, len); 120653922Shibler if (error == 0) 120753922Shibler *retval = sizeof(hpux040context); 120853922Shibler return (error); 120953922Shibler } 121053922Shibler #endif 121155072Spendry len = min(uap->len, sizeof(hpuxcontext)); 121241486Smckusick if (len) 121341486Smckusick error = copyout(hpuxcontext, uap->buf, (u_int)len); 121443452Shibler if (error == 0) 121543452Shibler *retval = sizeof(hpuxcontext); 121644421Skarels return (error); 121741486Smckusick } 121841486Smckusick 121941486Smckusick /* 122041486Smckusick * This is the equivalent of BSD getpgrp but with more restrictions. 122141486Smckusick * Note we do not check the real uid or "saved" uid. 122241486Smckusick */ 122354917Storek struct hpuxgetpgrp2_args { 122454917Storek int pid; 122554917Storek }; 122643452Shibler hpuxgetpgrp2(cp, uap, retval) 122743452Shibler struct proc *cp; 122854917Storek register struct hpuxgetpgrp2_args *uap; 122943452Shibler int *retval; 123041486Smckusick { 123141486Smckusick register struct proc *p; 123241486Smckusick 123341486Smckusick if (uap->pid == 0) 123443452Shibler uap->pid = cp->p_pid; 123541486Smckusick p = pfind(uap->pid); 123643452Shibler if (p == 0) 123744421Skarels return (ESRCH); 123848478Skarels if (cp->p_ucred->cr_uid && p->p_ucred->cr_uid != cp->p_ucred->cr_uid && 123948478Skarels !inferior(p)) 124044421Skarels return (EPERM); 124143452Shibler *retval = p->p_pgid; 124244421Skarels return (0); 124341486Smckusick } 124441486Smckusick 124541486Smckusick /* 124641486Smckusick * This is the equivalent of BSD setpgrp but with more restrictions. 124741486Smckusick * Note we do not check the real uid or "saved" uid or pgrp. 124841486Smckusick */ 124954917Storek struct hpuxsetpgrp2_args { 125054917Storek int pid; 125154917Storek int pgrp; 125254917Storek }; 125343452Shibler hpuxsetpgrp2(p, uap, retval) 125443452Shibler struct proc *p; 125554917Storek struct hpuxsetpgrp2_args *uap; 125643452Shibler int *retval; 125743452Shibler { 125841486Smckusick /* empirically determined */ 125943452Shibler if (uap->pgrp < 0 || uap->pgrp >= 30000) 126044421Skarels return (EINVAL); 126148478Skarels return (setpgid(p, uap, retval)); 126241486Smckusick } 126341486Smckusick 126441486Smckusick /* 126555165Smckusick * XXX Same as BSD setre[ug]id right now. Need to consider saved ids. 126645753Smckusick */ 126754917Storek struct hpuxsetresuid_args { 126854917Storek int ruid; 126954917Storek int euid; 127054917Storek int suid; 127154917Storek }; 127245753Smckusick hpuxsetresuid(p, uap, retval) 127355165Smckusick struct proc *p; 127454917Storek struct hpuxsetresuid_args *uap; 127545753Smckusick int *retval; 127645753Smckusick { 127755165Smckusick return (osetreuid(p, uap, retval)); 127845753Smckusick } 127945753Smckusick 128054917Storek struct hpuxsetresgid_args { 128154917Storek int rgid; 128254917Storek int egid; 128354917Storek int sgid; 128454917Storek }; 128545753Smckusick hpuxsetresgid(p, uap, retval) 128655165Smckusick struct proc *p; 128754917Storek struct hpuxsetresgid_args *uap; 128845753Smckusick int *retval; 128945753Smckusick { 129055165Smckusick return (osetregid(p, uap, retval)); 129145753Smckusick } 129245753Smckusick 129345753Smckusick /* 129445753Smckusick * XXX: simple recognition hack to see if we can make grmd work. 129545753Smckusick */ 129654917Storek struct hpuxlockf_args { 129754917Storek int fd; 129854917Storek int func; 129954917Storek long size; 130054917Storek }; 130145753Smckusick hpuxlockf(p, uap, retval) 130245753Smckusick struct proc *p; 130354917Storek struct hpuxlockf_args *uap; 130445753Smckusick int *retval; 130545753Smckusick { 130645753Smckusick return (0); 130745753Smckusick } 130845753Smckusick 130954917Storek struct hpuxgetaccess_args { 131054917Storek char *path; 131154917Storek int uid; 131254917Storek int ngroups; 131354917Storek int *gidset; 131454917Storek void *label; 131554917Storek void *privs; 131654917Storek }; 131745753Smckusick hpuxgetaccess(p, uap, retval) 131845753Smckusick register struct proc *p; 131954917Storek register struct hpuxgetaccess_args *uap; 132045753Smckusick int *retval; 132145753Smckusick { 132245753Smckusick int lgroups[NGROUPS]; 132345753Smckusick int error = 0; 132445753Smckusick register struct ucred *cred; 132545753Smckusick register struct vnode *vp; 132652330Smckusick struct nameidata nd; 132745753Smckusick 132845753Smckusick /* 132945753Smckusick * Build an appropriate credential structure 133045753Smckusick */ 133148478Skarels cred = crdup(p->p_ucred); 133245753Smckusick switch (uap->uid) { 133345753Smckusick case 65502: /* UID_EUID */ 133445753Smckusick break; 133545753Smckusick case 65503: /* UID_RUID */ 133648478Skarels cred->cr_uid = p->p_cred->p_ruid; 133745753Smckusick break; 133845753Smckusick case 65504: /* UID_SUID */ 133945753Smckusick error = EINVAL; 134045753Smckusick break; 134145753Smckusick default: 134245753Smckusick if (uap->uid > 65504) 134345753Smckusick error = EINVAL; 134445753Smckusick cred->cr_uid = uap->uid; 134545753Smckusick break; 134645753Smckusick } 134745753Smckusick switch (uap->ngroups) { 134845753Smckusick case -1: /* NGROUPS_EGID */ 134945753Smckusick cred->cr_ngroups = 1; 135045753Smckusick break; 135145753Smckusick case -5: /* NGROUPS_EGID_SUPP */ 135245753Smckusick break; 135345753Smckusick case -2: /* NGROUPS_RGID */ 135445753Smckusick cred->cr_ngroups = 1; 135548478Skarels cred->cr_gid = p->p_cred->p_rgid; 135645753Smckusick break; 135745753Smckusick case -6: /* NGROUPS_RGID_SUPP */ 135848478Skarels cred->cr_gid = p->p_cred->p_rgid; 135945753Smckusick break; 136045753Smckusick case -3: /* NGROUPS_SGID */ 136145753Smckusick case -7: /* NGROUPS_SGID_SUPP */ 136245753Smckusick error = EINVAL; 136345753Smckusick break; 136445753Smckusick case -4: /* NGROUPS_SUPP */ 136545753Smckusick if (cred->cr_ngroups > 1) 136645753Smckusick cred->cr_gid = cred->cr_groups[1]; 136745753Smckusick else 136845753Smckusick error = EINVAL; 136945753Smckusick break; 137045753Smckusick default: 137145753Smckusick if (uap->ngroups > 0 && uap->ngroups <= NGROUPS) 137245753Smckusick error = copyin((caddr_t)uap->gidset, 137345753Smckusick (caddr_t)&lgroups[0], 137445753Smckusick uap->ngroups * sizeof(lgroups[0])); 137545753Smckusick else 137645753Smckusick error = EINVAL; 137745753Smckusick if (error == 0) { 137845753Smckusick int gid; 137945753Smckusick 138045753Smckusick for (gid = 0; gid < uap->ngroups; gid++) 138145753Smckusick cred->cr_groups[gid] = lgroups[gid]; 138245753Smckusick cred->cr_ngroups = uap->ngroups; 138345753Smckusick } 138445753Smckusick break; 138545753Smckusick } 138645753Smckusick /* 138745753Smckusick * Lookup file using caller's effective IDs. 138845753Smckusick */ 138945753Smckusick if (error == 0) { 139052330Smckusick NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, 139152330Smckusick uap->path, p); 139252330Smckusick error = namei(&nd); 139345753Smckusick } 139445753Smckusick if (error) { 139545753Smckusick crfree(cred); 139645753Smckusick return (error); 139745753Smckusick } 139845753Smckusick /* 139945753Smckusick * Use the constructed credentials for access checks. 140045753Smckusick */ 140152330Smckusick vp = nd.ni_vp; 140245753Smckusick *retval = 0; 140348478Skarels if (VOP_ACCESS(vp, VREAD, cred, p) == 0) 140445753Smckusick *retval |= R_OK; 140548478Skarels if (vn_writechk(vp) == 0 && VOP_ACCESS(vp, VWRITE, cred, p) == 0) 140645753Smckusick *retval |= W_OK; 140745753Smckusick /* XXX we return X_OK for root on VREG even if not */ 140848478Skarels if (VOP_ACCESS(vp, VEXEC, cred, p) == 0) 140945753Smckusick *retval |= X_OK; 141045753Smckusick vput(vp); 141145753Smckusick crfree(cred); 141245753Smckusick return (error); 141345753Smckusick } 141445753Smckusick 141545753Smckusick /* 141654857Shibler * Brutal hack! Map HP-UX u-area offsets into BSD u offsets. 141741486Smckusick * No apologies offered, if you don't like it, rewrite it! 141841486Smckusick */ 141941486Smckusick 142049134Skarels extern char kstack[]; 142141486Smckusick #define UOFF(f) ((int)&((struct user *)0)->f) 142241486Smckusick #define HPUOFF(f) ((int)&((struct hpuxuser *)0)->f) 142341486Smckusick 142441486Smckusick /* simplified FP structure */ 142541486Smckusick struct bsdfp { 142641486Smckusick int save[54]; 142741486Smckusick int reg[24]; 142841486Smckusick int ctrl[3]; 142941486Smckusick }; 143041486Smckusick 143141486Smckusick hpuxtobsduoff(off) 143241486Smckusick int *off; 143341486Smckusick { 143452381Smckusick register int *ar0 = curproc->p_md.md_regs; 143541486Smckusick struct hpuxfp *hp; 143641486Smckusick struct bsdfp *bp; 143741486Smckusick register u_int raddr; 143841486Smckusick 143948478Skarels /* u_ar0 field; procxmt puts in U_ar0 */ 144041486Smckusick if ((int)off == HPUOFF(hpuxu_ar0)) 144148478Skarels return(UOFF(U_ar0)); 144241486Smckusick 144341486Smckusick #ifdef FPCOPROC 144441486Smckusick /* 68881 registers from PCB */ 144541486Smckusick hp = (struct hpuxfp *)HPUOFF(hpuxu_fp); 144641486Smckusick bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs); 144741486Smckusick if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3]) 144841486Smckusick return((int)&bp->ctrl[off - hp->hpfp_ctrl]); 144941486Smckusick if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24]) 145041486Smckusick return((int)&bp->reg[off - hp->hpfp_reg]); 145141486Smckusick #endif 145241486Smckusick 145341486Smckusick /* 145441486Smckusick * Everything else we recognize comes from the kernel stack, 145541486Smckusick * so we convert off to an absolute address (if not already) 145641486Smckusick * for simplicity. 145741486Smckusick */ 145841486Smckusick if (off < (int *)ctob(UPAGES)) 145949134Skarels off = (int *)((u_int)off + (u_int)kstack); 146041486Smckusick 146141486Smckusick /* 146241486Smckusick * 68020 registers. 146354857Shibler * We know that the HP-UX registers are in the same order as ours. 146441486Smckusick * The only difference is that their PS is 2 bytes instead of a 146541486Smckusick * padded 4 like ours throwing the alignment off. 146641486Smckusick */ 146748478Skarels if (off >= ar0 && off < &ar0[18]) { 146841486Smckusick /* 146941486Smckusick * PS: return low word and high word of PC as HP-UX would 147041486Smckusick * (e.g. &u.u_ar0[16.5]). 147141486Smckusick */ 147248478Skarels if (off == &ar0[PS]) 147348478Skarels raddr = (u_int) &((short *)ar0)[PS*2+1]; 147441486Smckusick /* 147541486Smckusick * PC: off will be &u.u_ar0[16.5] 147641486Smckusick */ 147748478Skarels else if (off == (int *)&(((short *)ar0)[PS*2+1])) 147848478Skarels raddr = (u_int) &ar0[PC]; 147941486Smckusick /* 148041486Smckusick * D0-D7, A0-A7: easy 148141486Smckusick */ 148241486Smckusick else 148348478Skarels raddr = (u_int) &ar0[(int)(off - ar0)]; 148449134Skarels return((int)(raddr - (u_int)kstack)); 148541486Smckusick } 148641486Smckusick 148741486Smckusick /* everything else */ 148841486Smckusick return(-1); 148941486Smckusick } 149041486Smckusick 149141486Smckusick /* 149254857Shibler * Kludge up a uarea dump so that HP-UX debuggers can find out 149341486Smckusick * what they need. IMPORTANT NOTE: we do not EVEN attempt to 149441486Smckusick * convert the entire user struct. 149541486Smckusick */ 149641486Smckusick hpuxdumpu(vp, cred) 149741486Smckusick struct vnode *vp; 149841486Smckusick struct ucred *cred; 149941486Smckusick { 150048478Skarels struct proc *p = curproc; 150141486Smckusick int error; 150241486Smckusick struct hpuxuser *faku; 150341486Smckusick struct bsdfp *bp; 150441486Smckusick short *foop; 150541486Smckusick 150641486Smckusick faku = (struct hpuxuser *)malloc((u_long)ctob(1), M_TEMP, M_WAITOK); 150741486Smckusick /* 150841486Smckusick * Make sure there is no mistake about this 150941486Smckusick * being a real user structure. 151041486Smckusick */ 151141486Smckusick bzero((caddr_t)faku, ctob(1)); 151241486Smckusick /* 151341486Smckusick * Fill in the process sizes. 151441486Smckusick */ 151548478Skarels faku->hpuxu_tsize = p->p_vmspace->vm_tsize; 151648478Skarels faku->hpuxu_dsize = p->p_vmspace->vm_dsize; 151748478Skarels faku->hpuxu_ssize = p->p_vmspace->vm_ssize; 151841486Smckusick /* 151941486Smckusick * Fill in the exec header for CDB. 152041486Smckusick * This was saved back in exec(). As far as I can tell CDB 152141486Smckusick * only uses this information to verify that a particular 152241486Smckusick * core file goes with a particular binary. 152341486Smckusick */ 152449134Skarels bcopy((caddr_t)p->p_addr->u_pcb.pcb_exec, 152541486Smckusick (caddr_t)&faku->hpuxu_exdata, sizeof (struct hpux_exec)); 152641486Smckusick /* 152741486Smckusick * Adjust user's saved registers (on kernel stack) to reflect 152854857Shibler * HP-UX order. Note that HP-UX saves the SR as 2 bytes not 4 152941486Smckusick * so we have to move it up. 153041486Smckusick */ 153152381Smckusick faku->hpuxu_ar0 = p->p_md.md_regs; 153252381Smckusick foop = (short *) p->p_md.md_regs; 153341486Smckusick foop[32] = foop[33]; 153441486Smckusick foop[33] = foop[34]; 153541486Smckusick foop[34] = foop[35]; 153641486Smckusick #ifdef FPCOPROC 153741486Smckusick /* 153854857Shibler * Copy 68881 registers from our PCB format to HP-UX format 153941486Smckusick */ 154049134Skarels bp = (struct bsdfp *) &p->p_addr->u_pcb.pcb_fpregs; 154141486Smckusick bcopy((caddr_t)bp->save, (caddr_t)faku->hpuxu_fp.hpfp_save, 154241486Smckusick sizeof(bp->save)); 154341486Smckusick bcopy((caddr_t)bp->ctrl, (caddr_t)faku->hpuxu_fp.hpfp_ctrl, 154441486Smckusick sizeof(bp->ctrl)); 154541486Smckusick bcopy((caddr_t)bp->reg, (caddr_t)faku->hpuxu_fp.hpfp_reg, 154641486Smckusick sizeof(bp->reg)); 154741486Smckusick #endif 154841486Smckusick /* 154941486Smckusick * Slay the dragon 155041486Smckusick */ 155141486Smckusick faku->hpuxu_dragon = -1; 155241486Smckusick /* 155341486Smckusick * Dump this artfully constructed page in place of the 155441486Smckusick * user struct page. 155541486Smckusick */ 155648478Skarels error = vn_rdwr(UIO_WRITE, vp, (caddr_t)faku, ctob(1), (off_t)0, 155748478Skarels UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, 155849134Skarels (int *)NULL, p); 155941486Smckusick /* 156041486Smckusick * Dump the remaining UPAGES-1 pages normally 156141486Smckusick */ 156241486Smckusick if (!error) 156349134Skarels error = vn_rdwr(UIO_WRITE, vp, kstack + ctob(1), 156441486Smckusick ctob(UPAGES-1), (off_t)ctob(1), UIO_SYSSPACE, 156549134Skarels IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p); 156641486Smckusick free((caddr_t)faku, M_TEMP); 156741486Smckusick return(error); 156841486Smckusick } 156941486Smckusick 157041486Smckusick /* 157141486Smckusick * The remaining routines are essentially the same as those in kern_xxx.c 157241486Smckusick * and vfs_xxx.c as defined under "#ifdef COMPAT". We replicate them here 157341486Smckusick * to avoid HPUXCOMPAT dependencies in those files and to make sure that 157441486Smckusick * HP-UX compatibility still works even when COMPAT is not defined. 157541486Smckusick */ 157655832Shibler #ifdef COMPAT_OHPUX 157755832Shibler 157845753Smckusick #define HPUX_HZ 50 157945753Smckusick 1580*56506Sbostic #include <sys/times.h> 158141486Smckusick 158241486Smckusick /* from old timeb.h */ 158341486Smckusick struct hpuxtimeb { 158441486Smckusick time_t time; 158541486Smckusick u_short millitm; 158641486Smckusick short timezone; 158741486Smckusick short dstflag; 158841486Smckusick }; 158941486Smckusick 159041486Smckusick /* ye ole stat structure */ 159141486Smckusick struct ohpuxstat { 159253481Smckusick u_short ohst_dev; 159341486Smckusick u_short ohst_ino; 159441486Smckusick u_short ohst_mode; 159541486Smckusick short ohst_nlink; 159641486Smckusick short ohst_uid; 159741486Smckusick short ohst_gid; 159853481Smckusick u_short ohst_rdev; 159941486Smckusick int ohst_size; 160041486Smckusick int ohst_atime; 160141486Smckusick int ohst_mtime; 160241486Smckusick int ohst_ctime; 160341486Smckusick }; 160441486Smckusick 160541486Smckusick /* 160641486Smckusick * SYS V style setpgrp() 160741486Smckusick */ 160843452Shibler ohpuxsetpgrp(p, uap, retval) 160943452Shibler register struct proc *p; 161043452Shibler int *uap, *retval; 161141486Smckusick { 161241486Smckusick if (p->p_pid != p->p_pgid) 161348478Skarels enterpgrp(p, p->p_pid, 0); 161443452Shibler *retval = p->p_pgid; 161545753Smckusick return (0); 161641486Smckusick } 161741486Smckusick 161854917Storek struct ohpuxtime_args { 161954917Storek long *tp; 162054917Storek }; 162143452Shibler ohpuxtime(p, uap, retval) 162243452Shibler struct proc *p; 162354917Storek register struct ohpuxtime_args *uap; 162454917Storek int *retval; 162541486Smckusick { 162645753Smckusick int error = 0; 162741486Smckusick 162841486Smckusick if (uap->tp) 162943452Shibler error = copyout((caddr_t)&time.tv_sec, (caddr_t)uap->tp, 163043452Shibler sizeof (long)); 163154917Storek *(time_t *)retval = time.tv_sec; 163244421Skarels return (error); 163341486Smckusick } 163441486Smckusick 163554917Storek struct ohpuxstime_args { 163654917Storek int time; 163754917Storek }; 163843452Shibler ohpuxstime(p, uap, retval) 163943452Shibler struct proc *p; 164054917Storek register struct ohpuxstime_args *uap; 164143452Shibler int *retval; 164241486Smckusick { 164341486Smckusick struct timeval tv; 164443452Shibler int s, error; 164541486Smckusick 164641486Smckusick tv.tv_sec = uap->time; 164741486Smckusick tv.tv_usec = 0; 164848478Skarels if (error = suser(p->p_ucred, &p->p_acflag)) 164944421Skarels return (error); 165041486Smckusick 165141486Smckusick /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ 165241486Smckusick boottime.tv_sec += tv.tv_sec - time.tv_sec; 165341486Smckusick s = splhigh(); time = tv; splx(s); 165441486Smckusick resettodr(); 165544421Skarels return (0); 165641486Smckusick } 165741486Smckusick 165854917Storek struct ohpuxftime_args { 165954917Storek struct hpuxtimeb *tp; 166054917Storek }; 166143452Shibler ohpuxftime(p, uap, retval) 166243452Shibler struct proc *p; 166354917Storek register struct ohpuxftime_args *uap; 166443452Shibler int *retval; 166543452Shibler { 166641486Smckusick struct hpuxtimeb tb; 166741486Smckusick int s; 166841486Smckusick 166941486Smckusick s = splhigh(); 167041486Smckusick tb.time = time.tv_sec; 167141486Smckusick tb.millitm = time.tv_usec / 1000; 167241486Smckusick splx(s); 167341486Smckusick tb.timezone = tz.tz_minuteswest; 167441486Smckusick tb.dstflag = tz.tz_dsttime; 167544421Skarels return (copyout((caddr_t)&tb, (caddr_t)uap->tp, sizeof (tb))); 167641486Smckusick } 167741486Smckusick 167854917Storek struct ohpuxalarm_args { 167954917Storek int deltat; 168054917Storek }; 168143452Shibler ohpuxalarm(p, uap, retval) 168243452Shibler register struct proc *p; 168354917Storek register struct ohpuxalarm_args *uap; 168443452Shibler int *retval; 168541486Smckusick { 168641486Smckusick int s = splhigh(); 168741486Smckusick 168841486Smckusick untimeout(realitexpire, (caddr_t)p); 168941486Smckusick timerclear(&p->p_realtimer.it_interval); 169043452Shibler *retval = 0; 169141486Smckusick if (timerisset(&p->p_realtimer.it_value) && 169241486Smckusick timercmp(&p->p_realtimer.it_value, &time, >)) 169343452Shibler *retval = p->p_realtimer.it_value.tv_sec - time.tv_sec; 169441486Smckusick if (uap->deltat == 0) { 169541486Smckusick timerclear(&p->p_realtimer.it_value); 169641486Smckusick splx(s); 169744421Skarels return (0); 169841486Smckusick } 169941486Smckusick p->p_realtimer.it_value = time; 170041486Smckusick p->p_realtimer.it_value.tv_sec += uap->deltat; 170141486Smckusick timeout(realitexpire, (caddr_t)p, hzto(&p->p_realtimer.it_value)); 170241486Smckusick splx(s); 170344421Skarels return (0); 170441486Smckusick } 170541486Smckusick 170654917Storek struct ohpuxnice_args { 170754917Storek int niceness; 170854917Storek }; 170943452Shibler ohpuxnice(p, uap, retval) 171043452Shibler register struct proc *p; 171154917Storek register struct ohpuxnice_args *uap; 171243452Shibler int *retval; 171341486Smckusick { 171443452Shibler int error; 171541486Smckusick 171643452Shibler error = donice(p, p, (p->p_nice-NZERO)+uap->niceness); 171743452Shibler if (error == 0) 171843452Shibler *retval = p->p_nice - NZERO; 171944421Skarels return (error); 172041486Smckusick } 172141486Smckusick 172254917Storek struct ohpuxtimes_args { 172354917Storek struct tms *tmsb; 172454917Storek }; 172543452Shibler ohpuxtimes(p, uap, retval) 172643452Shibler struct proc *p; 172754917Storek register struct ohpuxtimes_args *uap; 172854917Storek int *retval; 172941486Smckusick { 173054771Storek struct timeval ru, rs; 173141486Smckusick struct tms atms; 173243452Shibler int error; 173341486Smckusick 173454771Storek calcru(p, &ru, &rs, NULL); 173554771Storek atms.tms_utime = hpuxscale(&ru); 173654771Storek atms.tms_stime = hpuxscale(&rs); 173748478Skarels atms.tms_cutime = hpuxscale(&p->p_stats->p_cru.ru_utime); 173848478Skarels atms.tms_cstime = hpuxscale(&p->p_stats->p_cru.ru_stime); 173943452Shibler error = copyout((caddr_t)&atms, (caddr_t)uap->tmsb, sizeof (atms)); 174043452Shibler if (error == 0) 174154917Storek *(time_t *)retval = hpuxscale(&time) - hpuxscale(&boottime); 174244421Skarels return (error); 174341486Smckusick } 174441486Smckusick 174545753Smckusick /* 174645753Smckusick * Doesn't exactly do what the documentation says. 174745753Smckusick * What we really do is return 1/HPUX_HZ-th of a second since that 174845753Smckusick * is what HP-UX returns. 174945753Smckusick */ 175045753Smckusick hpuxscale(tvp) 175141486Smckusick register struct timeval *tvp; 175241486Smckusick { 175345753Smckusick return (tvp->tv_sec * HPUX_HZ + tvp->tv_usec * HPUX_HZ / 1000000); 175441486Smckusick } 175541486Smckusick 175641486Smckusick /* 175741486Smckusick * Set IUPD and IACC times on file. 175841486Smckusick * Can't set ICHG. 175941486Smckusick */ 176054917Storek struct ohpuxutime_args { 176154917Storek char *fname; 176254917Storek time_t *tptr; 176354917Storek }; 176443452Shibler ohpuxutime(p, uap, retval) 176543452Shibler struct proc *p; 176654917Storek register struct ohpuxutime_args *uap; 176743452Shibler int *retval; 176843452Shibler { 176948478Skarels register struct vnode *vp; 177041486Smckusick struct vattr vattr; 177141486Smckusick time_t tv[2]; 177243452Shibler int error; 177348478Skarels struct nameidata nd; 177441486Smckusick 177541486Smckusick if (uap->tptr) { 177643452Shibler error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)); 177743452Shibler if (error) 177844421Skarels return (error); 177941486Smckusick } else 178041486Smckusick tv[0] = tv[1] = time.tv_sec; 178141486Smckusick vattr_null(&vattr); 178254107Smckusick vattr.va_atime.ts_sec = tv[0]; 178354107Smckusick vattr.va_atime.ts_nsec = 0; 178454107Smckusick vattr.va_mtime.ts_sec = tv[1]; 178554107Smckusick vattr.va_mtime.ts_nsec = 0; 178652330Smckusick NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 178752330Smckusick if (error = namei(&nd)) 178844421Skarels return (error); 178952330Smckusick vp = nd.ni_vp; 179042154Smckusick if (vp->v_mount->mnt_flag & MNT_RDONLY) 179143452Shibler error = EROFS; 179241486Smckusick else 179352330Smckusick error = VOP_SETATTR(vp, &vattr, nd.ni_cnd.cn_cred, p); 179441486Smckusick vput(vp); 179544421Skarels return (error); 179641486Smckusick } 179741486Smckusick 179843452Shibler ohpuxpause(p, uap, retval) 179943452Shibler struct proc *p; 180043452Shibler int *uap, *retval; 180141486Smckusick { 180249134Skarels (void) tsleep(kstack, PPAUSE | PCATCH, "pause", 0); 180342155Skarels /* always return EINTR rather than ERESTART... */ 180444421Skarels return (EINTR); 180541486Smckusick } 180641486Smckusick 180741486Smckusick /* 180841486Smckusick * The old fstat system call. 180941486Smckusick */ 181054917Storek struct ohpuxfstat_args { 181154917Storek int fd; 181254917Storek struct ohpuxstat *sb; 181354917Storek }; 181443452Shibler ohpuxfstat(p, uap, retval) 181543452Shibler struct proc *p; 181654917Storek register struct ohpuxfstat_args *uap; 181743452Shibler int *retval; 181843452Shibler { 181945923Smckusick register struct filedesc *fdp = p->p_fd; 182041486Smckusick struct file *fp; 182141486Smckusick 182248478Skarels if (((unsigned)uap->fd) >= fdp->fd_nfiles || 182348478Skarels (fp = fdp->fd_ofiles[uap->fd]) == NULL) 182444421Skarels return (EBADF); 182543452Shibler if (fp->f_type != DTYPE_VNODE) 182644421Skarels return (EINVAL); 182755282Smckusick return (ohpuxstat1((struct vnode *)fp->f_data, uap->sb, p)); 182841486Smckusick } 182941486Smckusick 183041486Smckusick /* 183141486Smckusick * Old stat system call. This version follows links. 183241486Smckusick */ 183354917Storek struct ohpuxstat_args { 183454917Storek char *fname; 183554917Storek struct ohpuxstat *sb; 183654917Storek }; 183743452Shibler ohpuxstat(p, uap, retval) 183843452Shibler struct proc *p; 183954917Storek register struct ohpuxstat_args *uap; 184043452Shibler int *retval; 184143452Shibler { 184243452Shibler int error; 184348478Skarels struct nameidata nd; 184441486Smckusick 184552330Smckusick NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p); 184652330Smckusick if (error = namei(&nd)) 184744421Skarels return (error); 184855282Smckusick error = ohpuxstat1(nd.ni_vp, uap->sb, p); 184952330Smckusick vput(nd.ni_vp); 185044421Skarels return (error); 185141486Smckusick } 185241486Smckusick 185341486Smckusick int 185455282Smckusick ohpuxstat1(vp, ub, p) 185541486Smckusick register struct vnode *vp; 185641486Smckusick struct ohpuxstat *ub; 185755282Smckusick struct proc *p; 185841486Smckusick { 185941486Smckusick struct ohpuxstat ds; 186041486Smckusick struct vattr vattr; 186141486Smckusick register int error; 186241486Smckusick 186355282Smckusick error = VOP_GETATTR(vp, &vattr, p->p_ucred, p); 186441486Smckusick if (error) 186541486Smckusick return(error); 186641486Smckusick /* 186741486Smckusick * Copy from inode table 186841486Smckusick */ 186941486Smckusick ds.ohst_dev = vattr.va_fsid; 187041486Smckusick ds.ohst_ino = (short)vattr.va_fileid; 187141486Smckusick ds.ohst_mode = (u_short)vattr.va_mode; 187241486Smckusick ds.ohst_nlink = vattr.va_nlink; 187341486Smckusick ds.ohst_uid = (short)vattr.va_uid; 187441486Smckusick ds.ohst_gid = (short)vattr.va_gid; 187553481Smckusick ds.ohst_rdev = (u_short)vattr.va_rdev; 187641486Smckusick ds.ohst_size = (int)vattr.va_size; 187754107Smckusick ds.ohst_atime = (int)vattr.va_atime.ts_sec; 187854107Smckusick ds.ohst_mtime = (int)vattr.va_mtime.ts_sec; 187954107Smckusick ds.ohst_ctime = (int)vattr.va_ctime.ts_sec; 188041486Smckusick return (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds))); 188141486Smckusick } 188241486Smckusick #endif 188355832Shibler #endif 1884