linux系统编程笔记:pwd的一个实现分析

这篇博客探讨了Linux文件系统的结构,并详细分析了如何实现`pwd`命令。通过理解文件系统的目录树结构和节点表示,作者阐述了获取节点号、确定文件名以及使用递归打印路径的步骤。主要涉及`get_inode`函数用于获取节点号,以及如何根据`..`和`.`来切换和打印目录路径。
摘要由CSDN通过智能技术生成

先上一个linux文件系统的结构示意图

 这个图说的是系统的文件是通过类似树这种数据结构来实现的。目录和文件是一个个的node,有各自的节点号,和一些基本信息(结构体方式存储),放在横条的白色部分。然后文件里面的数据是存放在后面的数据块。数据块不一定是连续的,由节点通过指针找到数据块的地址。

就好比上图里面最上面一层目录包括y、a、c三个文件(夹),这就是一个根节点。每个节点的“."代表他自身,”.."这个代表他的父亲。所以我们在linux命令中cd . . 就是进入上一层的意思.,而执行指令  ./xxx  ,就代表在当前目录下执行某个文件。

a 前面的数字277代表a在277这个位置 ,而下面图中277旁边的点  “."就代表a自身 ,其他的点也是一样。

那么要实现pwd命令的功能,就分这么几步:

一、获取节点号

ino_t get_inode(char *fname){
	struct stat info;
	if(stat(fname, &info) == -1){
		fprintf(stderr, "Cannot stat ");
		perror(fname);
		exit(1);
	}
	return info.st_ino;
}

这段代码中ino_t 指的是类似520,277这种数字的格式,是节点号类型 ,类似int,可以强转。

get_inode这个函数就是传入一个文件(目录)名称,返回他的节点号。函数的实现是通过系统提供的stat结构体,里面包含了st_ino成员,可以提供这个信息。

获取文件名(不是当前文件名fname,而如果是上一层以上,就是未知的,因此要给出获取方法):

void inum_to_name(ino_t inode_to_find, char * namebuf, int buflen){
	DIR * dir_ptr;
	struct dirent * direntp;
	dir_ptr = opendir(".");
	if(dir_ptr == NULL){
		perror(".");
		exit(1);
	}
	while((direntp = readdir(dir_ptr))!=NULL)
		if(direntp->d_ino == inode_to_find){
			strncpy(namebuf, direntp->d_name, buflen);
			namebuf[buflen - 1 ] = '\0';
			closedir(dir_ptr);
			return;
		}
	fprintf(stderr, "error looking for inum %d\n", (int)inode_to_find);
	exit(1);
}

实现并不复杂,是通过目录结构体dirent获取的。

三、然后是打印路径

void printpathto(ino_t this_inode){
	ino_t my_inode;
	char its_name[BUFSIZ];
	if( get_inode("..") != this_inode ){
		chdir("..");  /* up one dir */
		inum_to_name(this_inode, its_name, BUFSIZ);   /* get its name*/
		my_inode = get_inode(".");   /* print head */
		printpathto(my_inode);    	/* recursively */
		printf("/%s", its_name);  /* now print */
	}
}

这里用到了递归思想。有点像前面打印二进制格式数字的方法。C Primer Plus 15 章 编程题2 打印二进制格式字符串的两种方法_自觉的数字公民杨某某的博客-CSDN博客就是说,如果当前文件夹的上一层 chdir(".."),是不一样的节点的话get_inode("..") != this_inode,那么就调用自身。否则就打印(从根节点开始打印)

四、main函数部分:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


ino_t get_inode(char *);
void printpathto(ino_t);
void inum_to_name(ino_t, char * , int);

int main(){
	printpathto(get_inode(".")); 	/* print path to here */
	putchar('\n');
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值