系列文章 : [6.1810] 跟著 MIT 6.1810 學習基礎作業系統觀念
// Copy the next path element from path into name.
// Return a pointer to the element following the copied one.
// The returned path has no leading slashes,
// so the caller can check *path=='\0' to see if the name is the last one.
// If no name to remove, return 0.
//
// Examples:
// skipelem("a/bb/c", name) = "bb/c", setting name = "a"
// skipelem("///a//bb", name) = "bb", setting name = "a"
// skipelem("a", name) = "", setting name = "a"
// skipelem("", name) = skipelem("////", name) = 0
//
static char*
skipelem(char *path, char *name)
{
a/bb/c,這個 function 會抽出第一個 a,並回傳指標指向字串 bb/c
a/bb/c
b
bb/c
而不是 0!!// Look up and return the inode for a path name.
// If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes.
// Must be called inside a transaction since it calls iput().
static struct inode*
namex(char *path, int nameiparent, char *name)
{
struct inode *ip, *next;
if(*path == '/')
ip = iget(ROOTDEV, ROOTINO);
else
ip = idup(myproc()->cwd);
/ 開頭,則從根節點開始走訪 path。/ 開頭,則由當前的路徑開始走訪 path。 while((path = skipelem(path, name)) != 0){
ilock(ip);
if(ip->type != T_DIR){
iunlockput(ip);
return 0;
}
if(nameiparent && *path == '\0'){
// Stop one level early.
iunlock(ip);
return ip;
}
if((next = dirlookup(ip, name, 0)) == 0){
iunlockput(ip);
return 0;
}
iunlockput(ip);
ip = next;
}
if(nameiparent){
iput(ip);
return 0;
}
假如 nameiparent == 1,則應該要在 while 迴圈裡面就 return 了,走到這邊明顯不合理。
因路徑走訪失敗, return 0。
return ip;
}
回傳目標 struct-inode 的指標。
struct inode*
namei(char *path)
{
char name[DIRSIZ];
return namex(path, 0, name);
}
會呼叫 namex,參數 nameiparent 會設為 0,所以不會在意 name 被設為什麼值。
struct inode*
nameiparent(char *path, char *name)
{
return namex(path, 1, name);
}
會呼叫 namex,參數 nameiparent 會設為 1,所以會在意 name 被設為什麼值。