Linux模拟实现pwd,C语言实现linux pwd命令

C语言实现linux pwd命令

linux的文件格式

在linux文件系统中,文件=N(N>=1)个iNode和M(M>=1)个数据块

数据块存放文件的内容数据,数据块的数目随文件内容的大小而定。

iNode称为信息节点,与文件一一对应

作用:1.存储与文件相关的属性信息,如修改时间、所有人、文件类型和文件长度。不包含文件名

2.存储指向文件内容数据块的指针信息。

在一个文件系统中,一个iNode代表一个文件,用一个整数值inode_number唯一标志,通过其可以找到对应的inode

可以编程获取一个文件的iNode,从而得到它的inode_number

在linux系统中,文件系统通过目录包含子目录及文件的方式,组织成一个树状结构

目录在linux中也是一种文件,其文件内容是一个列表,每个列表项记录"inode_number + filename"

因此,目录a包含b文件,实现层面上就是目录a的内容列表里有一个关于b文件的列表项,即b的inode_number + filename

可以编程获取一个目录文件的内容列表,根据inode_number找到对应的filename

有两个特殊的文件名 .-目录自身、..-父目录

如果..和.的inode_number相同,那么说明已经到达根目录

pwd的实现如下:

1.从当前目录开始,判断是否已经到达根目录

2.若已经到达根目录则结束,并将字符串数组中的内容循环打印,如果一开始就在根目录,则输出“/”

3.若没有到达根目录,那么记录当前目录的inode_number,跳到父目录,找到记录的inode_number对应的文件名,存储到字符串数组中

需要实现的子模块:

1.搜索目录文件,根据inode_number获取对应的filename

2.搜索目录文件,根据filename获取对应的inode_number(用于获取当前目录.的inode_number

程序:

子模块:1.根据inode_number找到对应的filename

char *get_filename_byino(ino_t ino) {

DIR *dp = NULL;

struct dirent *dptr = NULL;

char *filename = NULL;

//打开当前目录文件.并将句柄传给dp

if ((dp = opendir(".")) == NULL) {

fprintf(stderr, "Cannot open Current Directory\n");

exit(-1);

} else {

//用dptr逐条读取dp的目录项,找到指定inode_number对应的filename

while ((dptr = dirread(dp)) != NULL) {

if (dptr->d_ino == ino) {

filename = strdup(dptr->d_name);

break;

}

}

closedir(dp);

}

return filename;

}

2.根据filename找到对应的inode_number

ino_t get_number_byname(char *filename) {

struct stat file_stat;

if (stat(filename, &file_stat) != 0) {

perror("stat");

exit(-1);

}

return file_stat.st_ino;

}

函数:

#include

int stat(const char *restrict pathname, struct stat *restrict buf);

返回一个结构,里面包含文件的全部属性

按照

成功返回0,失败返回-1

struct stat {

dev_t st_dev; //文件所在设备ID

ino_t st_ino; //inode编号

mode_t st_mode; //保护模式-文件访问权限

nlink_t st_nlink; //硬链接个数

uid_t st_uid; //所有者用户id

gid_t st_git; //所有者组id

dev_t st_rdev; //设备id-设备文件的设备id

off_t ** st_size; //总体尺寸(in bytes)

blksize_t st_blksize; //文件系统I/O块大小

blkcnt_t st_blocks; //已分配512B块的个数

time_t st_atime; //上次访问的时间

time_t st_mtime; //上次更新的时间

time_t st_ctime; //上次状态更改的时间

};

DIR结构体

struct _dirstream {

void *__fd;

char *__data;

int __entry_data;

char *__ptr;

int __entry_ptr;

size_t __allocation;

size_t __size;

__libc_lock_define (, __lock)

};

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 [NAMX_MAX + 1]; //文件名

typedef struct __dirstream DIR;

DIR *opendir(const char *pathname); 打开文件目录,返回指向DIR结构体的指针

struct dirent *readdir(DIR *dp);

DIR指向目录,dirent指向目录中的文件项,获取文件名d_name和索引节点d_ino

int closedir(DIR *dp);

主函数:

int main(int argc, char *argv[]) {

char *dir_stack[MAX_DIR_DEPTH];

unsigned current_depth = 0;

for (;;) {

ino_t current_ino = get_number_byname(".");

ino_t parent_ino = get_number_byname("..");

if (current_ino == parent_ino) {

break;

}

chdir("..");

dir_stack[current_depth++] = get_filename_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>= 0; i--) {

fprintf(stdout, "/%s", dir_stack[i]);

}

fprintf(stdout, "%s\n", current_depth == 0? "/":"");

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值