20155227 實現mypwd
阿新 • • 發佈:2017-11-19
clu 所有 一級目錄 into type std dpt mark unistd.h 。一般情況下,一個文件只有一個
20155227 實現mypwd
1 學習pwd命令
2 研究pwd實現需要的系統調用(man -k; grep),寫出偽代碼
3 實現mypwd
4 測試mypwd
課堂學習筆記
實現mypwd
在linux 中的文件系統中,文件=N(N>=1)個inode +M(M>=1)個數據塊
。
數據塊,存放文件的內容數據,數據塊的數目根據文件內容的大小而定。
i-node稱為信息節點,作用有:
1、存儲跟文件相關的屬性信息,如修改時間、所有者、文件類型和文
2、存儲指向文件內容數據塊的指針信息。
在一個文件系統中,一個inode
代表一個文件,並使用一個整數值來標誌該inode
,稱為inode-number,該值對於一個文件系統而言是唯一的,即通過該值可以找到其對應的inode
inode
信息用來描述它。目錄,在linux中,其實也是一種文件,所以它也是由“inode+數據塊”
構成的。而其文件內容是一個列表,每一個列表項記錄“inode-number+filename"
。
因此,我們通常所說的目錄a"包含"文件b,其實現層面上的意思是,目錄a的內容列表裏有一個關於文件b的列表項,即“b的inode-number+ b的filename”
。
綜上,linux中,一個文件(包括目錄)的文件名,及文件名與inode的對應關系
,都是由包含該文件的目錄
所描述的。
其中,有兩個特殊的文件名“.” 和 “..”,“.”代表當前目錄自身,".."代表包含當前目錄的上一級目錄。
結構體stat:
struct stat { dev_t st_dev; //文件的設備編號 ino_t st_ino; //節點 mode_t st_mode; //文件的類型和存取的權限 nlink_t st_nlink; //連到該文件的硬連接數目,剛建立的文件值為1 uid_t st_uid; //用戶ID gid_t st_gid; //組ID dev_t st_rdev; //(設備類型)若此文件為設備文件,則為其設備編號 off_t st_size; //文件字節數(文件大小) unsigned long st_blksize; //塊大小(文件系統的I/O 緩沖區大小) unsigned long st_blocks; //塊數 time_t st_atime; //最後一次訪問時間 time_t st_mtime; //最後一次修改時間 time_t st_ctime; //最後一次改變時間(指屬性) };
dirent結構體:
struct dirent
{
long d_ino; //inode number 索引節點號
off_t d_off; //offset to this dirent 在目錄文件中的偏移
unsigned short d_reclen;// length of this d_name 文件名長
unsigned char d_type; //the type of d_name 文件類型
char d_name [NAME_MAX+1]; //file name (null-terminated) 文件名,最長255字符
};
DIR結構體:
struct __dirstream
{
void *__fd; // `struct hurd_fd‘ pointer for descriptor.
char *__data; // Directory block.
int __entry_data; // Entry number `__data‘ corresponds to.
char *__ptr; // Current pointer into the block.
int __entry_ptr; // Entry number `__ptr‘ corresponds to.
size_t __allocation;// Space allocated for the block.
size_t __size; // Total valid data in the block.
__libc_lock_define (, __lock) // Mutex lock for this structure.
};
typedef struct __dirstream DIR;
mypwd.c:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#define MAX_DIR_DEPTH (256)
#define TRUE 1
#define FALSE 0
ino_t get_ino_byname(char *filename)
{
struct stat file_stat;
if(0 != stat(filename, &file_stat))
{
perror("stat");
exit(-1);
}
return file_stat.st_ino;
}
char *find_name_byino(ino_t ino)
{
DIR *dp = NULL;
struct dirent *dptr = NULL;
char *filename = NULL;
if(NULL == (dp = opendir(".")))
{
fprintf(stderr, "Can not open Current Directory\n");
exit(-1);
}
else
{
while(NULL != (dptr = readdir(dp)))
{
if(dptr->d_ino == ino)
{
filename = strdup(dptr->d_name);
break;
}
}
closedir(dp);
}
return filename;
}
int main(int argc, char *argv[])
{
char *dir_stack[MAX_DIR_DEPTH];
unsigned current_depth = 0;
while(TRUE)
{
ino_t current_ino = get_ino_byname(".");
ino_t parent_ino = get_ino_byname("..");
if(current_ino == parent_ino)
break; /*兩個inode-number不一樣*/
chdir("..");
dir_stack[current_depth++] = find_name_byino(current_ino);
if(current_depth >= MAX_DIR_DEPTH) {
fprintf(stderr, "Directory tree is too deep.\n");
exit(-1);
}
}
int i = current_depth - 1;
for(i = current_depth - 1; i >= 0; i--)
{
fprintf(stdout, "/%s", dir_stack[i]);
}
fprintf(stdout, "%s\n", current_depth == 0 ? "/" : "");
return 0;
}
運行截圖
20155227 實現mypwd