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

📄 kern_descrip.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* * Allocate a file descriptor for the process. */int fdexpand;intfdalloc(p, want, result)	struct proc *p;	int want;	int *result;{	register struct filedesc *fdp = p->p_fd;	register int i; 	int lim;#ifndef PMON	int last;	int nfiles;	struct file **newofile;	char *newofileflags;#endif	/*	 * Search for a free descriptor starting at the higher	 * of want or fd_freefile.  If that fails, consider	 * expanding the ofile array.	 */#ifdef NOTUSED_BY_PMON	lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);#else	lim = maxfiles;#endif#ifndef PMON	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) {				fd_used(fdp, i);				if (want <= fdp->fd_freefile)					fdp->fd_freefile = i;				*result = i;				return (0);			}		}		/*		 * No space in current array.  Expand?		 */		if (fdp->fd_nfiles >= lim)			return (EMFILE);		if (fdp->fd_nfiles < NDEXTENT)			nfiles = NDEXTENT;		else			nfiles = 2 * fdp->fd_nfiles;		nfiles = min(lim, 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++;	}#else	i = open("/dev/socket", 0, 0);	if (i > 0) {	   fd_used(fdp, i);	   *result = i;	   return (0);	}	return (EMFILE);#endif}/* * Check to see whether n user file descriptors * are available to the process p. */intfdavail(p, n)	struct proc *p;	register int n;{	register struct filedesc *fdp = p->p_fd;	register struct file **fpp;	register int i, lim;#ifdef NOTUSED_BY_PMON	lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);#else	lim = NDFILE;#endif	if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)		return (1);	fpp = &fdp->fd_ofiles[fdp->fd_freefile];	for (i = min(lim, 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. */intfalloc(p, resultfp, resultfd)	register struct proc *p;	struct file **resultfp;	int *resultfd;{	register struct file *fp, *fq;	int error, i;	if ((error = fdalloc(p, 0, &i)) != 0)		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);	bzero(fp, sizeof(struct file));	if ((fq = p->p_fd->fd_ofiles[0]) != NULL) {		LIST_INSERT_AFTER(fq, fp, f_list);	} else {		LIST_INSERT_HEAD(&filehead, fp, f_list);	}	p->p_fd->fd_ofiles[i] = fp;	fp->f_count = 1;	fp->f_cred = p->p_ucred;	crhold(fp->f_cred);	if (resultfp)		*resultfp = fp;	if (resultfd)		*resultfd = i;	return (0);}/* * Free a file descriptor. */voidffree(fp)	register struct file *fp;{	LIST_REMOVE(fp, f_list);	crfree(fp->f_cred);#ifdef DIAGNOSTIC	fp->f_count = 0;#endif	nfiles--;	FREE(fp, M_FILE);}/* * Build a new filedesc structure. */struct filedesc *fdinit(p)	struct proc *p;{	register struct filedesc0 *newfdp;	register struct filedesc *fdp = p->p_fd;	extern int cmask;	MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),	    M_FILEDESC, M_WAITOK);	bzero(newfdp, sizeof(struct filedesc0));	newfdp->fd_fd.fd_cdir = fdp->fd_cdir;#ifndef PMON	VREF(newfdp->fd_fd.fd_cdir);#endif	newfdp->fd_fd.fd_rdir = fdp->fd_rdir;#ifndef PMON	if (newfdp->fd_fd.fd_rdir)		VREF(newfdp->fd_fd.fd_rdir);#endif	/* Create the file descriptor table. */	newfdp->fd_fd.fd_refcnt = 1;	newfdp->fd_fd.fd_cmask = cmask;	newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;	newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;	newfdp->fd_fd.fd_nfiles = NDFILE;	newfdp->fd_fd.fd_freefile = 0;	newfdp->fd_fd.fd_lastfile = 0;	return (&newfdp->fd_fd);}/* * Share a filedesc structure. */struct filedesc *fdshare(p)	struct proc *p;{	p->p_fd->fd_refcnt++;	return (p->p_fd);}/* * 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 PMON	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 {		/*		 * 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];	}	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; i--, fpp++)		if (*fpp != NULL) {			/*			 * XXX Gruesome hack. If count gets too high, fail			 * to copy an fd, since fdcopy()'s callers do not			 * permit it to indicate failure yet.			 */			if ((*fpp)->f_count == LONG_MAX-2)				*fpp = NULL;			else				(*fpp)->f_count++;		}	return (newfdp);}/* * Release a filedesc structure. */voidfdfree(p)	struct proc *p;{	register struct filedesc *fdp = p->p_fd;	register struct file **fpp, *fp;	register int i;	if (--fdp->fd_refcnt > 0)		return;	fpp = fdp->fd_ofiles;	for (i = fdp->fd_lastfile; i >= 0; i--, fpp++) {		fp = *fpp;		if (fp != NULL) {			*fpp = NULL;			(void) closef(fp, p);		}	}	p->p_fd = NULL;	if (fdp->fd_nfiles > NDFILE)		FREE(fdp->fd_ofiles, M_FILEDESC);#ifndef PMON	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. * Note: p may be NULL when closing a file * that was being passed in a message. */intclosef(fp, p)	register struct file *fp;	register struct proc *p;{#ifndef PMON	struct vnode *vp;	struct flock lf;#endif	int error;	if (fp == NULL)		return (0);	/*	 * 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 the descriptor was in a message, POSIX-style locks	 * aren't passed with the descriptor.	 */#ifndef PMON	if (p && (p->p_flag & P_ADVLOCK) && 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 PMON	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	if (fp->f_ops)		error = (*fp->f_ops->fo_close)(fp, p);	else		error = 0;	ffree(fp);	return (error);}#ifdef NOTUSED_BY_PMON/* * 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 */intsys_flock(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_flock_args /* {		syscallarg(int) fd;		syscallarg(int) how;	} */ *uap = v;	int fd = SCARG(uap, fd);	int how = SCARG(uap, how);	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	struct vnode *vp;	struct flock lf;	if ((u_int)fd >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[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 (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 (how & LOCK_EX)		lf.l_type = F_WRLCK;	else if (how & LOCK_SH)		lf.l_type = F_RDLCK;	else		return (EINVAL);	fp->f_flag |= FHASLOCK;	if (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 */intfiledescopen(dev, mode, type, p)	dev_t dev;	int mode, type;	struct proc *p;{	/*	 * 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.	 */	p->p_dupfd = minor(dev);	return (ENODEV);}/* * Duplicate the specified descriptor to a free descriptor. */intdupfdopen(fdp, indx, dfd, mode, error)	register struct filedesc *fdp;	register int indx, dfd;	int mode;	int error;{	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);	/*	 * There are two cases of interest here.	 *	 * For ENODEV simply dup (dfd) to file descriptor	 * (indx) and return.	 *	 * For ENXIO steal away the file structure from (dfd) and	 * store it in (indx).  (dfd) is effectively closed by	 * this operation.	 *	 * Any other error code is just returned.	 */	switch (error) {	case ENODEV:		/*		 * 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);		if (wfp->f_count == LONG_MAX-2)			return (EDEADLK);		fdp->fd_ofiles[indx] = wfp;		fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];		wfp->f_count++;		fd_used(fdp, indx);		return (0);	case ENXIO:		/*		 * Steal away the file pointer from dfd, and stuff it into indx.		 */		fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];		fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];		fdp->fd_ofiles[dfd] = NULL;		fdp->fd_ofileflags[dfd] = 0;		/*		 * Complete the clean up of the filedesc structure by		 * recomputing the various hints.		 */		fd_used(fdp, indx);		fd_unused(fdp, dfd);		return (0);	default:		return (error);	}	/* NOTREACHED */}/* * Close any files on exec? */voidfdcloseexec(p)	struct proc *p;{	register struct filedesc *fdp = p->p_fd;	register int fd;	for (fd = 0; fd <= fdp->fd_lastfile; fd++)		if (fdp->fd_ofileflags[fd] & UF_EXCLOSE)			(void) fdrelease(p, fd);}#endif /* NOTUSED_BY_PMON */

⌨️ 快捷键说明

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