linux常用c函數 文件許可權控制篇

火星人 @ 2014-03-12 , reply:0
←手機掃碼閱讀

  
     access(判斷是否具有存取文件的許可權)
  相關函數  stat,open,chmod,chown,setuid,setgid
  表頭文件  #include<unistd.h>
  定義函數  int access(const char * pathname,int mode);
  函數說明  access()會檢查是否可以讀/寫某一已存在的文件。參數mode有幾種情況組合,R_OK,W_OK,X_OK 和F_OK。R_OK,W_OK與X_OK用來檢查文件是否具有讀取、寫入和執行的許可權。F_OK則是用來判斷該文件是否存在。由於access()只作許可權的核查,並不理會文件形態或文件內容,因此,如果一目錄表示為“可寫入”,表示可以在該目錄中建立新文件等操作,而非意味此目錄可以被當做文件處理。例如,你會發現DOS的文件都具有“可執行”許可權,但用execve()執行時則會失敗。
  返回值 若所有欲查核的許可權都通過了檢查則返回0值,表示成功,只要有一許可權被禁止則返回-1。
  錯誤代碼  EACCESS 參數pathname 所指定的文件不符合所要求測試的許可權。
  EROFS 欲測試寫入許可權的文件存在於只讀文件系統內。
  EFAULT 參數pathname指針超出可存取內存空間。
  EINVAL 參數mode 不正確。
  ENAMETOOLONG 參數pathname太長。
  ENOTDIR 參數pathname為一目錄。
  ENOMEM 核心內存不足
  ELOOP 參數pathname有過多符號連接問題。
  EIO I/O 存取錯誤。
  附加說明 使用access()作用戶認證方面的判斷要特別小心,例如在access()后再做open()的空文件可能會造成系統安全上的問題。
  範例  /* 判斷是否允許讀取/etc/passwd */
  #include<unistd.h>
  int main()
  {
  if (access(“/etc/passwd”,R_OK) = =0)
  printf(“/etc/passwd can be read\n”);
  }
  執行  /etc/passwd can be read
  alphasort(依字母順序排序目錄結構)
  相關函數  scandir,qsort
  表頭文件  #include<dirent.h>
  定義函數  int alphasort(const struct dirent **a,const struct dirent **b);
  函數說明  alphasort()為scandir()最後調用qsort()函數時傳給qsort()作為判斷的函數,詳細說明請參考scandir()及qsort()。
  返回值 參考qsort()。
  範例  /* 讀取/目錄下所有的目錄結構,並依字母順序排列*/
  main()
  {
  struct dirent **namelist;
  int i,total;
  total = scandir(“/”,&namelist ,0,alphasort);
  if(total <0)
  perror(“scandir”);
  else{
  for(i=0;i<total;i++)
  printf(“%s\n”,namelist[i]->d_name);
  printf(“total = %d\n”,total);
  }
  }
  執行  ..
  .gnome
  .gnome_private
  ErrorLog
  Weblog
  bin
  boot
  dev
  dosc
  dosd
  etc
  home
  lib
  lost+found
  misc
  mnt
  opt
  proc
  root
  sbin
  tmp
  usr
  var
  total = 24
  chdir(改變當前的工作(目錄)
  相關函數  getcwd,chroot
  表頭文件  #include<unistd.h>
  定義函數  int chdir(const char * path);
  函數說明  chdir()用來將當前的工作目錄改變成以參數path所指的目錄。
  返回值 執行成功則返回0,失敗返回-1,errno為錯誤代碼。
  範例  #include<unistd.h>
  main()
  {
  chdir(“/tmp”);
  printf(“current working directory: %s\n”,getcwd(NULL,NULL));
  }
  執行  current working directory :/tmp
  chmod(改變文件的許可權)
  相關函數  fchmod,stat,open,chown
  表頭文件  #include<sys/types.h>
  #include<sys/stat.h>
  定義函數  int chmod(const char * path,mode_t mode);
  函數說明  chmod()會依參數mode 許可權來更改參數path 指定文件的許可權。
  參數  mode 有下列數種組合
  S_ISUID 04000 文件的(set user-id on execution)位
  S_ISGID 02000 文件的(set group-id on execution)位
  S_ISVTX 01000 文件的sticky位
  S_IRUSR(S_IREAD) 00400 文件所有者具可讀取許可權
  S_IWUSR(S_IWRITE)00200 文件所有者具可寫入許可權
  S_IXUSR(S_IEXEC) 00100 文件所有者具可執行許可權
  S_IRGRP 00040 用戶組具可讀取許可權
  S_IWGRP 00020 用戶組具可寫入許可權
  S_IXGRP 00010 用戶組具可執行許可權
  S_IROTH 00004 其他用戶具可讀取許可權
  S_IWOTH 00002 其他用戶具可寫入許可權
  S_IXOTH 00001 其他用戶具可執行許可權
  只有該文件的所有者或有效用戶識別碼為0,才可以修改該文件許可權。基於系統安全,如果欲將數據寫入一執行文件,而該執行文件具有S_ISUID 或S_ISGID 許可權,則這兩個位會被清除。如果一目錄具有S_ISUID 位許可權,表示在此目錄下只有該文件的所有者或root可以刪除該文件。
  返回值 許可權改變成功返回0,失敗返回-1,錯誤原因存於errno。
  錯誤代碼  EPERM 進程的有效用戶識別碼與欲修改許可權的文件擁有者不同,而且也不具root許可權。
  EACCESS 參數path所指定的文件無法存取。
  EROFS 欲寫入許可權的文件存在於只讀文件系統內。
  EFAULT 參數path指針超出可存取內存空間。
  EINVAL 參數mode不正確
  ENAMETOOLONG 參數path太長
  ENOENT 指定的文件不存在
  ENOTDIR 參數path路徑並非一目錄
  ENOMEM 核心內存不足
  ELOOP 參數path有過多符號連接問題。
  EIO I/O 存取錯誤
  範例  /* 將/etc/passwd 文件許可權設成S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH */
  #include<sys/types.h>
  #include<sys/stat.h>
  main()
  {
  chmod(“/etc/passwd”,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
  }
  chown(改變文件的所有者)
  相關函數  fchown,lchown,chmod
  表頭文件  #include<sys/types.h>
  #include<unistd.h>
  定義函數  int chown(const char * path, uid_t owner,gid_t group);
  函數說明  chown()會將參數path指定文件的所有者變更為參數owner代表的用戶,而將該文件的組變更為參數group組。如果參數owner或group為-1,對應的所有者或組不會有所改變。root與文件所有者皆可改變文件組,但所有者必須是參數group組的成員。當root用chown()改變文件所有者或組時,該文件若具有S_ISUID或S_ISGID許可權,則會清除此許可權位,此外如果具有S_ISGID許可權但不具S_IXGRP位,則該文件會被強制鎖定,文件模式會保留。
  返回值 成功則返回0,失敗返回-1,錯誤原因存於errno。
  錯誤代碼 參考chmod()。
  範例  /* 將/etc/passwd 的所有者和組都設為root */
  #include<sys/types.h>
  #include<unistd.h>
  main()
  {
  chown(“/etc/passwd”,0,0);
  }
  chroot(改變根目錄)
  相關函數  chdir
  表頭文件  #include<unistd.h>
  定義函數  int chroot(const char * path);
  函數說明  chroot()用來改變根目錄為參數path 所指定的目錄。只有超級用戶才允許改變根目錄,子進程將繼承新的根目錄。
  返回值 調用成功則返回0,失敗則返-1,錯誤代碼存於errno。
  錯誤代碼  EPERM 許可權不足,無法改變根目錄。
  EFAULT 參數path指針超出可存取內存空間。
  ENAMETOOLONG 參數path太長。
  ENOTDIR 路徑中的目錄存在但卻非真正的目錄。
  EACCESS 存取目錄時被拒絕
  ENOMEM 核心內存不足。
  ELOOP 參數path有過多符號連接問題。
  EIO I/O 存取錯誤。
  範例  /* 將根目錄改為/tmp ,並將工作目錄切換至/tmp */
  #include<unistd.h>
  main()
  {
  chroot(“/tmp”);
  chdir(“/”);
  }
       closedir(關閉目錄)
  相關函數  opendir
  表頭文件  #include<sys/types.h>
  #include<dirent.h>
  定義函數  int closedir(DIR *dir);
  函數說明  closedir()關閉參數dir所指的目錄流。
  返回值 關閉成功則返回0,失敗返回-1,錯誤原因存於errno 中。
  錯誤代碼  EBADF 參數dir為無效的目錄流
  範例 參考readir()。
  fchdir(改變當前的工作目錄)
  相關函數  getcwd,chroot
  表頭文件  #include<unistd.h>
  定義函數  int fchdir(int fd);
  函數說明  fchdir()用來將當前的工作目錄改變成以參數fd 所指的文件描述詞。
  返回值執 行成功則返回0,失敗返回-1,errno為錯誤代碼。
  附加說明
  範例  #include<sys/types.h>
  #include<sys/stat.h>
  #include<fcntl.h>
  #include<unistd.h>
  main()
  {
  int fd;
  fd = open(“/tmp”,O_RDONLY);
  fchdir(fd);
  printf(“current working directory : %s \n”,getcwd(NULL,NULL));
  close(fd);
  }
  執行  current working directory : /tmp
  fchmod(改變文件的許可權)
  相關函數  chmod,stat,open,chown
  表頭文件  #include<sys/types.h>
  #include<sys/stat.h>
  定義函數  int fchmod(int fildes,mode_t mode);
  函數說明  fchmod()會依參數mode許可權來更改參數fildes所指文件的許可權。參數fildes為已打開文件的文件描述詞。參數mode請參考chmod()。
  返回值 許可權改變成功則返回0,失敗返回-1,錯誤原因存於errno。
  錯誤原因  EBADF 參數fildes為無效的文件描述詞。
  EPERM 進程的有效用戶識別碼與欲修改許可權的文件所有者不同,而且也不具root許可權。
  EROFS 欲寫入許可權的文件存在於只讀文件系統內。
  EIO I/O 存取錯誤。
  範例  #include<sys/stat.h>
  #include<fcntl.h>
  main()
  {
  int fd;
  fd = open (“/etc/passwd”,O_RDONLY);
  fchmod(fd,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
  close(fd);
  }
  fchown(改變文件的所有者)
  相關函數  chown,lchown,chmod
  表頭文件  #include<sys/types.h>
  #include<unistd.h>
  定義函數  int fchown(int fd,uid_t owner,gid_t group);
  函數說明  fchown()會將參數fd指定文件的所有者變更為參數owner代表的用戶,而將該文件的組變更為參數group組。如果參數owner或group為-1,對映的所有者或組有所改變。參數fd 為已打開的文件描述詞。當root用fchown()改變文件所有者或組時,該文件若具S_ISUID或S_ISGID許可權,則會清除此許可權位。
  返回值 成功則返回0,失敗則返回-1,錯誤原因存於errno。
  錯誤代碼  EBADF 參數fd文件描述詞為無效的或該文件已關閉。
  EPERM 進程的有效用戶識別碼與欲修改許可權的文件所有者不同,而且也不具root許可權,或是參數owner、group不正確。
  EROFS 欲寫入的文件存在於只讀文件系統內。
  ENOENT 指定的文件不存在
  EIO I/O存取錯誤
  範例  #include<sys/types.h>
  #include<unistd.h>
  #include<fcntl.h>
  main()
  {
  int fd;
  fd = open (“/etc/passwd”,O_RDONLY);
  chown(fd,0,0);
  close(fd);
  }
  fstat(由文件描述詞取得文件狀態)
  相關函數  stat,lstat,chmod,chown,readlink,utime
  表頭文件  #include<sys/stat.h>
  #include<unistd.h>
  定義函數  int fstat(int fildes,struct stat *buf);
  函數說明  fstat()用來將參數fildes所指的文件狀態,複製到參數buf所指的結構中(struct stat)。Fstat()與stat()作用完全相同,不同處在於傳入的參數為已打開的文件描述詞。詳細內容請參考stat()。
  返回值 執行成功則返回0,失敗返回-1,錯誤代碼存於errno。
  範例  #include<sys/stat.h>
  #include<unistd.h>
  #include<fcntk.h>
  main()
  {
  struct stat buf;
  int fd;
  fd = open (“/etc/passwd”,O_RDONLY);
  fstat(fd,&buf);
  printf(“/etc/passwd file size +%d\n “,buf.st_size);
  }
  執行  /etc/passwd file size = 705
  ftruncate(改變文件大小)
  相關函數  open,truncate
  表頭文件  #include<unistd.h>
  定義函數  int ftruncate(int fd,off_t length);
  函數說明  ftruncate()會將參數fd指定的文件大小改為參數length指定的大小。參數fd為已打開的文件描述詞,而且必須是以寫入模式打開的文件。如果原來的文件大小比參數length大,則超過的部分會被刪去。
  返回值 執行成功則返回0,失敗返回-1,錯誤原因存於errno。
  錯誤代碼  EBADF 參數fd文件描述詞為無效的或該文件已關閉。
  EINVAL 參數fd 為一socket 並非文件,或是該文件並非以寫入模式打開。
  getcwd(取得當前的工作目錄)
  相關函數  get_current_dir_name,getwd,chdir
  表頭文件  #include<unistd.h>
  定義函數  char * getcwd(char * buf,size_t size);
  函數說明  getcwd()會將當前的工作目錄絕對路徑複製到參數buf所指的內存空間,參數size為buf的空間大小。在調用此函數時,buf所指的內存空間要足夠大,若工作目錄絕對路徑的字元串長度超過參數size大小,則回值NULL,errno的值則為ERANGE。倘若參數buf為NULL,getcwd()會依參數size的大小自動配置內存(使用malloc()),如果參數size也為0,則getcwd()會依工作目錄絕對路徑的字元串程度來決定所配置的內存大小,進程可以在使用完此字元串后利用free()來釋放此空間。
  返回值 執行成功則將結果複製到參數buf所指的內存空間,或是返回自動配置的字元串指針。失敗返回NULL,錯誤代碼存於errno。
  範例  #include<unistd.h>
  main()
  {
  char buf[80];
  getcwd(buf,sizeof(buf));
  printf(“current working directory : %s\n”,buf);
  }
  執行  current working directory :/tmp
  link(建立文件連接)
  相關函數  symlink,unlink
  表頭文件  #include<unistd.h>
  定義函數  int link (const char * oldpath,const char * newpath);
  函數說明  link()以參數newpath指定的名稱來建立一個新的連接(硬連接)到參數oldpath所指定的已存在文件。如果參數newpath指定的名稱為一已存在的文件則不會建立連接。
  返回值 成功則返回0,失敗返回-1,錯誤原因存於errno。
  附加說明  link()所建立的硬連接無法跨越不同文件系統,如果需要請改用symlink()。
  錯誤代碼  EXDEV 參數oldpath與newpath不是建立在同一文件系統。
  EPERM 參數oldpath與newpath所指的文件系統不支持硬連接
  EROFS 文件存在於只讀文件系統內
  EFAULT 參數oldpath或newpath 指針超出可存取內存空間。
  ENAMETOLLONG 參數oldpath或newpath太長
  ENOMEM 核心內存不足
  EEXIST 參數newpath所指的文件名已存在。
  EMLINK 參數oldpath所指的文件已達最大連接數目。
  ELOOP 參數pathname有過多符號連接問題
  ENOSPC 文件系統的剩餘空間不足。
  EIO I/O 存取錯誤。
  範例  /* 建立/etc/passwd 的硬連接為pass */
  #include<unistd.h>
  main()
  {
  link(“/etc/passwd”,”pass”);
  }
  lstat(由文件描述詞取得文件狀態)
  相關函數  stat,fstat,chmod,chown,readlink,utime
  表頭文件  #include<sys/stat.h>
  #include<unistd.h>
  定義函數  int lstat (const char * file_name.struct stat * buf);
  函數說明  lstat()與stat()作用完全相同,都是取得參數file_name所指的文件狀態,其差別在於,當文件為符號連接時,lstat()會返回該link本身的狀態。詳細內容請參考stat()。
  返回值 執行成功則返回0,失敗返回-1,錯誤代碼存於errno。
  範例 參考stat()。
       opendir(打開目錄)
  相關函數  open,readdir,closedir,rewinddir,seekdir,telldir,scandir
  表頭文件  #include<sys/types.h>
  #include<dirent.h>
  定義函數  DIR * opendir(const char * name);
  函數說明  opendir()用來打開參數name指定的目錄,並返回DIR*形態的目錄流,和open()類似,接下來對目錄的讀取和搜索都要使用此返回值。
  返回值 成功則返回DIR* 型態的目錄流,打開失敗則返回NULL。
  錯誤代碼  EACCESS 許可權不足
  EMFILE 已達到進程可同時打開的文件數上限。
  ENFILE 已達到系統可同時打開的文件數上限。
  ENOTDIR 參數name非真正的目錄
  ENOENT 參數name 指定的目錄不存在,或是參數name 為一空字元串。
  ENOMEM 核心內存不足。
  readdir(讀取目錄)
  相關函數  open,opendir,closedir,rewinddir,seekdir,telldir,scandir
  表頭文件  #include<sys/types.h>
  #include<dirent.h>
  定義函數  struct dirent * readdir(DIR * dir);
  函數說明  readdir()返回參數dir目錄流的下個目錄進入點。
  結構dirent定義如下
  struct dirent
  {
  ino_t d_ino;
  ff_t d_off;
  signed short int d_reclen;
  unsigned char d_type;
  har d_name[256;
  };
  d_ino 此目錄進入點的inode
  d_off 目錄文件開頭至此目錄進入點的位移
  d_reclen _name的長度,不包含NULL字元
  d_type d_name 所指的文件類型
  d_name 文件名
  返回值 成功則返回下個目錄進入點。有錯誤發生或讀取到目錄文件尾則返回NULL。
  附加說明  EBADF參數dir為無效的目錄流。
  範例  #include<sys/types.h>
  #include<dirent.h>
  #include<unistd.h>
  main()
  {
  DIR * dir;
  struct dirent * ptr;
  int i;
  dir =opendir(“/etc/rc.d”);
  while((ptr = readdir(dir))!=NULL)
  {
  printf(“d_name: %s\n”,ptr->d_name);
  }
  closedir(dir);
  }
  執行  d_name:.
  d_name:..
  d_name:init.d
  d_name:rc0.d
  d_name:rc1.d
  d_name:rc2.d
  d_name:rc3.d
  d_name:rc4.d
  d_name:rc5.d
  d_name:rc6.d
  d_name:rc
  d_name:rc.local
  d_name:rc.sysinit
  readlink(取得符號連接所指的文件)
  相關函數  stat,lstat,symlink
  表頭文件  #include<unistd.h>
  定義函數  int readlink(const char * path ,char * buf,size_t bufsiz);
  函數說明  readlink()會將參數path的符號連接內容存到參數buf所指的內存空間,返回的內容不是以NULL作字元串結尾,但會將字元串的字元數返回。若參數bufsiz小於符號連接的內容長度,過長的內容會被截斷。
  返回值 執行成功則傳符號連接所指的文件路徑字元串,失敗則返回-1,錯誤代碼存於errno。
  錯誤代碼  EACCESS 取文件時被拒絕,許可權不夠
  EINVAL 參數bufsiz 為負數
  EIO I/O 存取錯誤。
  ELOOP 欲打開的文件有過多符號連接問題。
  ENAMETOOLONG 參數path的路徑名稱太長
  ENOENT 參數path所指定的文件不存在
  ENOMEM 核心內存不足
  ENOTDIR 參數path路徑中的目錄存在但卻非真正的目錄。
  remove(刪除文件)
  相關函數  link,rename,unlink
  表頭文件  #include<stdio.h>
  定義函數  int remove(const char * pathname);
  函數說明  remove()會刪除參數pathname指定的文件。如果參數pathname為一文件,則調用unlink()處理,若參數pathname為一目錄,則調用rmdir()來處理。請參考unlink()與rmdir()。
  返回值 成功則返回0,失敗則返回-1,錯誤原因存於errno。
  錯誤代碼  EROFS 欲寫入的文件存在於只讀文件系統內
  EFAULT 參數pathname指針超出可存取內存空間
  ENAMETOOLONG 參數pathname太長
  ENOMEM 核心內存不足
  ELOOP 參數pathname有過多符號連接問題
  EIO I/O 存取錯誤。
  rename(更改文件名稱或位置)
  相關函數  link,unlink,symlink
  表頭文件  #include<stdio.h>
  定義函數  int rename(const char * oldpath,const char * newpath);
  函數說明  rename()會將參數oldpath 所指定的文件名稱改為參數newpath所指的文件名稱。若newpath所指定的文件已存在,則會被刪除。
  返回值 執行成功則返回0,失敗返回-1,錯誤原因存於errno
  範例  /* 設計一個DOS下的rename指令rename 舊文件名新文件名*/
  #include <stdio.h>
  void main(int argc,char **argv)
  {
  if(argc<3){
  printf(“Usage: %s old_name new_name\n”,argv[0]);
  return;
  }
  printf(“%s=>%s”,argc[1],argv[2]);
  if(rename(argv[1],argv[2]<0)
  printf(“error!\n”);
  else
  printf(“ok!\n”);
  }
  rewinddir(重設讀取目錄的位置為開頭位置)
  相關函數  open,opendir,closedir,telldir,seekdir,readdir,scandir
  表頭文件  #include<sys/types.h>
  #include<dirent.h>
  定義函數  void rewinddir(DIR *dir);
  函數說明  rewinddir()用來設置參數dir 目錄流目前的讀取位置為原來開頭的讀取位置。
  返回值
  錯誤代碼  EBADF dir為無效的目錄流
  範例  #include<sys/types.h>
  #include<dirent.h>
  #include<unistd.h>
  main()
  {
  DIR * dir;
  struct dirent *ptr;
  dir = opendir(“/etc/rc.d”);
  while((ptr = readdir(dir))!=NULL)
  {
  printf(“d_name :%s\n”,ptr->d_name);
  }
  rewinddir(dir);
  printf(“readdir again!\n”);
  while((ptr = readdir(dir))!=NULL)
  {
  printf(“d_name: %s\n”,ptr->d_name);
  }
  closedir(dir);
  }
  執行  d_name:.
  d_name:..
  d_name:init.d
  d_name:rc0.d
  d_name:rc1.d
  d_name:rc2.d
  d_name:rc3.d
  d_name:rc4.d
  d_name:rc5.d
  d_name:rc6.d
  d_name:rc
  d_name:rc.local
  d_name:rc.sysinit
  readdir again!
  d_name:.
  d_name:..
  d_name:init.d
  d_name:rc0.d
  d_name:rc1.d
  d_name:rc2.d
  d_name:rc3.d
  d_name:rc4.d
  d_name:rc5.d
  d_name:rc6.d
  d_name:rc
  d_name:rc.local
  d_name:rc.sysinit
      seekdir(設置下回讀取目錄的位置)
  相關函數  open,opendir,closedir,rewinddir,telldir,readdir,scandir
  表頭文件  #include<dirent.h>
  定義函數  void seekdir(DIR * dir,off_t offset);
  函數說明  seekdir()用來設置參數dir目錄流目前的讀取位置,在調用readdir()時便從此新位置開始讀取。參數offset 代表距離目錄文件開頭的偏移量。
  返回值
  錯誤代碼  EBADF 參數dir為無效的目錄流
  範例  #include<sys/types.h>
  #include<dirent.h>
  #include<unistd.h>
  main()
  {
  DIR * dir;
  struct dirent * ptr;
  int offset,offset_5,i=0;
  dir=opendir(“/etc/rc.d”);
  while((ptr = readdir(dir))!=NULL)
  {
  offset = telldir(dir);
  if(++i = =5) offset_5 =offset;
  printf(“d_name :%s offset :%d \n”,ptr->d_name,offset);
  }
  seekdir(dir offset_5);
  printf(“Readdir again!\n”);
  while((ptr = readdir(dir))!=NULL)
  {
  offset = telldir(dir);
  printf(“d_name :%s offset :%d\n”,ptr->d_name.offset);
  }
  closedir(dir);
  }
  執行  d_name : . offset :12
  d_name : .. offset:24
  d_name : init.d offset 40
  d_name : rc0.d offset :56
  d_name :rc1.d offset :72
  d_name:rc2.d offset :88
  d_name:rc3.d offset 104
  d_name:rc4.d offset:120
  d_name:rc5.d offset:136
  d_name:rc6.d offset:152
  d_name:rc offset 164
  d_name:rc.local offset :180
  d_name:rc.sysinit offset :4096
  readdir again!
  d_name:rc2.d offset :88
  d_name:rc3.d offset 104
  d_name:rc4.d offset:120
  d_name:rc5.d offset:136
  d_name:rc6.d offset:152
  d_name:rc offset 164
  d_name:rc.local offset :180
  d_name:rc.sysinit offset :4096
  stat(取得文件狀態)
  相關函數  fstat,lstat,chmod,chown,readlink,utime
  表頭文件  #include<sys/stat.h>
  #include<unistd.h>
  定義函數  int stat(const char * file_name,struct stat *buf);
  函數說明  stat()用來將參數file_name所指的文件狀態,複製到參數buf所指的結構中。
  下面是struct stat內各參數的說明
  struct stat
  {
  dev_t st_dev; /*device*/
  ino_t st_ino; /*inode*/
  mode_t st_mode; /*protection*/
  nlink_t st_nlink; /*number of hard links */
  uid_t st_uid; /*user ID of owner*/
  gid_t st_gid; /*group ID of owner*/
  dev_t st_rdev; /*device type */
  off_t st_size; /*total size, in bytes*/
  unsigned long st_blksize; /*blocksize for filesystem I/O */
  unsigned long st_blocks; /*number of blocks allocated*/
  time_t st_atime; /* time of lastaccess*/
  time_t st_mtime; /* time of last modification */
  time_t st_ctime; /* time of last change */
  };
  st_dev 文件的設備編號
  st_ino 文件的i-node
  st_mode 文件的類型和存取的許可權
  st_nlink 連到該文件的硬連接數目,剛建立的文件值為1。
  st_uid 文件所有者的用戶識別碼
  st_gid 文件所有者的組識別碼
  st_rdev 若此文件為裝置設備文件,則為其設備編號
  st_size 文件大小,以位元組計算
  st_blksize 文件系統的I/O 緩衝區大小。
  st_blcoks 佔用文件區塊的個數,每一區塊大小為512 個位元組。
  st_atime 文件最近一次被存取或被執行的時間,一般只有在用mknod、utime、read、write與tructate時改變。
  st_mtime 文件最後一次被修改的時間,一般只有在用mknod、utime和write時才會改變
  st_ctime i-node最近一次被更改的時間,此參數會在文件所有者、組、許可權被更改時更新先前所描述的st_mode 則定義了下列數種情況
  S_IFMT 0170000 文件類型的位遮罩
  S_IFSOCK 0140000 scoket
  S_IFLNK 0120000 符號連接
  S_IFREG 0100000 一般文件
  S_IFBLK 0060000 區塊裝置
  S_IFDIR 0040000 目錄
  S_IFCHR 0020000 字元裝置
  S_IFIFO 0010000 先進先出
  S_ISUID 04000 文件的(set user-id on execution)位
  S_ISGID 02000 文件的(set group-id on execution)位
  S_ISVTX 01000 文件的sticky位
  S_IRUSR(S_IREAD) 00400 文件所有者具可讀取許可權
  S_IWUSR(S_IWRITE)00200 文件所有者具可寫入許可權
  S_IXUSR(S_IEXEC) 00100 文件所有者具可執行許可權
  S_IRGRP 00040 用戶組具可讀取許可權
  S_IWGRP 00020 用戶組具可寫入許可權
  S_IXGRP 00010 用戶組具可執行許可權
  S_IROTH 00004 其他用戶具可讀取許可權
  S_IWOTH 00002 其他用戶具可寫入許可權
  S_IXOTH 00001 其他用戶具可執行許可權
  上述的文件類型在POSIX 中定義了檢查這些類型的宏定義
  S_ISLNK (st_mode) 判斷是否為符號連接
  S_ISREG (st_mode) 是否為一般文件
  S_ISDIR (st_mode)是否為目錄
  S_ISCHR (st_mode)是否為字元裝置文件
  S_ISBLK (s3e) 是否為先進先出
  S_ISSOCK (st_mode) 是否為socket
  若一目錄具有sticky 位(S_ISVTX),則表示在此目錄下的文件只能被該文件所有者、此目錄所有者或root來刪除或改名。
  返回值 執行成功則返回0,失敗返回-1,錯誤代碼存於errno
  錯誤代碼  ENOENT 參數file_name指定的文件不存在
  ENOTDIR 路徑中的目錄存在但卻非真正的目錄
  ELOOP 欲打開的文件有過多符號連接問題,上限為16符號連接
  EFAULT 參數buf為無效指針,指向無法存在的內存空間
  EACCESS 存取文件時被拒絕
  ENOMEM 核心內存不足
  ENAMETOOLONG 參數file_name的路徑名稱太長
  範例  #include<sys/stat.h>
  #include<unistd.h>
  mian()
  {
  struct stat buf;
  stat (“/etc/passwd”,&buf);
  printf(“/etc/passwd file size = %d \n”,buf.st_size);
  }
  執行  /etc/passwd file size = 705
symlink(建立文件符號連接)
  相關函數  link,unlink
  表頭文件  #include<unistd.h>
  定義函數  int symlink( const char * oldpath,const char * newpath);
  函數說明  symlink()以參數newpath指定的名稱來建立一個新的連接(符號連接)到參數oldpath所指定的已存在文件。參數oldpath指定的文件不一定要存在,如果參數newpath指定的名稱為一已存在的文件則不會建立連接。
  返回值 成功則返回0,失敗返回-1,錯誤原因存於errno。
  錯誤代碼  EPERM 參數oldpath與newpath所指的文件系統不支持符號連接
  EROFS 欲測試寫入許可權的文件存在於只讀文件系統內
  EFAULT 參數oldpath或newpath指針超出可存取內存空間。
  ENAMETOOLONG 參數oldpath或newpath太長
  ENOMEM 核心內存不足
  EEXIST 參數newpath所指的文件名已存在。
  EMLINK 參數oldpath所指的文件已達到最大連接數目
  ELOOP 參數pathname有過多符號連接問題
  ENOSPC 文件系統的剩餘空間不足
  EIO I/O 存取錯誤
  範例  #include<unistd.h>
  main()
  {
  symlink(“/etc/passwd”,”pass”);
  }
  telldir(取得目錄流的讀取位置)
  相關函數  open,opendir,closedir,rewinddir,seekdir,readdir,scandir
  表頭文件  #include<dirent.h>
  定義函數  off_t telldir(DIR *dir);
  函數說明  telldir()返回參數dir目錄流目前的讀取位置。此返回值代表距離目錄文件開頭的偏移量返回值返回下個讀取位置,有錯誤發生時返回-1。
  錯誤代碼  EBADF參數dir為無效的目錄流。
  範例  #include<sys/types.h>
  #include<dirent.h>
  #include<unistd.h>
  main()
  {
  DIR *dir;
  struct dirent *ptr;
  int offset;
  dir = opendir(“/etc/rc.d”);
  while((ptr = readdir(dir))!=NULL)
  {
  offset = telldir (dir);
  printf(“d_name : %s offset :%d\n”, ptr->d_name,offset);
  }
  closedir(dir);
  }
  執行  d_name : . offset :12
  d_name : .. offset:24
  d_name : init.d offset 40
  d_name : rc0.d offset :56
  d_name :rc1.d offset :72
  d_name:rc2.d offset :88
  d_name:rc3.d offset 104
  d_name:rc4.d offset:120
  d_name:rc5.d offset:136
  d_name:rc6.d offset:152
  d_name:rc offset 164
  d_name:rc.local offset :180
  d_name:rc.sysinit offset :4096
  truncate(改變文件大小)
  相關函數  open,ftruncate
  表頭文件  #include<unistd.h>
  定義函數  int truncate(const char * path,off_t length);
  函數說明  truncate()會將參數path 指定的文件大小改為參數length 指定的大小。如果原來的文件大小比參數length大,則超過的部分會被刪去。
  返回值 執行成功則返回0,失敗返回-1,錯誤原因存於errno。
  錯誤代碼  EACCESS 參數path所指定的文件無法存取。
  EROFS 欲寫入的文件存在於只讀文件系統內
  EFAULT 參數path指針超出可存取內存空間
  EINVAL 參數path包含不合法字元
  ENAMETOOLONG 參數path太長
  ENOTDIR 參數path路徑並非一目錄
  EISDIR 參數path 指向一目錄
  ETXTBUSY 參數path所指的文件為共享程序,而且正被執行中
  ELOOP 參數path’有過多符號連接問題
  EIO I/O 存取錯誤。
  umask(設置建立新文件時的許可權遮罩)
  相關函數  creat,open
  表頭文件  #include<sys/types.h>
  #include<sys/stat.h>
  定義函數  mode_t umask(mode_t mask);
  函數說明  umask()會將系統umask值設成參數mask&0777后的值,然後將先前的umask值返回。在使用open()建立新文件時,該參數mode並非真正建立文件的許可權,而是(mode&~umask)的許可權值。例如,在建立文件時指定文件許可權為0666,通常umask值默認為022,則該文件的真正許可權則為0666&~022=0644,也就是rw-r--r--返回值此調用不會有錯誤值返回。返回值為原先系統的umask值。
 
 unlink(刪除文件)
  相關函數  link,rename,remove
  表頭文件  #include<unistd.h>
  定義函數  int unlink(const char * pathname);
  函數說明  unlink()會刪除參數pathname指定的文件。如果該文件名為最後連接點,但有其他進程打開了此文件,則在所有關於此文件的文件描述詞皆關閉后才會刪除。如果參數pathname為一符號連接,則此連接會被刪除。
  返回值 成功則返回0,失敗返回-1,錯誤原因存於errno
  錯誤代碼  EROFS 文件存在於只讀文件系統內
  EFAULT 參數pathname指針超出可存取內存空間
  ENAMETOOLONG 參數pathname太長
  ENOMEM 核心內存不足
  ELOOP 參數pathname 有過多符號連接問題
  EIO I/O 存取錯誤
  utime(修改文件的存取時間和更改時間)
  相關函數  utimes,stat
  表頭文件  #include<sys/types.h>
  #include<utime.h>
  定義函數  int utime(const char * filename,struct utimbuf * buf);
  函數說明  utime()用來修改參數filename文件所屬的inode存取時間。
  結構utimbuf定義如下
  struct utimbuf{
  time_t actime;
  time_t modtime;
  };
  返回值 如果參數buf為空指針(NULL),則該文件的存取時間和更改時間全部會設為目前時間。
  執行成功則返回0,失敗返回-1,錯誤代碼存於errno。
  錯誤代碼  EACCESS 存取文件時被拒絕,許可權不足
  ENOENT 指定的文件不存在。
  utimes(修改文件的存取時間和更改時間)
  相關函數  utime,stat
  表頭文件  #include<sys/types.h>
  #include<utime.h>
  定義函數  int utimes(char * filename.struct timeval *tvp);
  函數說明  utimes()用來修改參數filename文件所屬的inode存取時間和修改時間。
  結構timeval定義如下
  struct timeval {
  long tv_sec;
  long tv_usec; /* 微妙*/
  };
  返回值 參數tvp 指向兩個timeval 結構空間,和utime()使用的utimebuf結構比較,tvp[0].tc_sec 則為utimbuf.actime,tvp]1].tv_sec 為utimbuf.modtime。
  執行成功則返回0。失敗返回-1,錯誤代碼存於errno。
  錯誤代碼  EACCESS 存取文件時被拒絕,許可權不足
  ENOENT 指定的文件不存在





[火星人 via ] linux常用c函數 文件許可權控制篇已經有251次圍觀

http://www.coctec.com/docs/program/show-post-71595.html