Linux进程编程介绍(三)3.进程的特殊操作 上一节介绍了有关进程的一些基本操作,如进程的产生、进程的终止、进程执行映像的改变、等待子进程终止等。本节要介绍一些有关进程的特殊操作。有了这些操作,就使得进程的编程更加完善,能编制更为实用的程序。 主要的内容有得到关于进程的各种ID、对进程的设置用户ID、改变进程的工作目录、改变进程的根、改变进程的优先权值等操作。 3.1 获得进程相关的ID 与进程相关的ID有:
如果要获得进程的用户标识号,用getuid调用。调用geteuid是用来获得进程的有效用户标识号。有效用户ID与真正用户ID的不同是由于执行文件设置set-uid位引起的。这两个调用的格式如下: uid_t getuid(void);uid_t geteuid(void); 在使用这两个调用的程序中加入下列头文件: #include#include 如果要获得运行进程的用户组ID,使用getgid调用来获得真正的用户组ID,用getegid获得有效的用户组ID。标识gid与egid的不同是由于执行文件设置set-gid位引起的。这两个调用的格式如下: gid_t getgid(void);gid_t getegid(void); 在使用这两个调用的程序中加入下列头文件: #include#include 如果要获得进程的ID,使用getpid调用;要获得进程的父进程的ID,使用getppid调用。这两个调用的格式如下: pid_t getpid(void);pid_t getppid(void); 在使用这两个调用的程序中加入下列头文件: #include如果要获得进程所属组的ID,使用getpgrp调用;若要获得指定PID进程所属组的ID用getpgid调用。这两个调用的格式如下: pid_t getpgrp(void);pid_t getpgid(pid_t pid); 在使用这两个调用的程序中加入下列头文件: #include注意一下gid和pgrp的区别,一般执行该进程的用户的组ID就是该进程的gid,如果该执行文件设置了set_gid位,则文件所属的组ID就是该进程的gid。对于进程组ID,一般来说,一个进程在shell下执行,shell程序就将该进程的PID赋给该进程的进程组ID,从该进程派生的子进程都拥有父进程所属的进程组ID,除非父进程将子进程的所属组ID设置成与该子进程的PID一样。由于这几个调用使用很简单,这里就不再举例。 3.2 setuid 和 setgid 系统调用 前面讲述了如何得到uid和gid,现在来看看如何设置它们。在讲述这两个调用以前我们先来看看对文件设置set_uid位会有什么作用。我们先编了一个小程序来做试验。这个程序的作用是,打印出进程的uid和euid,然后打开一个名为tty.c的文件。如果打不开,就显示错误代码;如果打开了,就显示打开成功。假设该程序名叫uid_test.c: /* uid_test.c */#include #include #include #include #include #include extern int errno; int main() { int fd; printf("This process's uid = %d, euid = %d ",getuid(),geteuid()); if ((fd = open("tty.c",O_RDONLY))==-1) { printf("Open error, errno is %d ",errno); exit(1); } else { printf("Open success "); } } 下面列出这几个文件的目录,可以看到文件tty.c的存取许可权仅为属主root可读写。 [wap@wapgw /tmp]$ ls -ltotal 3 -rw------- 1 root root 0 May 31 16:15 tty.c -rwxr-xr-x 1 root root 14121 May 31 16:15 uid_test -rw-r--r-- 1 root root 390 May 31 16:15 uid_test.c [wap@wapgw /tmp]$ 在该系统中的用户中个用户wap(500),以root用户身份执行程序: [root@wapgw /tmp]# ./uid_testThis process's uid = 0, euid = 0 Open success [root@wapgw /tmp]# 下面使用su命令,转到用户wap下,执行程序 [root@wapgw /tmp]#su wap[wap@wapgw /tmp]$ ./uid_test This process's uid = 500, euid = 500 Open error, errno is 13 [wap@wapgw /tmp]$ 这是由于进程的uid是500(wap),对文件tty.c没有存取权,所以出错。 给程序文件设置set-uid位 [root@wapgw /tmp]# chmod 4755 uid_test再转到用户wap下,执行程序uid_test。 [wap@wapgw /tmp]$ ./uid_testThis process's uid = 500, euid = 0 Open success [wap@wapgw /tmp]$ 从上面我们看到,进程打印出的euid是0(root),而运行该进程的用户是500(wap)。由于进程的euid是root,所以成功打开了文件tty.c。 上面的例子说明了两个事实:第一,内核对进程存取文件的许可权的检查,是通过检查进程的有效用户ID来实现的;第二,执行一个设置set_uid位的程序时,内核将进程表项中和u区中的有效用户ID设置为文件属主的ID。为了区别进程表项中的euid和u区中的euid,我们将进程表项中的euid域称为保存用户标识号(saved user ID)。 上一篇:Linux进程编程介绍(四) 下一篇:Linux进程编程介绍(二) 更多相关文章
|
推荐文章
精彩文章
|