在unix系统中,每个进程都有一个非负整型表示的唯一进程ID。当一个进程终止时,进程ID可以重新被其他进程使用,为了防止误判,unix系统实现延迟重用算法,即新建的进程ID不同于最近终止进程所使用的ID。
进程ID为0的是调度进程,也称为交换进程,是内核的一部分,不执行磁盘上的程序,因此也称为系统进程。进程ID为1的是init进程,负责在自举内核后启动一个unix系统,init通常读与系统有关的初始文件,并将系统引导到一个状态,该进程不是终止,它是一个普通的用户进程。下面函数是对进程ID的操作。
/* 进程ID */ /* * 函数功能:获取进程ID; * 返回值:所调用进程的ID; * 函数原型: */ #include <unistd.h> pid_t getpid(void); /* * 函数功能:获取父进程ID; * 返回值:所调用进程的父进程ID; * 函数原型: */ pid_t getppid(void); /* * 函数功能:进程实际用户ID; * 返回值:所调用进程的实际用户ID; * 函数原型: */ uid_t getuid(void); /* * 函数功能:进程有效用户ID; * 返回值:所调用进程的有效用户ID; * 函数原型: */ uid_t geteuid(void); /* * 函数功能:进程实际组ID; * 返回值:所调用进程的实际组ID; * 函数原型: */ gid_t getgid(void); /* * 函数功能:进程有效组ID; * 返回值:所调用进程的有效组ID; * 函数原型: */ gid_t getegid(void);测试程序:
#include <unistd.h> #include "apue.h" int main(void) { printf("pid: %d.\n",getpid()); printf("ppid: %d.\n",getppid()); printf("uid: %d.\n",getuid()); printf("euid: %d.\n",geteuid()); printf("gid: %d.\n",getgid()); printf("egid: %d.\n",getegid()); exit(0); }输出结果:
pid: 9136. ppid: 3765. uid: 1000. euid: 1000. gid: 1000. egid: 1000.
为了能够满足一些进程的访问权限,我们会对进程ID进行更改,主要是更改进程的用户ID和组ID。更改ID的规则如下:实际用户ID是指进程执行者;有效用户ID是指进程执行时对文件的访问权限;保存的设置用户ID是有效用户ID的副本,在执行exec调用时后能重新恢复原来的有效用户ID。注:以下的规则也适用于组ID。
以下是更改进程ID的函数
/* 更改进程ID */ /* * 函数功能:设置用户或组ID(包括有效、实际和保存的设置用户的ID); * 返回值:若成功则返回0,若出错则返回-1; * 函数原型: */ #include <unistd.h> int setuid(uid_t uid); int setgid(gid_t gid); /* * 函数功能:交换实际用户(组)ID和有效用户(组)ID; * 返回值:若成功则返回0,若出错则返回-1; */ #include <unistd.h> int setreuid(uid_t ruid, uid_t euid); int setregid(gid_t rgid, gid_t egid); /* 说明: * 若其中任一参数值为-1,则表示ID不变; */ /* * 函数功能:更改有效用户或有效组ID; * 返回值:若成功则返回0,若出错则返回-1; * 函数原型: */ #include <unistd.h> int seteuid(uid_t uid); int setegid(gid_t gid);参考资料:
《unix高级环境编程》