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

📄 patch.c

📁 一个简单的操作系统minix的核心代码
💻 C
📖 第 1 页 / 共 2 页
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				src/fs/path.c	 	 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

24700	/* This file contains the procedures that look up path names in the directory
24701	 * system and determine the inode number that goes with a given path name.
24702	 *
24703	 *  The entry points into this file are
24704	 *   eat_path:   the 'main' routine of the path-to-inode conversion mechanism
24705	 *   last_dir:   find the final directory on a given path
24706	 *   advance:    parse one component of a path name
24707	 *   search_dir: search a directory for a string and return its inode number
24708	 */
24709	
24710	#include "fs.h"
24711	#include <string.h>
24712	#include <minix/callnr.h>
24713	#include "buf.h"
24714	#include "file.h"
24715	#include "fproc.h"
24716	#include "inode.h"
24717	#include "super.h"
24718	
24719	PUBLIC char dot1[2] = ".";      /* used for search_dir to bypass the access */
24720	PUBLIC char dot2[3] = "..";     /* permissions for . and ..                 */
24721	
24722	FORWARD _PROTOTYPE( char *get_name, (char *old_name, char string [NAME_MAX]) );
24723	
24724	/*===========================================================================*
24725	 *                              eat_path                                     *
24726	 *===========================================================================*/
24727	PUBLIC struct inode *eat_path(path)
24728	char *path;                     /* the path name to be parsed */
24729	{
24730	/* Parse the path 'path' and put its inode in the inode table. If not possible,
24731	 * return NIL_INODE as function value and an error code in 'err_code'.
24732	 */
24733	
24734	  register struct inode *ldip, *rip;
24735	  char string[NAME_MAX];        /* hold 1 path component name here */
24736	
24737	  /* First open the path down to the final directory. */
24738	  if ( (ldip = last_dir(path, string)) == NIL_INODE)
24739	        return(NIL_INODE);      /* we couldn't open final directory */
24740	
24741	  /* The path consisting only of "/" is a special case, check for it. */
24742	  if (string[0] == '\0') return(ldip);
24743	
24744	  /* Get final component of the path. */
24745	  rip = advance(ldip, string);
24746	  put_inode(ldip);
24747	  return(rip);
24748	}
	
	
24751	/*===========================================================================*
24752	 *                              last_dir                                     *
24753	 *===========================================================================*/
24754	PUBLIC struct inode *last_dir(path, string)
24755	char *path;                     /* the path name to be parsed */
24756	char string[NAME_MAX];          /* the final component is returned here */
24757	{
24758	/* Given a path, 'path', located in the fs address space, parse it as
24759	 * far as the last directory, fetch the inode for the last directory into
24760	 * the inode table, and return a pointer to the inode.  In
24761	 * addition, return the final component of the path in 'string'.
24762	 * If the last directory can't be opened, return NIL_INODE and
24763	 * the reason for failure in 'err_code'.
24764	 */
24765	
24766	  register struct inode *rip;
24767	  register char *new_name;
24768	  register struct inode *new_ip;
24769	
24770	  /* Is the path absolute or relative?  Initialize 'rip' accordingly. */
24771	  rip = (*path == '/' ? fp->fp_rootdir : fp->fp_workdir);
24772	
24773	  /* If dir has been removed or path is empty, return ENOENT. */
24774	  if (rip->i_nlinks == 0 || *path == '\0') {
24775	        err_code = ENOENT;
24776	        return(NIL_INODE);
24777	  }
24778	
24779	  dup_inode(rip);               /* inode will be returned with put_inode */
24780	
24781	  /* Scan the path component by component. */
24782	  while (TRUE) {
24783	        /* Extract one component. */
24784	        if ( (new_name = get_name(path, string)) == (char*) 0) {
24785	                put_inode(rip); /* bad path in user space */
24786	                return(NIL_INODE);
24787	        }
24788	        if (*new_name == '\0')
24789	                if ( (rip->i_mode & I_TYPE) == I_DIRECTORY)
24790	                        return(rip);    /* normal exit */
24791	                else {
24792	                        /* last file of path prefix is not a directory */
24793	                        put_inode(rip);
24794	                        err_code = ENOTDIR;                     
24795	                        return(NIL_INODE);
24796	                }
24797	
24798	        /* There is more path.  Keep parsing. */
24799	        new_ip = advance(rip, string);
24800	        put_inode(rip);         /* rip either obsolete or irrelevant */
24801	        if (new_ip == NIL_INODE) return(NIL_INODE);
24802	
24803	        /* The call to advance() succeeded.  Fetch next component. */
24804	        path = new_name;
24805	        rip = new_ip;
24806	  }
24807	}
	
	
24810	/*===========================================================================*
24811	 *                              get_name                                     *
24812	 *===========================================================================*/
24813	PRIVATE char *get_name(old_name, string)
24814	char *old_name;                 /* path name to parse */
24815	char string[NAME_MAX];          /* component extracted from 'old_name' */
24816	{
24817	/* Given a pointer to a path name in fs space, 'old_name', copy the next
24818	 * component to 'string' and pad with zeros.  A pointer to that part of
24819	 * the name as yet unparsed is returned.  Roughly speaking,
24820	 * 'get_name' = 'old_name' - 'string'.
24821	 *
24822	 * This routine follows the standard convention that /usr/ast, /usr//ast,
24823	 * //usr///ast and /usr/ast/ are all equivalent.
24824	 */
24825	
24826	  register int c;
24827	  register char *np, *rnp;
24828	
24829	  np = string;                  /* 'np' points to current position */
24830	  rnp = old_name;               /* 'rnp' points to unparsed string */
24831	  while ( (c = *rnp) == '/') rnp++;     /* skip leading slashes */
24832	
24833	  /* Copy the unparsed path, 'old_name', to the array, 'string'. */
24834	  while ( rnp < &old_name[PATH_MAX]  &&  c != '/'   &&  c != '\0') {
24835	        if (np < &string[NAME_MAX]) *np++ = c;
24836	        c = *++rnp;             /* advance to next character */
24837	  }
24838	
24839	  /* To make /usr/ast/ equivalent to /usr/ast, skip trailing slashes. */
24840	  while (c == '/' && rnp < &old_name[PATH_MAX]) c = *++rnp;
24841	
24842	  if (np < &string[NAME_MAX]) *np = '\0';       /* Terminate string */
24843	
24844	  if (rnp >= &old_name[PATH_MAX]) {
24845	        err_code = ENAMETOOLONG;
24846	        return((char *) 0);
24847	  }
24848	  return(rnp);
24849	}
	
	
24852	/*===========================================================================*
24853	 *                              advance                                      *
24854	 *===========================================================================*/
24855	PUBLIC struct inode *advance(dirp, string)
24856	struct inode *dirp;             /* inode for directory to be searched */
24857	char string[NAME_MAX];          /* component name to look for */
24858	{
24859	/* Given a directory and a component of a path, look up the component in
24860	 * the directory, find the inode, open it, and return a pointer to its inode
24861	 * slot.  If it can't be done, return NIL_INODE.
24862	 */
24863	
24864	  register struct inode *rip;
24865	  struct inode *rip2;
24866	  register struct super_block *sp;
24867	  int r, inumb;
24868	  dev_t mnt_dev;
24869	  ino_t numb;
24870	
24871	  /* If 'string' is empty, yield same inode straight away. */
24872	  if (string[0] == '\0') return(get_inode(dirp->i_dev, (int) dirp->i_num));
24873	
24874	  /* Check for NIL_INODE. */
24875	  if (dirp == NIL_INODE) return(NIL_INODE);
24876	
24877	  /* If 'string' is not present in the directory, signal error. */
24878	  if ( (r = search_dir(dirp, string, &numb, LOOK_UP)) != OK) {
24879	        err_code = r;
24880	        return(NIL_INODE);
24881	  }
24882	
24883	  /* Don't go beyond the current root directory, unless the string is dot2. */

⌨️ 快捷键说明

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