Linux getcwd()的實現

經過getcwd()能夠獲取當前工做目錄。node

1 #include <unistd.h>
2 
3 char *getcwd(char *cwdbuf, size_t size);

成功調用返回指向cwdbuf的指針,失敗返回NULL。編程

getcwd()的實現是《Linux/Unix系統編程手冊》的練習18.5,題目以下:函數

實現一個功能與getcwd()至關的函數。提示:要獲取當前工做目錄的名稱,可調用opendir()和readdir()來遍歷其父目錄(..)中的各個條目,查找其中與當前工做目錄具備相同i-node編號及設備號的一項。如此這般,沿着目錄樹層層拾級而上(chdir(..))並進行掃描,就能構建出完整的目錄路徑。當前目錄與當前工做目錄相同時,就結束遍歷。不管調用該函數成功與否,都應將調用者遣回其起始目錄(使用open()和fchdir()能方便地實現這一功能)學習

一、經過stat獲取文件信息,根據文件信息中的i-node編號和設備號來找到正確的目錄測試

二、運用opendir()、readdir()來獲取目錄的信息,目錄不能經過read()來獲取信息。網站

PS:tlpi_hdr.h頭文件爲《Linux/Unix系統編程手冊》的頭文件,能夠去做者的網站下載,其中的errExit()爲錯誤處理函數。。。。spa

  1 /*
  2  * =====================================================================================
  3  *
  4  *       Filename:  18.5.c
  5  *
  6  *    Description:  
  7  *
  8  *        Version:  1.0
  9  *        Created:  2014年05月11日 14時04分35秒
 10  *       Revision:  none
 11  *       Compiler:  gcc
 12  *
 13  *         Author:  alan (), alan19920626@gmail.com
 14  *   Organization:  
 15  *
 16  * =====================================================================================
 17  */
 18 
 19 #include <sys/stat.h>
 20 #include <fcntl.h>
 21 #include <dirent.h>
 22 #include <sys/types.h>
 23 #include "tlpi_hdr.h"
 24 
 25 #define BUF_MAX 4096
 26 
 27 extern int errno; 
 28 
 29 char *Getcwd(char *cwdbuf, size_t size){
 30     char path[BUF_MAX], cwd[BUF_MAX];
 31     DIR *dirp;
 32     struct dirent *dp;
 33     struct stat sb, sb_d, sb_1;
 34     dev_t dev;
 35     ino_t ino;
 36 
 37     while(1){
 38         //獲取當前目錄的文件信息
 39         if(stat(".", &sb) == -1)
 40             errExit("stat");
 41         dev = sb.st_dev;
 42         ino = sb.st_ino;
 43 
 44         //獲取父目錄的對應的目錄流和父目錄的文件信息
 45         if((dirp = opendir("..")) == NULL)
 46             errExit("opendir");
 47         if(stat("..", &sb_1) == -1)
 48             errExit("stat");
 49 
 50         //判斷當前目錄是否與父目錄相同
 51         if(sb_1.st_dev == dev && sb_1.st_ino == ino)
 52             break;
 53 
 54         errno = 0;
 55         
 56         //在父目錄對應的目錄流讀取條目
 57         while((dp = readdir(dirp)) != NULL){
 58             snprintf(path, BUF_MAX, "../%s", dp->d_name);
 59 
 60             if(stat(path, &sb_d) == -1)
 61                 errExit("stat");
 62 
 63             //獲得當前目錄對應的條目並將目錄逐漸完善
 64             if(dev == sb_d.st_dev && ino == sb_d.st_ino){
 65                 memset(cwd, 0, sizeof(cwd));
 66                 if(strcat(cwd, "/") == NULL)
 67                     errExit("strcat");
 68                 if(strcat(cwd, dp->d_name) == NULL)
 69                     errExit("strcat");
 70                 if(strcat(cwd, cwdbuf) == NULL)
 71                     errExit("strcat");
 72 
 73                 if(strncpy(cwdbuf, cwd, BUF_MAX) == NULL)
 74                     errExit("strncpy");
 75                 break;
 76             }
 77             
 78         }
 79 
 80         if(dp == NULL && errno != 0)
 81             errExit("readdir");
 82 
 83         closedir(dirp);
 84         chdir("..");      //改變當前目錄
 85     }
 86 
 87     return cwdbuf;
 88 }
 89 
 90 int main(int argc, char *argv[]){
 91     char buf[BUF_MAX];
 92     char t_buf[BUF_MAX];
 93     char *p;
 94     int fd;
 95 
 96     if((fd = open(".", O_RDONLY)) == -1)
 97         errExit("open");
 98 
 99     if(argc != 1)
100         usageErr("%s", argv[0]);
101 
102     p = Getcwd(buf, BUF_MAX);
103     if(p == NULL)
104         errExit("My getcwd");
105     printf("My getcwd: %s\n", p);
106     fchdir(fd);    //遣回最初的目錄
107 
108     p = getcwd(t_buf, BUF_MAX);
109     if(p == NULL)
110         errExit("getcwd");
111     printf("getcwd: %s\n", p);
112 
113     exit(EXIT_SUCCESS);
114 }

測試結果:指針

lancelot@debian:~/Code/tlpi$ pwd
/home/lancelot/Code/tlpi
lancelot@debian:~/Code/tlpi$ ./18.5 
My getcwd: /home/lancelot/Code/tlpi
getcwd: /home/lancelot/Code/tlpi

吐槽&收穫:原本打算慢慢經過寫學習記錄,可是以爲學習不少只是經過把一些重點寫出來和一些習題,因此打算放一放,有空再寫。重點什麼的還要慢慢總結。先把一些習題作了,順便結合以前學得系統調用和庫函數作一些實際的東西先。。。。。。一個下午作這麼一條題。。。真心弱菜,不過作出來真得很開心。。。。。還有慢慢長路要走!!!繼續努力!!!code

相關文章
相關標籤/搜索