您的位置:首页 > 运维架构 > Linux

【Unix/Linux编程实践】文件系统:编写pwd

2015-12-06 23:33 766 查看

知识点

目录是一个包含文件名与i-节点对的列表的文件。

”文件在目录中“的含义:目录中存放的只是文件在i-节点表的入口,而文件的内容则存储在数据区中。例如,“文件x在目录a中”意味着在目录a中有一个指向文件x的i-节点的链接,这个链接所附加的文件名为x。

pwd:用来显示到达当前目录的路径。

pwd的工作过程

得到“.”(当前目录)的i-节点号,称其为n(使用stat);

chdir .. (使用chdir,进入父目录);

找到i-节点号n链接的名字(存放在父目录的数据区中,使用opendir, readdir, closedir);

回到1,直到到达树的顶端(当“.”和”..”的i-节点号相同时)。

此外,为以正确的顺序打印目录名字,且方便简单,我们可以递归地打印。

pwd的一种版本

/* spwd.c: a simplified version of pwd
*
*  starts in current directory and recursively
*  climbs up to root of filesystem, prints top part
*  then prints current part
*
*  uses readdir() to get info about each thing
*
*      bug: prints an empty string if run from "/"
**/
#include    <stdio.h>
#include    <sys/types.h>
#include    <sys/stat.h>
#include    <dirent.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');              /* then add newline */
return 0;
}

void printpathto( ino_t this_inode )
/*
*  prints path leading down to an object with this inode
*  kindof recursive
*/
{
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    */
/* name of this */
}
}

void inum_to_name(ino_t inode_to_find , char *namebuf, int buflen)
/*
*  looks through current directory for a file with this inode
*  number and copies its name into namebuf
*/
{
DIR     *dir_ptr;       /* the directory */
struct dirent   *direntp;       /* each entry    */

dir_ptr = opendir( "." );
if ( dir_ptr == NULL ){
perror( "." );
exit(1);
}

/*
* search directory for a file with specified inum
*/

while ( ( direntp = readdir( dir_ptr ) ) != NULL )
if ( direntp->d_ino == inode_to_find )
{
strncpy( namebuf, direntp->d_name, buflen);
namebuf[buflen-1] = '\0';   /* just in case */
closedir( dir_ptr );
return;
}
fprintf(stderr, "error looking for inum %d\n", inode_to_find);
exit(1);
}

ino_t get_inode( char *fname )
/*
*  returns inode number of the file
*/
{
struct stat info;

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


下面我们进行测试,分别使用pwd和我们自己写的spwd打印当前目录路径:

jiange@jiange-Inspiron:~/linux/unix编程实践教程代码/CH04$ pwd
/home/jiange/linux/unix编程实践教程代码/CH04
jiange@jiange-Inspiron:~/linux/unix编程实践教程代码/CH04$ ./spwd
/jiange/linux/unix编程实践教程代码/CH04


咦,为什么不一样呢?

因为命令pwd显示达到这个计算机上整棵文件树的根,而我们写的程序只是到达所在文件系统的根而已!

我的电脑在分区的时候,/ 以及 /home 是分在不同的区中,即两者是在不同的文件系统当中的。在unix中,每个分区都有自己的文件系统树,当计算机上存在多个文件系统时,unix将这些数整合成一颗更大的树。比如我们的 / 和 /home, / 所在文件系统为根文件系统,/home所在文件系统被附件到根文件系统的/home子目录上,根文件系统中的目录/home作为指针,指向/home文件系统的根,这样子两个文件系统就联系起来了。

使用命令mount可以查看当前所装载的文件系统以及它们的装载点。

×硬链接不可以跨越文件系统,符号链接则可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: