2017-2018-1 20155310 《資訊安全系統設計基礎》 實作mypwd
作業要求:
1、學習pwd指令
2、研究pwd實作需要的系統調用(man -k; grep),寫出僞代碼
3、實作mypwd
4、測試mypwd
學習pwd指令
指令簡介:
該指令用來顯示目前所在的工作目錄。指令英文原義:print work directory
執行權限 :All User
指令所在路徑:/usr/bin/pwd 或 /bin/pwd
指令文法:
pwd [OPTION]...
指令參數:
參數 | 長參數 | 描述 |
---|---|---|
-L | --logical(無效) | 當目錄為連接配接路徑時,顯示連接配接路徑 |
-P | --physical(無效) | 顯示實際實體路徑,而非使用連接配接(link)路徑 |
. | --help | 顯示指令線上幫助(該參數無法使用) |
. | --version | 顯示指令版本資訊(該參數無法使用) |
使用示例:
1:檢視pwd指令的幫助資訊
[email protected] init.d]# man pwd
PWD(1) User Commands PWD(1)
NAME
pwd - print name of current/working directory
SYNOPSIS
pwd [OPTION]...
DESCRIPTION
Print the full filename of the current working directory.
-L, --logical
use PWD from environment, even if it contains symlinks
-P, --physical
avoid all symlinks
--help display this help and exit
--version
output version information and exit
NOTE: your shell may have its own version of pwd, which usually supersedes the version described here. Please refer to your shell鈥檚 documentation for details about the
options it supports.
AUTHOR
Written by Jim Meyering.
REPORTING BUGS
Report bugs to <[email protected]>.
COPYRIGHT
Copyright 漏 2006 Free Software Foundation, Inc.
This is free software. You may redistribute copies of it under the terms of the GNU General Public License <http://www.gnu.org/licenses/gpl.html>. There is NO WARRANTY, to
the extent permitted by law.
SEE ALSO
The full documentation for pwd is maintained as a Texinfo manual. If the info and pwd programs are properly installed at your site, the command
info pwd
should give you access to the complete manual.
pwd 5.97 May 2011 PWD(1)
(END)
2:顯示目前目錄所在路徑 pwd
[[email protected] networking]# pwd
/etc/sysconfig/networking
3:顯示目前目錄的實體路徑 pwd –P
[[email protected] init.d]# cd /etc/init.d
[[email protected] init.d]# pwd -P
/etc/rc.d/init.d
4: 顯示目前目錄的連接配接路徑:pwd -L
[[email protected] networking]# cd /etc/init.d
[[email protected] init.d]# pwd -L
/etc/init.d
[[email protected] init.d]# pwd
/etc/init.d
實作mypwd
代碼如下:
#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
//根據檔案名擷取檔案的inode-number
ino_t get_ino_byname(char *filename)
{
struct stat file_stat;
if(0 != stat(filename, &file_stat)) //stat()通過檔案名filename擷取檔案資訊,并儲存在buf所指的結構體stat中
{
perror("stat");
exit(-1);
}
return file_stat.st_ino;
}
//根據inode-number, 在目前目錄中查找對呀的檔案名
char *find_name_byino(ino_t ino)
{
DIR *dp = NULL;
struct dirent *dptr = NULL;
char *filename = NULL;
if(NULL == (dp = opendir("."))) //opendir()打開一個目錄,在失敗的時候傳回一個空的指針,成傳回DIR結構體
{
fprintf(stderr, "Can not open Current Directory\n");
exit(-1);
}
else
{
while(NULL != (dptr = readdir(dp))) //readdir()用來讀取目錄。傳回是dirent結構體指針
{
if(dptr->d_ino == ino)
{
filename = strdup(dptr->d_name); //strdup()将串拷貝到建立的位置處,傳回一個指針,指向為複制字元串配置設定的空間;如果配置設定空間失敗,則傳回NULL值.
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("."); //通過特殊的檔案名"."擷取當期目錄的inode-number
ino_t parent_ino = get_ino_byname(".."); //通過特殊的檔案名".."擷取目前目錄的父目錄的inode-number
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;
}
/*
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;
結構體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; //最後一次改變時間(指屬性)
}; */
運作截圖:

轉載于:https://www.cnblogs.com/m20155310/p/7860262.html