[APUE]進程控制(下)

一、更改用戶ID和組ID

  可以用setuid設置實際用戶ID和有效用戶ID。可以用setgid函數設置實際組ID和有效組ID。

#include <sys/types.h>
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
返回值:成功爲0,出錯爲-1

  有關改變用戶ID的規則。

  • 若進程具有root特權,則setuid函數將實際用戶ID、有效用戶ID,以及保存的設置-用戶-ID設置爲uid。
  • 若進程沒有root權限,但是uid等於實際用戶ID或保存的設置-用戶-ID,則setuid只將有效用用戶ID設置爲uid。不改變實際用戶ID和保存的設置-用戶-ID。
  • 如果上面兩個條件都不滿足,則errno設置爲EPERM,並返回出錯。

  在這裏假定_POSIX+_SAVED_IDS爲真。如果沒有提供這種功能,則上面所說的關於保存的設置-用戶-ID部分都無效。
  關於內核所維護的三個用戶ID,還要注意以下:

  • 只有root用戶可以修改實際用戶ID。通常,實際用戶ID是在用戶登錄時,由login程序設置的,而且絕不會改變它。因爲login進程是一個root進程,當它調用setuid時,設置所有三個用戶ID。
  • 僅當對程序文件設置了設置-用戶-ID位時,exec函數設置有效用戶ID。任何時候都可以調用setuid,將有效用戶ID設置爲實際用戶ID或保存的設置-用戶-ID。自然,不能將有效用戶ID設置爲任一隨機值。
  • 保存的設置-用戶-ID是由exec從有效用戶ID複製的。在exec按文件用戶ID設置了有效用戶ID後,即進行這種複製,並將此副本保存起來。

  下表列出了改變這三個用戶ID的不同方法

1. setreuid和setregid函數

  4.3+BSD支持setregid函數,其功能是交換實際用戶ID和有效用戶ID的值。

#include <sys/types.h>
#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);

其作用是一個非特權用戶總能交換實際用戶ID和有效用戶ID。這就允許一個設置-用戶-ID程序轉換成只具有用戶的普通權限,以後又可再次切換回設置-用戶-ID所得到大的額外權限。

2. seteuid和setegid函數

  這兩個函數只更改有效用戶ID和有效組ID。

#include <sys/types.h>
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_t gid);
返回值: 成功爲0,出錯爲-1

一個非特權用戶可將有效用戶ID設置爲其實際用戶ID獲取保存的設置-用戶-ID。對於一個特權用戶可將有效用戶ID設置爲uid。

3. 組ID

以上所說明的一切都以類似方式適用於各個組ID,添加組ID不受setgid函數的影響。

 

二、解釋器文件

  解釋器文件就是linxu中的shell腳本。這種文件是文本文件,其起始行的形式是:

#! pathname [optional-argument]

  在感嘆號和pathname之間的空格是可任選的。最常見的是以下列行開始:

#! /bin/sh

  pathname通常是個絕對路徑名,對它不進行什麼特殊的處理(不適用PATH進行路徑搜索)。
  很多系統對解釋器文件第一行有長度限制(32個字符)。這包括#!、pathname、可選參數以及空格數。

三、system函數

  ANSI C定義了system函數

#include <stdlib.h>
int system(const char *cmdstring);

  如果cmdstring是一個空指針,則僅當命令處理程序可用時,system返回非0值,這一特性可以決定在一個給定的操作系統上是否支持system函數。
  system在其實現中調用了fork、exec和waitpid,因此有三種返回值:
(1) 如果fork失敗或者waitpid返回除EINTR之外的出錯,則system返回-1,而且errno中設置了錯誤類型。
(2) 如果exec失敗(表示不能執行shell),則其返回值如果shell執行了exit(127)一樣。
(3) 如果三個函數都成功,則system的返回值是shell的終止狀態。   如果一個進程正以特殊的許可權 (設置-用戶-I D或設置-組-I D )運行,它又想生成另一個進程執行另一個程序,則它應當直接使用fork和exec,而且在fork之後、exec之前要改回到普通許可權。設置-用戶-I D或設置-組-I D程序決不應調用system函數。

四、進程時間

  任一進程都可調用times函數以獲得它自己及終止子進程的時鐘時間、用戶CPU時間和系統CPU時間。

#include <sys/times.h>
clock_t times(struct tms *buf);
返回: 若成功則爲經過的時鐘時間,若出錯則爲-1

此函數填寫由buf指向的tms結構,該結構定義如下:

struct tms {
    clock_t tms_utime; /* 用戶CPU時間 */
    clock_t tms_stime; /* 系統CPU時間 */
    clock_t tms_cutime; /* 終止子進程用戶CPU時間 */
    clock_t tms_cstime; /* 終止子進程系統CPU時間 */
}

  此結構沒有時鐘時間。作爲代替,times函數返回時鐘時間作爲函數值。此至是相對於過去的某一時刻度量的,所以不能用其絕對值而應該使用其相對值。例: 調用times,保存其返回值,在以後的某個時間再次調用times,從新返回的值中減去以前返回的值,此差值就是時鐘時間。
  所有由次函數返回的clock_t值都用_SC_CLK_TCK(由sysconf函數返回的每秒時鐘滴答數)轉換成秒數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章