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

📄 kern_descrip.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: kern_descrip.c,v 1.3 1998/06/17 00:49:47 chris Exp $ *//* * Copyright (c) 1982, 1986, 1989, 1991 Regents of the University of California. * All rights reserved. * * 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	7.28 (Berkeley) 6/25/91 */#include "param.h"#include "systm.h"#include "filedesc.h"#include "kernel.h"#include "vnode.h"#include "proc.h"#include "file.h"#include "socket.h"#include "socketvar.h"#include "stat.h"#include "ioctl.h"#include "fcntl.h"#include "malloc.h"#include "syslog.h"#include "resourcevar.h"/* * Descriptor management. */struct file *filehead;	/* head of list of open files */int nfiles;		/* actual number of open files *//* * System calls on descriptors. *//* ARGSUSED */SYSCALL(getdtablesize)(p, uap, retval)	struct proc *p;	struct args *uap;	int *retval;{#ifdef PROM	*retval = NDFILE;#else	*retval = p->p_rlimit[RLIMIT_OFILE].rlim_cur;#endif	return (0);}/* * Duplicate a file descriptor. *//* ARGSUSED */SYSCALL(dup)(p, v, retval)	struct proc *p;	void *v;	int *retval;{        register struct args {		int	i;	} *uap = v;	register struct filedesc *fdp = p->p_fd;	struct file *fp;	int fd, error;	/*	 * XXX Compatibility	 */	if (uap->i &~ 077) { uap->i &= 077;			     return (SYSCALL(dup2)(p, uap, retval)); }	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);}/* * Duplicate a file descriptor to a particular value. *//* ARGSUSED */SYSCALL(dup2)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		u_int	from;		u_int	to;	} *uap = v;	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	register u_int old = uap->from, new = uap->to;	int i, error;	if (old >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[old]) == NULL ||#ifdef PROM	    new >= NDFILE#else	    new >= p->p_rlimit[RLIMIT_OFILE].rlim_cur#endif	    )		return (EBADF);	*retval = new;	if (old == new)		return (0);	if (new >= fdp->fd_nfiles) {		if (error = fdalloc(p, new, &i))			return (error);		if (new != i)			panic("dup2: fdalloc");	} else if (fdp->fd_ofiles[new]) {#ifndef PROM		if (fdp->fd_ofileflags[new] & UF_MAPPED)			(void) munmapfd(p, new);#endif		/*		 * dup2() must succeed even if the close has an error.		 */		(void) closef(fdp->fd_ofiles[new], p);	}	fdp->fd_ofiles[new] = fp;	fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;	fp->f_count++;	if (new > fdp->fd_lastfile)		fdp->fd_lastfile = new;	return (0);}/* * The file control system call. *//* ARGSUSED */SYSCALL(fcntl)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	fd;		int	cmd;		int	arg;	} *uap = v;	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	register char *pop;	struct vnode *vp;	int i, tmp, error, flg = F_POSIX;	struct flock fl;	if ((unsigned)uap->fd >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)		return (EBADF);	pop = &fdp->fd_ofileflags[uap->fd];	switch(uap->cmd) {	case F_DUPFD:#ifdef PROM		if ((unsigned)uap->arg >= NDFILE)			return (EINVAL);#else		if ((unsigned)uap->arg >= p->p_rlimit[RLIMIT_OFILE].rlim_cur)			return (EINVAL);#endif		if (error = fdalloc(p, uap->arg, &i))			return (error);		fdp->fd_ofiles[i] = fp;		fdp->fd_ofileflags[i] = *pop &~ UF_EXCLOSE;		fp->f_count++;		if (i > fdp->fd_lastfile)			fdp->fd_lastfile = i;		*retval = i;		return (0);	case F_GETFD:		*retval = *pop & 1;		return (0);	case F_SETFD:		*pop = (*pop &~ 1) | (uap->arg & 1);		return (0);	case F_GETFL:		*retval = OFLAGS(fp->f_flag);		return (0);	case F_SETFL:		fp->f_flag &= ~FCNTLFLAGS;		fp->f_flag |= FFLAGS(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, (int)TIOCGPGRP, (caddr_t)retval, p);		*retval = -*retval;		return (error);	case F_SETOWN:		if (fp->f_type == DTYPE_SOCKET) {			((struct socket *)fp->f_data)->so_pgid = uap->arg;			return (0);		}		if (uap->arg <= 0) {			uap->arg = -uap->arg;		} else {			struct proc *p1 = pfind(uap->arg);			if (p1 == 0)				return (ESRCH);#ifdef PROM			uap->arg = p1->p_pid;#else			uap->arg = p1->p_pgrp->pg_id;#endif		}		return ((*fp->f_ops->fo_ioctl)			(fp, (int)TIOCSPGRP, (caddr_t)&uap->arg, p));#ifndef PROM	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)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 |= SADVLCK;			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 |= SADVLCK;			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)uap->arg, (caddr_t)&fl, sizeof (fl));		if (error)			return (error);		if (fl.l_whence == SEEK_CUR)			fl.l_start += fp->f_offset;		if (error = VOP_ADVLOCK(vp, (caddr_t)p, F_GETLK, &fl, F_POSIX))			return (error);		return (copyout((caddr_t)&fl, (caddr_t)uap->arg, sizeof (fl)));#endif	default:		return (EINVAL);	}	/* NOTREACHED */}/* * Close a file descriptor. *//* ARGSUSED */SYSCALL(close)(p, v, retval)	struct proc *p;	void *v;	int *retval;{        register struct args {		int	fd;	} *uap = v;	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	register int fd = uap->fd;	register u_char *pf;	if ((unsigned)fd >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[fd]) == NULL)		return (EBADF);	pf = (u_char *)&fdp->fd_ofileflags[fd];#ifndef PROM	if (*pf & UF_MAPPED)		(void) munmapfd(p, fd);#endif	fdp->fd_ofiles[fd] = NULL;	while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)		fdp->fd_lastfile--;	if (fd < fdp->fd_freefile)		fdp->fd_freefile = fd;	*pf = 0;	return (closef(fp, p));}/* * Return status information about a file descriptor. *//* ARGSUSED */SYSCALL(fstat)(p, v, retval)	struct proc *p;	void *v;	int *retval;{	register struct args {		int	fd;		struct	stat *sb;	} *uap = v;	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	struct stat ub;	int error;	if ((unsigned)uap->fd >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)		return (EBADF);	switch (fp->f_type) {#ifndef PROM	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;	default:		panic("fstat");		/*NOTREACHED*/	}	if (error == 0)		error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));	return (error);}/* * Allocate a file descriptor for the process. */int fdexpand;fdalloc(p, want, result)	struct proc *p;	int want;	int *result;{	register struct filedesc *fdp = p->p_fd;	register int i;

⌨️ 快捷键说明

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