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

📄 gfs_descrip.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)gfs_descrip.c	4.9	(ULTRIX)	5/2/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1988 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ * *			Modification History * *	prs 4/2/91 *	The F_GETLK request to fcntl() should always return the blocking * 	lock description relative to the beginning of the file if process *	is running in POSIX mode. * *	prs 2/28/91 *	Added support for a configurable number of open *	file descriptors. * *	prs 1/21/91 *	f_data is now controlled with lk_file instead of per file *	table entry lock. This is for vhangup(). * *	scott 03/29/90 *      add check on fp->f_data before fetching mode and number * *	prs 11/14/89 *	Fixed EBADF detection within locking code of fcntl(). * *	scott 10/16/89 *      fix use of gnode dev # for audit * *	scott 8/24/89 *	moved closef() in close(). * *	condylis 6/23/89 *	Removed references to unp_gc(). * *	prs 06/14/89 *	Locked gnode during call to sfs close routine in closef(). * *	Scott 06/09/89 *	Add audit support * *      McMenemy 05/04/89 *      Add internal_dup2 call. * *	prs 03/21/89 *	Added lockinit of LK_ACCT in finit() * *	Condylis 09/12/88 *	Made SMP changes in flock() * *	Fred Glover, 8/29/88 *	add POSIX check for fcntl locking with F_GETFL; *	change error code returned for file which does not support locking; *	fix return from rewhence function for unimplemented GGETVAL function. * * 	Paul Shaughnessy, 8/22/88 *	Cleaned up F_SETFL fcntl() requests. * *	prs for chet	, 8/15/88 *	Don't call the close routine pointed to in the file ops *	structure if f_data is NULL in closef(). * *	prs - 7/12/88 *	Added SMP file table entry locks around calls to dupit. * *	Paul Shaughnessy, 7/11/88 *	Added fifo support to fsetown() and fgetown(). * *	Fred Glover	6/10/88 *	Modify error return mapping from Sys-V locking (via fcntl). *	Currently, EWOULDBLOCK and EDEADLK are the same errno.  Thus *	modify check in fcntl under locking commands: it is unnecessary  *	to map EWOULDBLOCK into a Sys-V errno, and in fact an error to  *	do so, since that would also remap EDEADLK. * *	Paul Shaughnessy, 4/27/88 *	Changed closef to handle closing a file pointer that was *	"divorced" from its gnode via vhangup(). * *	Paul Shaughnessy, 2/10/88 *	Modified to handle the new fifo code. * *	Fred Glover	1/26/88 *	Modify fcntl lock routines to support kernel and daemon based *	Sys-V style locking through the modified GRLOCK macro. * *	Joe Amato, 8/28/87 *	closef() returns err from the file systems. *	close() sets u.u_error from closef(). * *	Larry Palmer 	8/25/87 *	Made socket fsetown/fgetown set the pgrp as a positive *	value. This mathces how the socket opt does it. * * 	Paul Shaughnessy, 10/02/86 * 005- Added code to clear the close_on_exec bit when the F_DUPFD *	command is specified with the fcntl system call. * *	Paul Shaughnessy, 12/23/85 * 004- Added commands to fcntl system calls to turn on/off * 	the syncronous write option to a file. * * 11 Nov 85 -- depp *	Removed all conditional compiles for System V IPC. * *	Stephen Reilly, 9/09/85 * 002-	Modified to handle the new lockf code.				 * *	Stephen Reilly,	2/19/85 * 001- Process group or process ID was not stored correctly into the *	socket structure. * * 	Larry Cohen, 4/4/85 * 002- Changes for block in use capability. *	Also changed calls to getf to GETF macro * * 15 Mar 85 -- funding *	Added named pipe support (re. System V named pipes) * * 	Larry Cohen, 4/13/85 *	call ioctl FIOCINUSE when closing inuse desriptor * * 05-May-85 - Larry Cohen *	keep track of the highest number file descriptor opened * * I moved a line around as part of the inode count going negative * Rich * *	kern_descrip.c	6.2	83/09/25 * ***********************************************************************/#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/kernel.h"#include "../h/gnode.h"#include "../h/proc.h"#include "../h/conf.h"#include "../h/file.h"#include "../h/socket.h"#include "../h/socketvar.h"#include "../h/mount.h"#include "../h/stat.h"#include "../h/ioctl.h"#include "../h/flock.h"#include "../h/exec.h"#include "../h/kmalloc.h"#ifdef KLMDEBUGextern int klm_debug;#endif KLMDEBUG/* * Descriptor management. *//* * TODO: *	eliminate u.u_error side effects *//* * Private routine forward declarations. */int      alloc_fd_slots();extern int max_nofile;/* * Ensure that descriptor slot n has been allocated, returning -1 if * unable to do so and 0 otherwise.  Expressed as a macro to make it * cheap enough to call within loops iterating over all descriptors. * The predicate part arranges that the function to allocate descriptor * slots in the range [NOFILE_IN_U .. max_nofile] is called only when * necessary. */#define       enable_fd_slot(n) \        (((n) < (NOFILE_IN_U + u.u_of_count)) ? \                0 : alloc_fd_slots((n)))struct lock_t lk_file;/* * System calls on descriptors. */getdtablesize(){	u.u_r.r_val1 = max_nofile;}getdopt(){}setdopt(){}dup(){	register struct a {		int	i;	} *uap = (struct a *) u.u_ap;	register struct file *fp;	register int j;	if (uap->i &~ 077) { uap->i &= 077; dup2(); return; }	/* XXX */	GETF(fp, uap->i);	j = ufalloc(0);	if (j < 0)		return;	smp_lock(&lk_file, LK_RETRY);	dupit(j, fp, U_POFILE(uap->i));	smp_unlock(&lk_file);}dup2(){	register struct a {		int	i, j;	} *uap = (struct a *) u.u_ap;	internal_dup2(uap->i, uap->j);}internal_dup2(old, new)        int old;        int new;{	register struct file *fp;	register struct file *fp2;	register struct gnode *gp;	GETF(fp, old);	if (new < 0 || new >= max_nofile) {		u.u_error = EBADF;		return;	}	u.u_r.r_val1 = new;	if (old == new)		return;	/* audit info */	if ( audswitch ) {		if ( gp = (struct gnode *)fp->f_data ) {			u.u_gno_dev[0] = (gp->g_mode & GFMT) == GFCHR ? gp->g_rdev : gp->g_dev;			u.u_gno_num[0] = gp->g_number;			u.u_gno_indx = 1;		}	}	if (enable_fd_slot(new))		goto out;	if (U_OFILE(new)) {		/* Release all System-V style record locks, if any */		(void)gno_lockrelease (U_OFILE(new)); /* error? */		/*		 * It's a no-op, why call it?		 *		 * if (U_POFILE(new) & UF_MAPPED)		 *	munmapfd(new);		 */			fp2 = U_OFILE(new); 		U_OFILE_SET(new, NULL);		U_POFILE_SET(new, 0);		closef(fp2);		if (u.u_error)			goto out;	}	if (new > u.u_omax)  /* track largest file pointer number */		u.u_omax = new;	smp_lock(&lk_file, LK_RETRY);	dupit(new, fp, U_POFILE(old));	smp_unlock(&lk_file);out:        AUDIT_CALL ( u.u_event, u.u_error, u.u_r.r_val1, AUD_HDR|AUD_PRM|AUD_RES, (int *)0, 0 );}dupit(fd, fp, flags)	register int fd;	register struct file *fp;	register int flags;{	U_OFILE_SET(fd, fp);#ifdef notdef	flags &= ~(UF_INUSE); /* remove INUSE reference to inode   *002*/ #endif	U_POFILE_SET(fd, flags);	fp->f_count++;}/* * The file control system call. */fcntl(){	register struct file *fp;	register struct a {		int	fdes;		int	cmd;		int	arg;	} *uap;	register int i;	struct flock bf;	register struct gnode *gp;		/* 004 */	int oldwhence;		/* whence of request */	uap = (struct a *)u.u_ap;	GETF(fp, uap->fdes);	smp_lock(&fp->f_lk, LK_RETRY);	/* 004 - Fill gnode structure */	gp = (struct gnode *)fp->f_data;	switch(uap->cmd) {	case F_DUPFD:		i = uap->arg;		if (i < 0 || i >= max_nofile) {			u.u_error = EINVAL;			break;		}		if ((i = ufalloc(i)) >= 0) {			smp_lock(&lk_file, LK_RETRY);			dupit(i, fp, U_POFILE(uap->fdes) & ~UF_EXCLOSE);			smp_unlock(&lk_file);		}		break;	case F_GETFD:		u.u_r.r_val1 = U_POFILE(uap->fdes) & UF_EXCLOSE;		break;	case F_SETFD:		U_POFILE_SET(uap->fdes, (U_POFILE(uap->fdes) & ~UF_EXCLOSE) |			     (uap->arg & UF_EXCLOSE));		break;	case F_GETFL:		u.u_r.r_val1 = fp->f_flag+FOPEN;		break;	case F_SETFL:		/*		 * Clear user-settable flags		 */		fp->f_flag &= ~FCNTLONLYSET;		/*		 * Now, only and in the flags that a user can set		 * with this request.		 */		fp->f_flag |= ((uap->arg-FOPEN) & FCNTLONLYSET);		/*		 * Setting FNDELAY may need a call to a driver, handle		 * it seperatly.		 */		u.u_error = fset(fp, FNDELAY, fp->f_flag & FNDELAY);		if (!u.u_error) {			u.u_error = fset(fp, FASYNC, fp->f_flag & FASYNC);			if (u.u_error)				(void) fset(fp, FNDELAY, 0);		}		break;	case F_GETOWN:		u.u_error = fgetown(fp, &u.u_r.r_val1);		break;	case F_SETOWN:		u.u_error = fsetown(fp, uap->arg);		break;	case F_GETLK:	case F_SETLK:	case F_SETLKW: 		/* Locks supported for disk inodes only	*/		if (fp->f_type != DTYPE_INODE) {			u.u_error = EINVAL;			break;		}		/*	Verify inode pointer	*/		if (fp->f_data == NULL) {			u.u_error = EFAULT;			break;		}		/* get flock structure from user space */		if (u.u_error = copyin((caddr_t)uap->arg, (caddr_t)&bf, 		   sizeof(bf))){			break;		}		/* 		 * check access permissions:		 * POSIX requires a valid type even for F_GETLK		 * requests; otherwise, F_GETLK requests may point		 * to an empty flock structure.		 */		if ((uap->cmd != F_GETLK) || 		    (u.u_procp->p_progenv == A_POSIX)) {		   switch (bf.l_type) {			case F_RDLCK:				if ((uap->cmd != F_GETLK) &&				    !(fp->f_flag & FREAD)) {					u.u_error = EBADF;				}				break;			case F_WRLCK:				if ((uap->cmd != F_GETLK) &&				    !(fp->f_flag & FWRITE)) {					u.u_error = EBADF;				}				break;			case F_UNLCK:				break;			default:				u.u_error = EINVAL;				break;		   }			/* End switch */		   if (u.u_error)	/* error encountered above */			   break;		}				/* convert offset to start of file */		oldwhence = bf.l_whence;	/* save to renormalize later */		if (u.u_error = rewhence(&bf, fp, 0)) {			break;		}		/* convert negative lengths to positive */		if (bf.l_len < 0) {			bf.l_start += bf.l_len;		/* adjust start */			bf.l_len = -(bf.l_len);		/* absolute value */		}	 		/* check for validity */		if (bf.l_start < 0) {			u.u_error = EINVAL;			break;		}		/*		 *	Now, process the request 		 */		if ((uap->cmd != F_GETLK) && (bf.l_type != F_UNLCK)) {			/* If locking is attempted, mark file locked			 * to force unlock on close.			 * Also, since the SVID specifies that the 			 * FIRST close releases all locks, mark process			 * to reduce the search overhead in 			 * gno_lockrelease().		 	 */				U_POFILE_SET(uap->fdes, U_POFILE(uap->fdes) | UF_FDLOCK);			u.u_procp->p_file |= SLKDONE;		}		/*		 * Dispatch out to specific file system to do the actual 		 * locking. Then, continue based upon the error returned.		 */		switch (u.u_error = GRLOCK (gp, &bf, uap->cmd, fp)) {			case 0:				break;		/* continue, if successful */			default:	/* some other error code */				break;		}		/* End Switch */		if (u.u_error)	/* error encountered above */			break;		/* if F_GETLK, return flock structure to user space */		if (uap->cmd == F_GETLK) {			/* 			 * per SVID and P1003.1 : change only 'l_type' 			 * field if unlocked			 */			if (bf.l_type == F_UNLCK) {				u.u_error = copyout((caddr_t)&bf.l_type,				   (caddr_t)&((struct flock*)uap->arg)->l_type,				    sizeof (bf.l_type));			} else {				/* 				 * per P1003.1 : 'l_whence' field must be				 * relative to start of file (SEEK_SET)				 */				if (u.u_procp->p_progenv != A_POSIX)					u.u_error=rewhence(&bf, fp, oldwhence);				if (!u.u_error)					u.u_error = copyout((caddr_t) &bf,				       (caddr_t) uap->arg, sizeof (bf));			}		}	/* End if F_GETLK processing */# ifdef KLMDEBUG		if (klm_debug) {			printf ("fcntl(3) ret: eno:%d cmd:%d ty:%d wh:%d st:%d ln:%d pid:%d\n",			u.u_error,uap->cmd, bf.l_type, bf.l_whence, bf.l_start,			bf.l_len, bf.l_pid);		}# endif KLMDEBUG		break;	case F_SETSYN:

⌨️ 快捷键说明

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