程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> unix系統編程小結(二)------文件和目錄

unix系統編程小結(二)------文件和目錄

編輯:關於C語言

一.對linux的安全機制的一點感悟         各種權限,read,write,execute,set-user-ID,set-group-ID,sticky bit,對目錄的權限,對文件的權限,用於保證系統安全的各種組合技,各種經典。比如,如果我們想unlink一個文件,就必須擁有該文件所在目錄的write與execute的權限。二.兩個小例子         1.當文件有hole時,cp命令會同時拷貝這些hole為'\0'。這裡是一個實現了拷貝時跳過文件hole的程序。ps:我用的buffer是一個字節的,效率很低,但如果用大的buffer就會使得hole被移除,使得原先分開的字符被連上。我沒想好如何解決這個問題。如果您知道,請您告訴小弟我,非常感謝![cpp] view plaincopy

  1. #include <apue.h>  
  2. #include <my_error.h>  
  3. #include <fcntl.h>  
  4.   
  5. int main()  
  6. {  
  7.     char buf[1];  
  8.     int fd,fd_to;  
  9.     int n;  
  10.     if( (fd=open("temp_in_hole",O_RDWR) )<0)  
  11.         err_sys("error open");  
  12.     if( (fd_to=open("temp_OUT_hole",O_WRONLY))<0 )  
  13.         err_sys("error open for ");  
  14.     while( (n=read(fd,buf,1))!=0 )  
  15.     {  
  16.         if(buf[0]!='\0')   
  17.             if(write(fd_to,buf,1)!=n)  
  18.                 err_sys("error write");  
  19.     }  
  20.     close(fd);  
  21.     close(fd_to);  
  22.     return 0;  
  23. }  

         2.遍歷目錄。這裡只貼出主要代碼:   ps:有一個技巧就是每遇到一個目錄時,就用chdir將該目錄設置為當前的工作目錄,可以提高程序運行的效率。
[cpp] view plaincopy
  1. static int dopath(Myfunc * func)  
  2. {  
  3.     struct stat    statbuf;  
  4.     struct dirent  *dirp;  
  5.     DIR            *dp;  
  6.     int            ret;  
  7.     char           *ptr;  
  8.   
  9.     if(lstat(fullpath,&statbuf)<0)  
  10.         return (func(fullpath,&statbuf,FTW_NS));  
  11.     if(S_ISDIR(statbuf.st_mode)==0)  
  12.         return (func(fullpath,&statbuf,FTW_F));  
  13.   
  14.     if( (ret=func(fullpath,&statbuf,FTW_D))!=0 )  
  15.         return ret;  
  16.   
  17.     ptr=fullpath+strlen(fullpath);  
  18.     *ptr++='/';  
  19.     *ptr=0;  
  20.   
  21.     if(chdir(fullpath)<0)  
  22.         err_ret("chdir for %s failed!",fullpath);  
  23.     if((dp=opendir("./"))==NULL)  
  24.         return (func(fullpath,&statbuf,FTW_DNR));  
  25.     while((dirp=readdir(dp))!=NULL)  
  26.     {  
  27.         if(strcmp(dirp->d_name,".")==0 || strcmp(dirp->d_name,"..")==0)   
  28.             continue;  
  29.         strcpy(ptr,dirp->d_name);  
  30.         if(ret=dopath(func)!=0)  
  31.             return ret;  
  32.     }  
  33.     ptr[-1]=0;  
  34.     if(closedir(dp)<0)  
  35.         err_ret("can't close directory %s",fullpath);  
  36.     if(chdir("../")<0)  
  37.         err_ret("chdir for ../ failed!");  
  38.     return ret;  
  39. }  

三.一些筆記         相關的system call很多,具體的用法我就不列出來了,只列出一些我在看書過程中的筆記(有些是摘自apue)。         1.there is no distinction to the UNIX kernel whether this data is text or binary.    2.FIFO is a type of file used for communication between processed.It's sometimes called a named pipe.         3.if we used the stat function,we would never see symbolic links.用lstat才能處理symbolic links.    4. set-user-ID:這個概念要特別注意。比如說,當一個文件被設置了set-user-ID後,而這個文件的owner是root,然後用一個非root的進程執行這個文件,那麼該文件所執行的進程也將擁有root權限。比如說passwd命令就是一個set-user-ID程序。任何用戶都可以修改密碼,但/etc/passwd只能是root才有write的權利,所以這時set-usr_ID就可以發揮作用,讓所有執行passwd的進程都可以向/etc/passwd中write。         5.whenever we want to open any type of file by name ,we must have execute permission in each directory mentioned in the name,including the current directory,if it is implied.This is why the execute permission bit for a directory is often called the search bit.這個比較好理解,對於一個目錄來說,自然不可能去執行目錄,所以目錄的可執行性就是為了執行該目錄下的文件作基礎。    6.目錄的read權限僅僅是獲得a list of all the filenames in the directory.目錄的read權限與執行權限是很不相同的。    7.we cannot create a new file in a directory unless we have write permission and execute permission in the directory.    8.To delete an existing file,we need write permission and execute permission in the directory containing the file.We do not need read permission or write permission for the file itself.以前沒有注意目錄與文件之間的這樣的權限的聯系。    9.當用gcc編譯生成一個二進制文件後,用chmod u+s來設置set-user-ID。 當再用gcc更新該二進制文件後,set-user-ID就會消失    10.read系統調用讀的內容是不會自動加上'\0'的,所以在使用printf輸出該內容的時候要手動加上'\0'    11.open(filename,O_TRunC).就可以清空文件filename    12.The i-nodes are fixed-length entries that contain most of the information about a file.Most of the information in the stat structure is obtained from the i-node.    13.對目錄做硬鏈接有可能使得文件系統出現循環,而這個循環是處理文件系統的很多工具都無法解決的。所以非常多的UNIX實現版本都不允許對目錄做硬鏈接。apue上4.16有出現循環的例子    14.We've mentioned before that to unlink a file,we must have write permission and execute permission in the directory containing the directory entry,as it is the directory entry that we will be removing.Also,we mentioned in Section 4.10(in apue)that if the sticky bit is set in this directory we must have write permission for the directory and one of the following:Own the file;Own the directory;Have superuser privileges.    15.A symbolic link is an indirect pointer to a file,unlike the hard links,which pointed directly to the i-node of the file.    16.?ln -s ../foo link_file   這裡的../foo可以是不存在的文件,然後就像絕對路徑一樣,link_file 直接指向../foo。例子:foo是一個目錄。ln -s ../foo foo/testdir 再ll  foo會顯示drwxr-xr-x 2 root root 4096 2012-12-06 22:37 ./drwxr-xr-x 3 root root 4096 2012-12-06 22:37 ../lrwxrwxrwx 1 root root    6 2012-12-06 22:37 testdir -> ../foo/    17.All the information in the i-node is stored separately from the actual contents of the file.    18.A directory is simply a file containing directory entries:filenames and associated i-node numbers.    19.?typedef的一個用法:    typedef int Func(int a,int b);  //這聲明了一個新的函數類型,Func,這種函數類型有兩個int類型的參數,返回值也是int類型 static Func  my_func1;   //my_func1的函數原型,完整的寫法是static int my_func1(int a ,int b);  在這裡使用typedef,會使得代碼更加簡潔,清晰,對代碼的可讀性有好處    20.?char *p;   *p++='0';  是將*p賦值為'0'後,p指針再加1個單位的地址                 *++p='0';  是先將p執行加一個單位的地址後,再將*p賦值為'0';   這是一個比較容易混淆和容易記錯的地方    21.char *ptr;  ptr[-1]是指是的ptr指向位置的上一個元素。    22.The current working directory is an attribute of a process .    23. If we try,using either open or creat,to create a file that alredy exists,the file's access permission bits are not changed but the files were truncated(被清空).      24.The size of a directory should never be 0,since there should always be entries for dot and dot-dot.The size of a symbolic link is the number of characters in the pathname contained in the symbolic link,and this pathname must always contain at least one character.    25.time ./pro1 計算整個pro1程序執行的時間    26.The kernel has no inherent limit on the depth of a directory tree.But many commands will fail on pathnames that exceed PATH_MAX,比如getcwd.   參考資料:apue    如果您覺得我的文章對您有幫助,請您贊一下,非常感謝!

本文出自 “Neil的博客” 博客,請務必保留此出處http://neilhappy.blog.51cto.com/5504414/1083055

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved