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

📄 kern_descrip.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
	int lim, last, nfiles;	struct file **newofile;	char *newofileflags;	/*	 * Search for a free descriptor starting at the higher	 * of want or fd_freefile.  If that fails, consider	 * expanding the ofile array.	 */#ifdef PROM	lim = NDFILE;#else	lim = p->p_rlimit[RLIMIT_OFILE].rlim_cur;#endif	for (;;) {		last = min(fdp->fd_nfiles, lim);		if ((i = want) < fdp->fd_freefile)			i = fdp->fd_freefile;		for (; i < last; i++) {			if (fdp->fd_ofiles[i] == NULL) {				fdp->fd_ofileflags[i] = 0;				if (i > fdp->fd_lastfile)					fdp->fd_lastfile = i;				if (want <= fdp->fd_freefile)					fdp->fd_freefile = i;				*result = i;				return (0);			}		}		/*		 * No space in current array.  Expand?		 */#ifdef PROM		return (EMFILE);#else		if (fdp->fd_nfiles >= lim)			return (EMFILE);		if (fdp->fd_nfiles < NDEXTENT)			nfiles = NDEXTENT;		else			nfiles = 2 * fdp->fd_nfiles;		MALLOC(newofile, struct file **, nfiles * OFILESIZE,		    M_FILEDESC, M_WAITOK);		newofileflags = (char *) &newofile[nfiles];		/*		 * Copy the existing ofile and ofileflags arrays		 * and zero the new portion of each array.		 */		bcopy(fdp->fd_ofiles, newofile,			(i = sizeof(struct file *) * fdp->fd_nfiles));		bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i);		bcopy(fdp->fd_ofileflags, newofileflags,			(i = sizeof(char) * fdp->fd_nfiles));		bzero(newofileflags + i, nfiles * sizeof(char) - i);		if (fdp->fd_nfiles > NDFILE)			FREE(fdp->fd_ofiles, M_FILEDESC);		fdp->fd_ofiles = newofile;		fdp->fd_ofileflags = newofileflags;		fdp->fd_nfiles = nfiles;		fdexpand++;#endif	}}/* * Check to see whether n user file descriptors * are available to the process p. */fdavail(p, n)	struct proc *p;	register int n;{	register struct filedesc *fdp = p->p_fd;	register struct file **fpp;	register int i;#ifdef PROM	if ((i = NDFILE - fdp->fd_nfiles) > 0 &&	    (n -= i) <= 0)		return (1);#else	if ((i = p->p_rlimit[RLIMIT_OFILE].rlim_cur - fdp->fd_nfiles) > 0 &&	    (n -= i) <= 0)		return (1);#endif	fpp = &fdp->fd_ofiles[fdp->fd_freefile];	for (i = fdp->fd_nfiles - fdp->fd_freefile; --i >= 0; fpp++)		if (*fpp == NULL && --n <= 0)			return (1);	return (0);}/* * Create a new open file structure and allocate * a file decriptor for the process that refers to it. */falloc(p, resultfp, resultfd)	register struct proc *p;	struct file **resultfp;	int *resultfd;{	register struct file *fp, *fq, **fpp;	int error, i;	if (error = fdalloc(p, 0, &i))		return (error);	if (nfiles >= maxfiles) {		tablefull("file");		return (ENFILE);	}	/*	 * Allocate a new file descriptor.	 * If the process has file descriptor zero open, add to the list	 * of open files at that point, otherwise put it at the front of	 * the list of open files.	 */	nfiles++;	MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK);	if (fq = p->p_fd->fd_ofiles[0])		fpp = &fq->f_filef;	else		fpp = &filehead;	p->p_fd->fd_ofiles[i] = fp;	if (fq = *fpp)		fq->f_fileb = &fp->f_filef;	fp->f_filef = fq;	fp->f_fileb = fpp;	*fpp = fp;	fp->f_count = 1;	fp->f_msgcount = 0;	fp->f_offset = 0;	fp->f_cred = p->p_ucred;	crhold(fp->f_cred);	if (resultfp)		*resultfp = fp;	if (resultfd)		*resultfd = i;	return (0);}/* * Free a file descriptor. */ffree(fp)	register struct file *fp;{	register struct file *fq;	if (fq = fp->f_filef)		fq->f_fileb = fp->f_fileb;	*fp->f_fileb = fq;	crfree(fp->f_cred);#ifdef DIAGNOSTIC	fp->f_filef = NULL;	fp->f_fileb = NULL;	fp->f_count = 0;#endif	nfiles--;	FREE(fp, M_FILE);}/* * Copy a filedesc structure. */struct filedesc *fdcopy(p)	struct proc *p;{	register struct filedesc *newfdp, *fdp = p->p_fd;	register struct file **fpp;	register int i;	MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0),	    M_FILEDESC, M_WAITOK);	bcopy(fdp, newfdp, sizeof(struct filedesc));#ifndef PROM	VREF(newfdp->fd_cdir);	if (newfdp->fd_rdir)		VREF(newfdp->fd_rdir);#endif	newfdp->fd_refcnt = 1;	/*	 * If the number of open files fits in the internal arrays	 * of the open file structure, use them, otherwise allocate	 * additional memory for the number of descriptors currently	 * in use.	 */	if (newfdp->fd_lastfile < NDFILE) {		newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;		newfdp->fd_ofileflags =		    ((struct filedesc0 *) newfdp)->fd_dfileflags;		i = NDFILE;	} else {#ifdef PROM	    	panic ("fdcopy");#else		/*		 * Compute the smallest multiple of NDEXTENT needed		 * for the file descriptors currently in use,		 * allowing the table to shrink.		 */		i = newfdp->fd_nfiles;		while (i > 2 * NDEXTENT && i >= newfdp->fd_lastfile * 2)			i /= 2;		MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE,		    M_FILEDESC, M_WAITOK);		newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];#endif	}	newfdp->fd_nfiles = i;	bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **));	bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));	fpp = newfdp->fd_ofiles;	for (i = newfdp->fd_lastfile; i-- >= 0; fpp++)		if (*fpp != NULL)			(*fpp)->f_count++;	return (newfdp);}/* * Release a filedesc structure. */voidfdfree(p)	struct proc *p;{	register struct filedesc *fdp = p->p_fd;	struct file **fpp;	register int i;	if (--fdp->fd_refcnt > 0)		return;	fpp = fdp->fd_ofiles;	for (i = fdp->fd_lastfile; i-- >= 0; fpp++)		if (*fpp)			(void) closef(*fpp, p);	if (fdp->fd_nfiles > NDFILE)		FREE(fdp->fd_ofiles, M_FILEDESC);#ifndef PROM	vrele(fdp->fd_cdir);	if (fdp->fd_rdir)		vrele(fdp->fd_rdir);#endif	FREE(fdp, M_FILEDESC);}/* * Internal form of close. * Decrement reference count on file structure. */closef(fp, p)	register struct file *fp;	register struct proc *p;{	struct vnode *vp;	struct flock lf;	int error;	if (fp == NULL)		return (0);#ifndef PROM	/*	 * POSIX record locking dictates that any close releases ALL	 * locks owned by this process.  This is handled by setting	 * a flag in the unlock to free ONLY locks obeying POSIX	 * semantics, and not to free BSD-style file locks.	 */	if ((p->p_flag & SADVLCK) && fp->f_type == DTYPE_VNODE) {		lf.l_whence = SEEK_SET;		lf.l_start = 0;		lf.l_len = 0;		lf.l_type = F_UNLCK;		vp = (struct vnode *)fp->f_data;		(void) VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_POSIX);	}#endif	if (--fp->f_count > 0)		return (0);	if (fp->f_count < 0)		panic("closef: count < 0");#ifndef PROM	if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {		lf.l_whence = SEEK_SET;		lf.l_start = 0;		lf.l_len = 0;		lf.l_type = F_UNLCK;		vp = (struct vnode *)fp->f_data;		(void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);	}#endif	error = (*fp->f_ops->fo_close)(fp, p);	ffree(fp);	return (error);}#ifndef PROM/* * Apply an advisory lock on a file descriptor. * * Just attempt to get a record lock of the requested type on * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0). *//* ARGSUSED */flock(p, uap, retval)	struct proc *p;	register struct args {		int	fd;		int	how;	} *uap;	int *retval;{	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	struct vnode *vp;	struct flock lf;	int error;	if ((unsigned)uap->fd >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)		return (EBADF);	if (fp->f_type != DTYPE_VNODE)		return (EOPNOTSUPP);	vp = (struct vnode *)fp->f_data;	lf.l_whence = SEEK_SET;	lf.l_start = 0;	lf.l_len = 0;	if (uap->how & LOCK_UN) {		lf.l_type = F_UNLCK;		fp->f_flag &= ~FHASLOCK;		return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK));	}	if (uap->how & LOCK_EX)		lf.l_type = F_WRLCK;	else if (uap->how & LOCK_SH)		lf.l_type = F_RDLCK;	else		return (EBADF);	fp->f_flag |= FHASLOCK;	if (uap->how & LOCK_NB)		return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));	return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));}/* * File Descriptor pseudo-device driver (/dev/fd/). * * Opening minor device N dup()s the file (if any) connected to file * descriptor N belonging to the calling process.  Note that this driver * consists of only the ``open()'' routine, because all subsequent * references to this file will be direct to the other driver. *//* ARGSUSED */fdopen(dev, mode, type)	dev_t dev;	int mode, type;{	/*	 * XXX Kludge: set curproc->p_dupfd to contain the value of the	 * the file descriptor being sought for duplication. The error 	 * return ensures that the vnode for this device will be released	 * by vn_open. Open will detect this special error and take the	 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN	 * will simply report the error.	 */	curproc->p_dupfd = minor(dev);		/* XXX */	return (ENODEV);}/* * Duplicate the specified descriptor to a free descriptor. */dupfdopen(fdp, indx, dfd, mode)	register struct filedesc *fdp;	register int indx, dfd;	int mode;{	register struct file *wfp;	struct file *fp;		/*	 * If the to-be-dup'd fd number is greater than the allowed number	 * of file descriptors, or the fd to be dup'd has already been	 * closed, reject.  Note, check for new == old is necessary as	 * falloc could allocate an already closed to-be-dup'd descriptor	 * as the new descriptor.	 */	fp = fdp->fd_ofiles[indx];	if ((u_int)dfd >= fdp->fd_nfiles ||	    (wfp = fdp->fd_ofiles[dfd]) == NULL || fp == wfp)		return (EBADF);	/*	 * Check that the mode the file is being opened for is a subset 	 * of the mode of the existing descriptor.	 */	if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)		return (EACCES);	fdp->fd_ofiles[indx] = wfp;	fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];	wfp->f_count++;	if (indx > fdp->fd_lastfile)		fdp->fd_lastfile = indx;	return (0);}#endif /* !PROM */

⌨️ 快捷键说明

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