《unix高级环境编程》进程控制——进程ID

进程ID

        在unix系统中,每个进程都有一个非负整型表示的唯一进程ID。当一个进程终止时,进程ID可以重新被其他进程使用,为了防止误判,unix系统实现延迟重用算法,即新建的进程ID不同于最近终止进程所使用的ID。

        进程ID为0的是调度进程,也称为交换进程,是内核的一部分,不执行磁盘上的程序,因此也称为系统进程。进程ID为1的是init进程,负责在自举内核后启动一个unix系统,init通常读与系统有关的初始文件,并将系统引导到一个状态,该进程不是终止,它是一个普通的用户进程。下面函数是对进程ID的操作。

获取进程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是有效用户ID的副本,在执行exec调用时后能重新恢复原来的有效用户ID。注:以下的规则也适用于组ID。

  1. 若进程具有超级用户特权,则setuid函数将实际用户ID、有效用户ID,以及保存的设置用户ID设置为uid。
  2. 若进程没有超级用户权限,但是uid等于实际用户ID或保存的设置用户ID,则setuid函数将有效用户ID设置为uid。不改变实际用户和保存的设置用户ID。
  3. 若以上都不满足,则将errno设置为EPERM,并返回-1。
     关于内核维护的三个用户ID,应注意以下几点:

  1. 只有超级用户才可以修改实际用户ID。
  2. 仅当对程序文件设置了设置用户ID位时,exec函数才会设置有效用户ID。
  3. 保存的设置用户ID是由exec函数复制有效用户ID而得来的。
     改变三个用户ID的不同方法如下图所示:

《unix高级环境编程》进程控制——进程ID_第1张图片

      以下是更改进程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高级环境编程》

你可能感兴趣的:(进程控制,进程ID,Unix高级环境编程)