歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Unix知識 >> Unix教程 >> 初學入門系列:Unix常用函數2

初學入門系列:Unix常用函數2

日期:2017/2/27 17:43:14   编辑:Unix教程

  一、系統子程序
  
  (1)I/O子程序
  
  *creat():建立一個新文件或重寫一個暫存文件。需要兩個參數:文件名和存取許可值(8進制方式)。如:
  
  creat("/usr/pat/read_write",0666) /* 建立存取許可方式為0666的文件 */
  
  調用此子程序的進程必須要有建立的文件的所在目錄的寫和執行許可,置給creat()的許可方式變量將被umask()設置的文件建立屏蔽值所修改,新文件的所有者和小組由有效的UID和GID決定。返回值為新建文件的文件描述符。
  
  *fstat():見後面的stat()。
  
  *open():在C程序內部打開文件。需要兩個參數:文件路徑名和打開方式(I,O,I&O)。如果調用此子程序的進程沒有對於要打開的文件的正確存取許可(包括文件路徑上所有目錄分量的搜索許可),將會引起執行失敗。如果此子程序被調用去打開不存在的文件,除非設置了O_CREAT標志,調用將不成功。此時,新文件的存取許可作為第三個參數(可被用戶的umask修改)。當文件被進程打開後再改變該文件或該文件所在目錄的存取許可,不影響對該文件的I/O操作。
  
  *read():已由open()打開並用作輸入的文件中讀信息。它並不關心該文件的存取許可。一旦文件作為輸入打開,即可從該文件中讀取信息。
  
  *write():輸出信息到已由open()打開並用作輸出的文件中。同read()一樣它也不關心該文件的存取許可。
  
  (2)進程控制
  
  *exec()族:包括execl(),execv(),execle(),execve(),execlp()和execvp()可將一可執行模快拷貝到調用進程占有的存貯空間。正被調用進程執行的程序將不復存在,新程序取代其位置。這是UNIX系統中一個程序被執行的唯一方式:用將執行的程序復蓋原有的程序。
  
  安全注意事項:
  
  實際的和有效的UID和GID傳遞給由exec()調入的不具有SUID和SGID許可的程序。
  
  如果由exec()調入的程序有SUID和SGID許可,則有效的UID和GID將設置給該程序的所有者或小組。
  
  文件建立屏蔽值將傳遞給新程序。
  
  除設了對exec()關閉標志的文件外,所有打開的文件都傳遞給新程序。用fcntl()子程序可設置對exec()的關閉標志
  
  *fork():用來建立新進程。其建立的子進程是與調用fork()的進程(父進程)完全相同的拷貝(除了進程號外)
  
  安全注意事項:
  
  子進程將繼承父進程的實際和有效的UID和GID。
  
  子進程繼承文件方式建立屏蔽值。
  
  所有打開的文件傳給子進程。
  
  *signal():允許進程處理可能發生的意外事件和中斷。需要兩個參數:信號編號和信號發生時要調用的子程序。信號編號定義在signal.h中。信號發生時要調用的子程序可由用戶編寫,也可用系統給的值,如:SIG_IGN,則信號將被忽略;SIG_DFL則信號將按系統的缺省方式處理。如許多與安全有關的程序禁止終端發中斷信息(BREAK和DELETE),以免自己被用戶終端終止運行。有些信號使UNIX系統的產生進程的核心轉儲(進程接收到信號時所占內存的內容,有時含有重要信息),此系統子程序可用於禁止核心轉儲。
  
  (3)文件屬性
  
  *access():檢測指定文件的存取能力是否符合指定的存取類型。需要兩個參數:文件名和要檢測的存取類型(整數)。
  
  存取類型定義如下:
  
  0: 檢查文件是否存在
  
  1: 檢查是否可執行(搜索)
  
  2: 檢查是否可寫
  
  3: 檢查是否可寫和執行
  
  4: 檢查是否可讀
  
  5: 檢查是否可讀和執行
  
  6: 檢查是否可讀可寫可執行
  
  這些數字的意義和chmod命令中規定許可方式的數字意義相同。此子程序使用實際的UID和GID檢測文件的存取能力(一般有效的UID和GID用於檢查文件存取能力)。返回值: 0:許可 -1:不許可。
  
  *chmod():將指定文件或目錄的存取許可方式改成新的許可方式。需要兩個參數:文件名和新的存取許可方式。
  
  *chown():同時改變指定文件的所有者和小組的UID和GID。(與chown命令不同),由於此子程序同時改變文件的所有者和小組,故必須取消所操作文件的SUID和SGID許可,以防止用戶建立SUID和SGID程序,然後運行chown()去獲得別人的權限。
  
  *stat():返回文件的狀態(屬性)。需要兩個參數:文件路徑名和一個結構指針,指向狀態信息的存放的位置。
  結構定義如下:
  st_mode: 文件類型和存取許可方式
  st_ino: I節點號
  st_dev: 文件所在設備的ID
  st_rdev: 特別文件的ID
  st_nlink: 文件鏈接數
  st_uid: 文件所有者的UID
  st_gid: 文件小組的GID
  st_size: 按字節計數的文件大小
  st_atime: 最後存取時間(讀)
  st_mtime: 最後修改時間(寫)和最後狀態的改變
  st_ctime: 最後的狀態修改時間
  返回值: 0:成功 1:失敗
  
  *umask():將調用進程及其子進程的文件建立屏蔽值設置為指定的存取許可。需要一個參數: 新的文件建立屏值。
  
  (4)UID和GID的處理
  
  *getuid():返回進程的實際UID。
  
  *getgid():返回進程的實際GID。
  
  以上兩個子程序可用於確定是誰在運行進程。
  
  *geteuid():返回進程的有效UID。
  
  *getegid():返回進程的有效GID。
  
  以上兩個子程序可在一個程序不得不確定它是否在運行某用戶而不是運行它的用戶的SUID程序時很有用,可調用它們來檢查確認本程序的確是以該用戶的SUID許可在運行。
  
  *setuid():用於改變有效的UID。對於一般用戶,此子程序僅對要在有效和實際的UID之間變換的SUID程序才有用(從原有效UID變換為實際UID),以保護進程不受到安全危害。實際上該
  進程不再是SUID方式運行。
  
  *setgid():用於改變有效的GID。
  
  二、標准C庫
  
  (1)標准I/O
  
  *fopen():打開一個文件供讀或寫,安全方面的考慮同open()一樣。
  
  *fread(),getc(),fgetc(),gets(),scanf()和fscanf():從已由fopen()打開供讀的文件中讀取信息。它們並不關心文件的存取許可,這一點同read()。
  
  *fwrite(),put(),fputc(),puts,fputs(),printf(),fprintf():寫信息到已由fopen()打開供寫的文件中。它們也不關心文件的存取許可,同write()。
  
  *getpass():從終端上讀至多8個字符長的口令,不回顯用戶輸入的字符。需要一個參數:提示信息。該子程序將提示信息顯示在終端上,禁止字符回顯功能,從/dev/tty讀取口令,然後再恢復字符回顯功能,返回剛敲入的口令的指針。
  
  *popen():將在(5)運行shell中介紹。
  
  (2)/etc/passwd處理
  
  有一組子程序可對/etc/passwd文件進行方便的存取,可對文件讀取到入口項或寫新的入口項或更新等等。
  
  *getpwuid():從/etc/passwd文件中獲取指定的UID的入口項。
  
  *getpwnam():對於指定的登錄名,在/etc/passwd文件檢索入口項。
  
  以上兩個子程序返回一指向passwd結構的指針,該結構定義在 /usr/include/pwd.h中,定義如下:
  struct passwd {
  char * pw_name; /* 登錄名 */
  char * pw_passwd; /* 加密後的口令 */
  uid_t pw_uid; /* UID */
  gid_t pw_gid; /* GID */
  char * pw_age; /* 代理信息 */
  char * pw_comment; /* 注釋 */
  char * pw_gecos;
  char * pw_dir; /* 主目錄 */
  char * pw_shell; /* 使用的shell */
  };
  
  *getpwent(),setpwent(),endpwent():對口令文件作後續處理。首次調用getpwent(),打開/etc/passwd並返回指向文件中第一個入口項的指針,保持調用之間文件的打開狀態。再調用getpwent()可順序地返回口令文件中的各入口項,調用setpwent()把口令文件的指針重新置為文件的開始處。使用完口令文件後調用endpwent()關閉口令文件。
  
  *putpwent():修改或增加/etc/passwd文件中的入口項。此子程序將入口項寫到一個指定的文件中,一般是一個臨時文件,直接寫口令文件是很危險的。最好在執行前做文件封鎖,使兩個程序不能同時寫一個文件。算法如下:
  
  建立一個獨立的臨時文件,即/etc/passnnn,nnn是PID號
  
  建立新產生的臨時文件和標准臨時文件/etc/ptmp的鏈,若建鏈失敗,則為有人正在使用/etc/ptmp,等待直到/etc/ptmp可用為止或退出
  
  將/etc/passwd拷貝到/etc/ptmp,可對此文件做任何修改
  
  將/etc/passwd移到備份文件/etc/opasswd
  
  建立/etc/ptmp和/etc/passwd的鏈
  
  斷開/etc/passnnn與/etc/ptmp的鏈
  
  注意:臨時文件應建立在/etc目錄,才能保證文件處於同一文件系統中,建鏈才能成功,且臨時文件不會不安全。此外,若新文件已存在,即便建鏈的是root用戶,也將失敗,從而保證了一旦臨時文件成功地建鏈後沒有人能再插進來干擾。當然,使用臨時文件的程序應確保清除所有
  臨時文件,正確地捕捉信號。
  
  (3)/etc/group的處理
  
  有一組類似於前面的子程序處理/etc/group的信息,使用時必須用include語句將/usr/include/grp.h文件加入到自己的程序中。該文件定義了group結構,將由getgrnam(),getgrgid(),getgrent()返回group結構指針。
  
  *getgrnam():在/etc/group文件中搜索指定的小組名,然後返回指向小組入口項的指針。
  
  *ge
Copyright © Linux教程網 All Rights Reserved