hpux_compat.c

来自「早期freebsd实现」· C语言 代码 · 共 2,252 行 · 第 1/4 页

C
2,252
字号
			error = 0;		}	}	return (error);}hpuxreadv(p, uap, retval)	struct proc *p;	struct hpuxrw_args *uap;	int *retval;{	int error;	error = readv(p, uap, retval);	if (error == EWOULDBLOCK) {		char *fp = &p->p_fd->fd_ofileflags[uap->fd];		if (*fp & UF_NONBLOCK_ON) {			*retval = -1;			error = OEAGAIN;		} else if (*fp & UF_FNDELAY_ON) {			*retval = 0;			error = 0;		}	}	return (error);}hpuxwritev(p, uap, retval)	struct proc *p;	struct hpuxrw_args *uap;	int *retval;{	int error;	error = writev(p, uap, retval);	if (error == EWOULDBLOCK) {		char *fp = &p->p_fd->fd_ofileflags[uap->fd];		if (*fp & UF_NONBLOCK_ON) {			*retval = -1;			error = OEAGAIN;		} else if (*fp & UF_FNDELAY_ON) {			*retval = 0;			error = 0;		}	}	return (error);}/* * 4.3bsd dup allows dup2 to come in on the same syscall entry * and hence allows two arguments.  HP-UX dup has only one arg. */struct hpuxdup_args {	int	i;};hpuxdup(p, uap, retval)	struct proc *p;	register struct hpuxdup_args *uap;	int *retval;{	register struct filedesc *fdp = p->p_fd;	struct file *fp;	int fd, error;	if (((unsigned)uap->i) >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[uap->i]) == NULL)		return (EBADF);	if (error = fdalloc(p, 0, &fd))		return (error);	fdp->fd_ofiles[fd] = fp;	fdp->fd_ofileflags[fd] = fdp->fd_ofileflags[uap->i] &~ UF_EXCLOSE;	fp->f_count++;	if (fd > fdp->fd_lastfile)		fdp->fd_lastfile = fd;	*retval = fd;	return (0);}struct hpuxutssys_args {	struct hpuxutsname *uts;	int dev;	int request;};hpuxutssys(p, uap, retval)	struct proc *p;	register struct hpuxutssys_args *uap;	int *retval;{	register int i;	int error;	switch (uap->request) {	/* uname */	case 0:		/* fill in machine type */		switch (machineid) {		case HP_320:			protoutsname.machine[6] = '2';			break;		/* includes 318 and 319 */		case HP_330:			protoutsname.machine[6] = '3';			break;		case HP_340:			protoutsname.machine[6] = '4';			break;		case HP_350:			protoutsname.machine[6] = '5';			break;		case HP_360:			protoutsname.machine[6] = '6';			break;		case HP_370:			protoutsname.machine[6] = '7';			break;		/* includes 345 */		case HP_375:			protoutsname.machine[6] = '7';			protoutsname.machine[7] = '5';			break;		/* includes 425 */		case HP_380:			protoutsname.machine[6] = '8';			break;		case HP_433:			protoutsname.machine[5] = '4';			protoutsname.machine[6] = '3';			protoutsname.machine[7] = '3';			break;		}		/* copy hostname (sans domain) to nodename */		for (i = 0; i < 8 && hostname[i] != '.'; i++)			protoutsname.nodename[i] = hostname[i];		protoutsname.nodename[i] = '\0';		error = copyout((caddr_t)&protoutsname, (caddr_t)uap->uts,				sizeof(struct hpuxutsname));		break;	/* gethostname */	case 5:		/* uap->dev is length */		if (uap->dev > hostnamelen + 1)			uap->dev = hostnamelen + 1;		error = copyout((caddr_t)hostname, (caddr_t)uap->uts,				uap->dev);		break;	case 1:	/* ?? */	case 2:	/* ustat */	case 3:	/* ?? */	case 4:	/* sethostname */	default:		error = EINVAL;		break;	}	return (error);}struct hpuxsysconf_args {	int	name;};hpuxsysconf(p, uap, retval)	struct proc *p;	struct hpuxsysconf_args *uap;	int *retval;{	switch (uap->name) {	/* clock ticks per second */	case HPUX_SYSCONF_CLKTICK:		*retval = hz;		break;	/* open files */	case HPUX_SYSCONF_OPENMAX:		*retval = NOFILE;		break;	/* architecture */	case HPUX_SYSCONF_CPUTYPE:		switch (machineid) {		case HP_320:		case HP_330:		case HP_350:			*retval = HPUX_SYSCONF_CPUM020;			break;		case HP_340:		case HP_360:		case HP_370:		case HP_375:			*retval = HPUX_SYSCONF_CPUM030;			break;		case HP_380:		case HP_433:			*retval = HPUX_SYSCONF_CPUM040;			break;		}		break;	default:		uprintf("HP-UX sysconf(%d) not implemented\n", uap->name);		return (EINVAL);	}	return (0);}struct hpuxstat_args {	char	*fname;	struct hpuxstat *hsb;};hpuxstat(p, uap, retval)	struct proc *p;	struct hpuxstat_args *uap;	int *retval;{	return (hpuxstat1(uap->fname, uap->hsb, FOLLOW, p));}struct hpuxlstat_args {	char	*fname;	struct hpuxstat *hsb;};hpuxlstat(p, uap, retval)	struct proc *p;	struct hpuxlstat_args *uap;	int *retval;{	return (hpuxstat1(uap->fname, uap->hsb, NOFOLLOW, p));}struct hpuxfstat_args {	int	fdes;	struct	hpuxstat *hsb;};hpuxfstat(p, uap, retval)	struct proc *p;	register struct hpuxfstat_args *uap;	int *retval;{	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	struct stat sb;	int error;	if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[uap->fdes]) == NULL)		return (EBADF);	switch (fp->f_type) {	case DTYPE_VNODE:		error = vn_stat((struct vnode *)fp->f_data, &sb, p);		break;	case DTYPE_SOCKET:		error = soo_stat((struct socket *)fp->f_data, &sb, p);		break;	default:		panic("fstat");		/*NOTREACHED*/	}	/* is this right for sockets?? */	if (error == 0)		error = bsdtohpuxstat(&sb, uap->hsb);	return (error);}struct hpuxulimit_args {	int	cmd;	long	newlimit;};hpuxulimit(p, uap, retval)	struct proc *p;	register struct hpuxulimit_args *uap;	long *retval;{	struct rlimit *limp;	int error = 0;	limp = &p->p_rlimit[RLIMIT_FSIZE];	switch (uap->cmd) {	case 2:		uap->newlimit *= 512;		if (uap->newlimit > limp->rlim_max &&		    (error = suser(p->p_ucred, &p->p_acflag)))			break;		limp->rlim_cur = limp->rlim_max = uap->newlimit;		/* else fall into... */	case 1:		*retval = limp->rlim_max / 512;		break;	case 3:		limp = &p->p_rlimit[RLIMIT_DATA];		*retval = ctob(p->p_vmspace->vm_tsize) + limp->rlim_max;		break;	default:		error = EINVAL;		break;	}	return (error);}/* * Map "real time" priorities 0 (high) thru 127 (low) into nice * values -16 (high) thru -1 (low). */struct hpuxrtprio_args {	int pid;	int prio;};hpuxrtprio(cp, uap, retval)	struct proc *cp;	register struct hpuxrtprio_args *uap;	int *retval;{	struct proc *p;	int nice, error;	if (uap->prio < RTPRIO_MIN && uap->prio > RTPRIO_MAX &&	    uap->prio != RTPRIO_NOCHG && uap->prio != RTPRIO_RTOFF)		return (EINVAL);	if (uap->pid == 0)		p = cp;	else if ((p = pfind(uap->pid)) == 0)		return (ESRCH);	nice = p->p_nice;	if (nice < NZERO)		*retval = (nice + 16) << 3;	else		*retval = RTPRIO_RTOFF;	switch (uap->prio) {	case RTPRIO_NOCHG:		return (0);	case RTPRIO_RTOFF:		if (nice >= NZERO)			return (0);		nice = NZERO;		break;	default:		nice = (uap->prio >> 3) - 16;		break;	}	error = donice(cp, p, nice);	if (error == EACCES)		error = EPERM;	return (error);}struct hpuxadvise_args {	int	arg;};hpuxadvise(p, uap, retval)	struct proc *p;	struct hpuxadvise_args *uap;	int *retval;{	int error = 0;	switch (uap->arg) {	case 0:		p->p_md.md_flags |= MDP_HPUXMMAP;		break;	case 1:		ICIA();		break;	case 2:		DCIA();		break;	default:		error = EINVAL;		break;	}	return (error);}struct hpuxptrace_args {	int	req;	int	pid;	int	*addr;	int	data;};hpuxptrace(p, uap, retval)	struct proc *p;	struct hpuxptrace_args *uap;	int *retval;{	int error, isps = 0;	struct proc *cp;	switch (uap->req) {	/* map signal */	case PT_STEP:	case PT_CONTINUE:		if (uap->data) {			uap->data = hpuxtobsdsig(uap->data);			if (uap->data == 0)				uap->data = NSIG;		}		break;	/* map u-area offset */	case PT_READ_U:	case PT_WRITE_U:		/*		 * Big, cheezy hack: hpuxtobsduoff is really intended		 * to be called in the child context (procxmt) but we		 * do it here in the parent context to avoid hacks in		 * the MI sys_process.c file.  This works only because		 * we can access the child's md_regs pointer and it		 * has the correct value (the child has already trapped		 * into the kernel).		 */		if ((cp = pfind(uap->pid)) == 0)			return (ESRCH);		uap->addr = (int *) hpuxtobsduoff(uap->addr, &isps, cp);		/*		 * Since HP-UX PS is only 16-bits in ar0, requests		 * to write PS actually contain the PS in the high word		 * and the high half of the PC (the following register)		 * in the low word.  Move the PS value to where BSD		 * expects it.		 */		if (isps && uap->req == PT_WRITE_U)			uap->data >>= 16;		break;	}	error = ptrace(p, uap, retval);	/*	 * Align PS as HP-UX expects it (see WRITE_U comment above).	 * Note that we do not return the high part of PC like HP-UX	 * would, but the HP-UX debuggers don't require it.	 */	if (isps && error == 0 && uap->req == PT_READ_U)		*retval <<= 16;	return (error);}struct hpuxgetdomainname_args {	char	*domainname;	u_int	len;};hpuxgetdomainname(p, uap, retval)	struct proc *p;	register struct hpuxgetdomainname_args *uap;	int *retval;{	if (uap->len > domainnamelen + 1)		uap->len = domainnamelen + 1;	return (copyout(domainname, uap->domainname, uap->len));}struct hpuxsetdomainname_args {	char	*domainname;	u_int	len;};hpuxsetdomainname(p, uap, retval)	struct proc *p;	register struct hpuxsetdomainname_args *uap;	int *retval;{	int error;	if (error = suser(p->p_ucred, &p->p_acflag))		return (error);	if (uap->len > sizeof (domainname) - 1)		return (EINVAL);	domainnamelen = uap->len;	error = copyin(uap->domainname, domainname, uap->len);	domainname[domainnamelen] = 0;	return (error);}#ifdef SYSVSHM#include <sys/shm.h>hpuxshmat(p, uap, retval)	struct proc *p;	int *uap, *retval;{	return (shmat(p, uap, retval));}hpuxshmdt(p, uap, retval)	struct proc *p;	int *uap, *retval;{	return (shmdt(p, uap, retval));}hpuxshmget(p, uap, retval)	struct proc *p;	int *uap, *retval;{	return (shmget(p, uap, retval));}hpuxshmctl(p, uap, retval)	struct proc *p;	int *uap, *retval;{	return (hpuxshmctl1(p, uap, retval, 0));}hpuxnshmctl(p, uap, retval)	struct proc *p;	int *uap, *retval;{	return (hpuxshmctl1(p, uap, retval, 1));}/* * Handle HP-UX specific commands. */struct hpuxshmctl_args {	int shmid;	int cmd;	caddr_t buf;};hpuxshmctl1(p, uap, retval, isnew)	struct proc *p;	struct hpuxshmctl_args *uap;	int *retval;	int isnew;{	register struct shmid_ds *shp;	register struct ucred *cred = p->p_ucred;	struct hpuxshmid_ds sbuf;	int error;	if (error = shmvalid(uap->shmid))		return (error);	shp = &shmsegs[uap->shmid % SHMMMNI];	switch (uap->cmd) {	case SHM_LOCK:	case SHM_UNLOCK:		/* don't really do anything, but make them think we did */		if (cred->cr_uid && cred->cr_uid != shp->shm_perm.uid &&		    cred->cr_uid != shp->shm_perm.cuid)			return (EPERM);		return (0);	case IPC_STAT:		if (!isnew)			break;		error = ipcaccess(&shp->shm_perm, IPC_R, cred);		if (error == 0) {			sbuf.shm_perm.uid = shp->shm_perm.uid;			sbuf.shm_perm.gid = shp->shm_perm.gid;			sbuf.shm_perm.cuid = shp->shm_perm.cuid;			sbuf.shm_perm.cgid = shp->shm_perm.cgid;			sbuf.shm_perm.mode = shp->shm_perm.mode;			sbuf.shm_perm.seq = shp->shm_perm.seq;			sbuf.shm_perm.key = shp->shm_perm.key;			sbuf.shm_segsz = shp->shm_segsz;			sbuf.shm_ptbl = shp->shm_handle;	/* XXX */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?