⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kern_descrip.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$Id: kern_descrip.c,v 1.3 2002/05/05 21:30:13 patrik Exp $ *//*	$OpenBSD: kern_descrip.c,v 1.18 1999/07/13 15:17:50 provos Exp $	*//*	$NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $	*//* * Copyright (c) 1982, 1986, 1989, 1991, 1993 *	The Regents of the University of California.  All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)kern_descrip.c	8.6 (Berkeley) 4/19/94 */#include <sys/param.h>#include <sys/systm.h>#include <sys/filedesc.h>#include <sys/kernel.h>#include <sys/vnode.h>#include <sys/proc.h>#include <sys/file.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/fcntl.h>#include <sys/malloc.h>#include <sys/syslog.h>#include <sys/ucred.h>#include <sys/unistd.h>#include <sys/resourcevar.h>#include <sys/conf.h>#if 0#include <sys/mount.h>#endif#include <sys/syscallargs.h>#include <vm/vm.h>#ifdef NOTUSED_BY_PMON#include <sys/pipe.h>#endif#ifdef PMON#include <fcntl.h>#endif/* * Descriptor management. */struct filelist filehead;	/* head of list of open files */int nfiles;			/* actual number of open files */static __inline void fd_used __P((struct filedesc *, int));static __inline void fd_unused __P((struct filedesc *, int));int finishdup __P((struct filedesc *, int, int, register_t *));static __inline voidfd_used(fdp, fd)	register struct filedesc *fdp;	register int fd;{	if (fd > fdp->fd_lastfile)		fdp->fd_lastfile = fd;}static __inline voidfd_unused(fdp, fd)	register struct filedesc *fdp;	register int fd;{	if (fd < fdp->fd_freefile)		fdp->fd_freefile = fd;#ifdef DIAGNOSTIC	if (fd > fdp->fd_lastfile)		panic("fd_unused: fd_lastfile inconsistent");#endif	if (fd == fdp->fd_lastfile) {		do {			fd--;		} while (fd >= 0 && fdp->fd_ofiles[fd] == NULL);		fdp->fd_lastfile = fd;	}}/* * System calls on descriptors. *//* * Duplicate a file descriptor. *//* ARGSUSED */intsys_dup(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	struct sys_dup_args /* {		syscallarg(u_int) fd;	} */ *uap = v;	register struct filedesc *fdp = p->p_fd;	register int old = SCARG(uap, fd);	int new;	int error;	if ((u_int)old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL)		return (EBADF);	if ((error = fdalloc(p, 0, &new)) != 0)		return (error);	return (finishdup(fdp, old, new, retval));}/* * Duplicate a file descriptor to a particular value. *//* ARGSUSED */intsys_dup2(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	struct sys_dup2_args /* {		syscallarg(u_int) from;		syscallarg(u_int) to;	} */ *uap = v;	register struct filedesc *fdp = p->p_fd;	register int old = SCARG(uap, from), new = SCARG(uap, to);	int i, error;	if ((u_int)old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL ||#ifdef NOTUSED_BY_PMON	    (u_int)new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||#endif	    (u_int)new >= maxfiles)		return (EBADF);	if (old == new) {		*retval = new;		return (0);	}	if (new >= fdp->fd_nfiles) {		if ((error = fdalloc(p, new, &i)) != 0)			return (error);		if (new != i)			panic("dup2: fdalloc");	} else {		(void) fdrelease(p, new);	}	return (finishdup(fdp, old, new, retval));}/* * The file control system call. *//* ARGSUSED */intsys_fcntl(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_fcntl_args /* {		syscallarg(int) fd;		syscallarg(int) cmd;		syscallarg(void *) arg;	} */ *uap = v;	int fd = SCARG(uap, fd);	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	int i, tmp, error;#ifndef PMON	struct vnode *vp;	int flg = F_POSIX;	struct flock fl;#endif	int newmin;	if ((u_int)fd >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[fd]) == NULL)		return (EBADF);	switch (SCARG(uap, cmd)) {	case F_DUPFD:		newmin = (long)SCARG(uap, arg);#ifdef NOTUSED_BY_PMON		if ((u_int)newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||#else		if (#endif		    (u_int)newmin >= maxfiles)			return (EINVAL);		if ((error = fdalloc(p, newmin, &i)) != 0)			return (error);		return (finishdup(fdp, fd, i, retval));	case F_GETFD:		*retval = fdp->fd_ofileflags[fd] & UF_EXCLOSE ? 1 : 0;		return (0);	case F_SETFD:		if ((long)SCARG(uap, arg) & 1)			fdp->fd_ofileflags[fd] |= UF_EXCLOSE;		else			fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;		return (0);	case F_GETFL:		*retval = OFLAGS(fp->f_flag);		return (0);	case F_SETFL:		fp->f_flag &= ~FCNTLFLAGS;		fp->f_flag |= FFLAGS((long)SCARG(uap, arg)) & FCNTLFLAGS;		tmp = fp->f_flag & FNONBLOCK;		error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);		if (error)			return (error);		tmp = fp->f_flag & FASYNC;		error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);		if (!error)			return (0);		fp->f_flag &= ~FNONBLOCK;		tmp = 0;		(void) (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);		return (error);	case F_GETOWN:		if (fp->f_type == DTYPE_SOCKET) {			*retval = ((struct socket *)fp->f_data)->so_pgid;			return (0);		}		error = (*fp->f_ops->fo_ioctl)			(fp, TIOCGPGRP, (caddr_t)retval, p);		*retval = -*retval;		return (error);#ifdef NOTUSED_BY_PMON	case F_SETOWN:		if (fp->f_type == DTYPE_SOCKET) {			struct socket *so = (struct socket *)fp->f_data;			so->so_pgid = (long)SCARG(uap, arg);			so->so_siguid = p->p_cred->p_ruid;			so->so_sigeuid = p->p_ucred->cr_uid;			return (0);		}		if ((long)SCARG(uap, arg) <= 0) {			SCARG(uap, arg) = (void *)(-(long)SCARG(uap, arg));		} else {			struct proc *p1 = pfind((long)SCARG(uap, arg));			if (p1 == 0)				return (ESRCH);			SCARG(uap, arg) = (void *)(long)p1->p_pgrp->pg_id;		}		return ((*fp->f_ops->fo_ioctl)			(fp, TIOCSPGRP, (caddr_t)&SCARG(uap, arg), p));	case F_SETLKW:		flg |= F_WAIT;		/* Fall into F_SETLK */	case F_SETLK:		if (fp->f_type != DTYPE_VNODE)			return (EBADF);		vp = (struct vnode *)fp->f_data;		/* Copy in the lock structure */		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&fl,		    sizeof (fl));		if (error)			return (error);		if (fl.l_whence == SEEK_CUR)			fl.l_start += fp->f_offset;		switch (fl.l_type) {		case F_RDLCK:			if ((fp->f_flag & FREAD) == 0)				return (EBADF);			p->p_flag |= P_ADVLOCK;			return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg));		case F_WRLCK:			if ((fp->f_flag & FWRITE) == 0)				return (EBADF);			p->p_flag |= P_ADVLOCK;			return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg));		case F_UNLCK:			return (VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &fl,				F_POSIX));		default:			return (EINVAL);		}	case F_GETLK:		if (fp->f_type != DTYPE_VNODE)			return (EBADF);		vp = (struct vnode *)fp->f_data;		/* Copy in the lock structure */		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&fl,		    sizeof (fl));		if (error)			return (error);		if (fl.l_whence == SEEK_CUR)			fl.l_start += fp->f_offset;		else if (fl.l_whence != SEEK_END &&			 fl.l_whence != SEEK_SET &&			 fl.l_whence != 0)			return (EINVAL);		if (fl.l_start < 0)			return (EINVAL);		if (fl.l_type != F_RDLCK &&		    fl.l_type != F_WRLCK &&		    fl.l_type != F_UNLCK &&		    fl.l_type != 0)			return (EINVAL);		error = VOP_ADVLOCK(vp, (caddr_t)p, F_GETLK, &fl, F_POSIX);		if (error)			return (error);		return (copyout((caddr_t)&fl, (caddr_t)SCARG(uap, arg),		    sizeof (fl)));#endif	default:		return (EINVAL);	}	/* NOTREACHED */}/* * Common code for dup, dup2, and fcntl(F_DUPFD). */intfinishdup(fdp, old, new, retval)	register struct filedesc *fdp;	register int old, new;	register_t *retval;{	register struct file *fp;	fp = fdp->fd_ofiles[old];	if (fp->f_count == LONG_MAX-2)		return (EDEADLK);	fdp->fd_ofiles[new] = fp;	fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;	fp->f_count++;	fd_used(fdp, new);	*retval = new;	return (0);}voidfdremove(fdp, fd)	struct filedesc *fdp;	int fd;{	fdp->fd_ofiles[fd] = NULL;	fd_unused(fdp, fd);}intfdrelease(p, fd)	struct proc *p;	int fd;{	register struct filedesc *fdp = p->p_fd;	register struct file **fpp, *fp;	register char *pf;	fpp = &fdp->fd_ofiles[fd];	fp = *fpp;	if (fp == NULL)		return (EBADF);	pf = &fdp->fd_ofileflags[fd];#ifndef PMON#if defined(UVM)	if (*pf & UF_MAPPED) {		/* XXX: USELESS? XXXCDC check it */		p->p_fd->fd_ofileflags[fd] &= ~UF_MAPPED;	}#else	if (*pf & UF_MAPPED)		(void) munmapfd(p, fd);#endif#endif	*fpp = NULL;	*pf = 0;	fd_unused(fdp, fd);	return (closef(fp, p));}/* * Close a file descriptor. *//* ARGSUSED */intsys_close(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	struct sys_close_args /* {		syscallarg(int) fd;	} */ *uap = v;	int fd = SCARG(uap, fd);	register struct filedesc *fdp = p->p_fd;	if ((u_int)fd >= fdp->fd_nfiles)		return (EBADF);	return (fdrelease(p, fd));}/* * Return status information about a file descriptor. *//* ARGSUSED */intsys_fstat(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_fstat_args /* {		syscallarg(int) fd;		syscallarg(struct stat *) sb;	} */ *uap = v;	int fd = SCARG(uap, fd);	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	struct stat ub;	int error;	if ((u_int)fd >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[fd]) == NULL)		return (EBADF);	switch (fp->f_type) {#ifndef PMON	case DTYPE_VNODE:		error = vn_stat((struct vnode *)fp->f_data, &ub, p);		break;#endif	case DTYPE_SOCKET:		error = soo_stat((struct socket *)fp->f_data, &ub);		break;#ifdef NOTUSED_BY_PMON#ifndef OLD_PIPE	case DTYPE_PIPE:		error = pipe_stat((struct pipe *)fp->f_data, &ub);		break;#endif#endif	default:		panic("fstat");		/*NOTREACHED*/	}	if (error == 0) {		/* Don't let non-root see generation numbers		   (for NFS security) */		if (suser(p->p_ucred, &p->p_acflag))			ub.st_gen = 0;		error = copyout((caddr_t)&ub, (caddr_t)SCARG(uap, sb),		    sizeof (ub));	}	return (error);}/* * Return pathconf information about a file descriptor. *//* ARGSUSED */intsys_fpathconf(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_fpathconf_args /* {		syscallarg(int) fd;		syscallarg(int) name;	} */ *uap = v;	int fd = SCARG(uap, fd);	struct filedesc *fdp = p->p_fd;	struct file *fp;#ifndef PMON	struct vnode *vp;#endif	if ((u_int)fd >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[fd]) == NULL)		return (EBADF);	switch (fp->f_type) {#ifndef OLD_PIPE	case DTYPE_PIPE:#endif	case DTYPE_SOCKET:		if (SCARG(uap, name) != _PC_PIPE_BUF)			return (EINVAL);		*retval = PIPE_BUF;		return (0);#ifndef PMON	case DTYPE_VNODE:		vp = (struct vnode *)fp->f_data;		return (VOP_PATHCONF(vp, SCARG(uap, name), retval));#endif	default:		panic("fpathconf");	}	/*NOTREACHED*/

⌨️ 快捷键说明

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