lienhua34
2014-10-05
1 main 函数是如何被调用的?
在编译 C 程序时,C 编译器调用链接器在生成的目标可执行程序文件中,设置一个特殊的启动例程为程序的起始地址。当内核执行 C 程序时,在调用 main 前先调用这个特殊的启动例程,该启动例程从内核取得命令行参数和环境变量值。
2 共享库
共享库使得可执行文件中不再需要包含共用的库例程,而只需在所有进程都可引用的存储区中维护这种库例程的一个副本。程序第一次执行或者第一次调用某个库函数时,用动态链接方法将程序与共享库函数相链接。
共享库的另一个优点是可以用库函数的新版本代替老版本,而无需对使用该库的程序重新链接。
3 进程标识符
每个进程都有一个非负整型表示的唯一进程 ID,称为进程标识符。进程 ID 可以被重用。当一个进程终止时,其进程 ID 就可以用于另一个新的进程。不过 UNIX 通过采用延迟重用算法,使得赋予新进程的 ID 不同于最近终止的进程所使用的 ID,防止将新进程误认为是使用同一个 ID的已经终止的前进程。
UNIX 系统通常有一些特殊的进程。例如,
(1)交换进程 swapper:交换进程是 UNIX 系统的调度进程,其进程 ID 为 0.该进程是内核的一部分,它并不执行任何磁盘上的程序。init 进程 init 进程的进程 ID 为 1。它在自举过程结束时由内核调用。
(2)init进程:通常读取与系统有关的初始化文件(/etc/rc* 文件或/etc/inittab文件,以及/etc/init.d 中的文件),并将系统引导到一个状态。init 进程是一个以超级用户特权执行的用户进程,它不会终止。另外,init进程是所有孤儿进程的父进程。
UNIX 系统提供了下面两个函数用于获取进程标识符,
#include <unistd.h>
pid_t getpid(void);
返回值:调用进程的进程IDpid_t getppid(void);
返回值:调用进程的父进程ID
4 进程的实际、有效和保存的用户和组 ID
在文件访问权限与进程访问控制中,我们讲到了进程的这几个属性。
UNIX 系统提供了下面几个函数用于获取相对应的属性,
#include <unistd.h>
uid_t getuid(void);
返回值:调用进程的实际用户IDuid_t geteuid(void);
返回值:调用进程的有效用户IDgid_t getgid(void);
返回值:调用进程的实际组IDgid_t getegid(void);
返回值:调用进程的有效组ID
保存的设置用户 ID 是由 exec 函数复制有效用户 ID 而得来的。如果设置了文件的设置用户 ID 位,则 exec 函数会将文件的用户 ID 设置为进程的有效用户 ID。否则,则新进程的有效用户 ID 不会被改变。但是,无论是否设置了文件的设置用户 ID 位,exec 函数都会将进程当前的有效用户 ID 复制到保存的设置用户 ID 中。
可以调用 setuid 函数设置实际用户 ID 和有效用户 ID。与此类似,可以调用 getgid 函数设置实际组 ID 和有效组 ID。
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
两个函数返回值:若成功则返回0,若出错则返回-1
setuid 函数改变用户 ID 的规则为(setgid 函数改变组 ID 的规则类似),
1. 若进程具有超级用户特权,则 setuid 函数将实际用户 ID、有效用户ID,以及保存的设置用户 ID 设置为 uid。
2. 若进程没有超级用户特权,但是 uid 等于实际用户 ID 或保存的设置用户 ID,则 setuid 函数只将进程有效用户 ID 设置为 uid,不改变实际用户 ID 和保存的设置用户 ID。
3. 如果上面两个条件都不满足,则将 errno 设置为 EPERM,并返回 -1.
POSIX.1 还提供了两个函数 seteuid 和 setegid,
#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_t gid);
两个函数返回值:若成功则返回0,若出错则返回-1
这两个函数类似 setuid 和 setgid,不过这两个函数只更改有效用户 ID 和有效组 ID。
(done)