【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 进程资源及属性

 

【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 进程资源及属性

 

进程资源:

进程资源由两部分组成:内核空间进程资源和用户空间进程资源。

内核空间进程资源即进程控制块(PCB)相关的信息。

包括进程控制块本身、打开的文件表项、当前目录、当前终端信息、线程基本信息、可访问内存地址空间、PID、PPID、UID、EUID等。也就是说,内核通过PCB可以访问到该进程所有的资源。这些资源只能通过系统调用才能访问。这一资源在当前进程退出时,只能由另一进程来回收。

用户空间进程资源包括通过成员mm_struct映射的内存空间。

实质就是进程的代码段、数据段、堆、栈,以及可以共享访问的内存空间。这些资源进程可以直接访问。这些资源在进程退出时主动释放。在进程运行时,可以通过文件/proc/{pid}/maps来查看可以访问的地址空间。

 

进程状态:

 

进程基本属性:

 与进程本身相关的属性包括进程号(PID)、父进程号(PPID)、进程组号(PGID)。

进程号:获取函数getpid(),在/usr/include/unistd.h中声明。返回值类型为pid_t, 成功返回当前进程的PID,失败返回-1,错误原因存储在error中。pid_t类型其实就是int类型的typedef,重新定义数据类型有助于提高代码的可阅读性。

父进程号:获取函数为getppid(), 成功返回当前进程的父进程号(PPID),其他与getpid()类似。

进程组号:获取函数getpgid(pid_t pid),用来获取指定进程的进程组号(PGID),如果参数为0,表示获取当前进程组号。其他与getpid()类似。也可以用getpgrp()来获取当前进程的进程组号。

系统调用函数setpgid(pid_t pid,pid_t pgid)用来将某进程加入到某个进程组。

会话:是一个或多个进程的集合。getsid(pid_t pid)用来获取某个进程的会话号SID。函数setsid()用来创建新会话。

控制终端:函数tcgetpgrp(int filedes)获取当前前台进程组的进程组号。函数tcsetpgrp(int filedes, pid_t pgrpid)设置某个进程是前台还是后台进程。函数tcgetsid(int filedes)获取控制终端的会话首进程的会话ID。、

示例程序代码(取自《Linux高级程序设计》):

/*************************************************************************
	> File Name: pg_test.c
	> Author: Geng
	> Mail: genglut@163.com
	> Created Time: Thu 30 Oct 2014 06:16:08 PM CST
 ************************************************************************/

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>

int main()
{
	int fd;
	pid_t pid;
	pid = fork();
	if(pid == -1)
		perror("fork");
	else if(pid > 0)
	{
		wait(NULL);
		exit(EXIT_FAILURE);
	}
	else 
	{
		if((fd = open("/dev/pts/0", O_RDWR)) == -1)
			perror("fopen");
		
		printf("pid=%d, ppid=%d\n", getpid(), getppid());
		printf("sid=%d, tcgetsid=%d\n", getsid(getpid()), tcgetsid(fd));
		printf("tcgetpgrp=%d\n", tcgetpgrp(fd));
		printf("pigd=%d\n", getpgid(getpid()));
	}
}


运行程序:

yang@ubuntu:~/temp$ ps
  PID TTY          TIME CMD
 3198 pts/0    00:00:02 bash
 4318 pts/0    00:00:00 ps
yang@ubuntu:~/temp$ ./pg_test 
pid=4320, ppid=4319
sid=3198, tcgetsid=3198
tcgetpgrp=4319
pigd=4319

关于进程组、会话和控制终端的文章链接:

http://www.2cto.com/os/201302/191922.html

http://blog.csdn.net/kankan231/article/details/23838711

http://blog.csdn.net/daniel_h1986/article/details/6067685

http://shake863.iteye.com/blog/187085

 

进程用户属性: 

进程真实用户号(RUID) 获取函数:getuid()
真实用户组号(RGID) 获取函数:getgid()
有效用户号(EUID)  获取函数:geteuid()
有效用户组号(EGID)  获取函数:getegid()

其他相关函数:

getresuid(&ruid, &euid, &suid);
getresgid(&rgid, &egid, &sgid);

普通用户能够修改自己的密码的原因:

/etc/passwd文件用来存储所有用户信息,任何用户都可以修改自己的密码,显然,其它用户在执行/usr/bin/passwd命令时修改了/etc/passwd文件(并不是说可以使用vi编辑器修改),但是,通过查看/etc/passwd文件的权限,发现普通用户对此文件仅有读的权限。是什么原因导致普通用户可以修改/etc/passwd文件呢?
这是因为用户执行“/usr/bin/passwd”命令时,/usr/bin/passwd文件设置了setuid位,在执行此程序(/usr/bin/passwd)时,该用户所拥有的权限等同于文件“/usr/bin/passwd”的拥有者root的权限,而root用户拥有对/ect/passwd文件写的权限,因此普通用户可以通过/usr/bin/passwd来修改/etc/passwd文件的内容。
如果清除掉“/usr/bin/passwd”文件的setuid权限位,普通用户就不能修改自己的密码了。

示例代码:

/*************************************************************************
	> File Name: getid_example.c
	> Author: Geng
	> Mail: genglut@163.com
	> Created Time: Thu 30 Oct 2014 09:33:00 PM CST
 ************************************************************************/

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main(int argc, char *argv[])
{
	int pid;

	printf("\tuid\tgid\teuid\tegid\n");
	printf("parent\t%d\t%d\t%d\t%d\n", getuid(), getgid(), geteuid(), getegid());
	int ruid, euid, suid;
	int rgid, egid, sgid;
	getresuid(&ruid, &euid, &suid);
	printf("\truid\teuid\tsuid\n");
	printf("\t%d\t%d\t%d\n", ruid, euid, suid);

	getresgid(&rgid, &egid, &sgid);
	printf("\trgid\tegid\tsgid\n");
	printf("\t%d\t%d\t%d\n", rgid, egid, sgid);
	
	if((pid = fork()) < 0)
	{
		perror("fork");
		exit(EXIT_FAILURE);
	}
	else if(pid > 0)
	{
		sleep(1);
	}
	else if(pid == 0)
	{
		printf("child\t%d\t%d\t%d\t%d\n", getuid(), getgid(), geteuid(), getegid());
		getresuid(&ruid, &euid, &suid);
		printf("\truid\teuid\tsuid\n");
		printf("\t%d\t%d\t%d\n", ruid, euid, suid);
	
		getresgid(&rgid, &egid, &sgid);
		printf("\trgid\tegid\tsgid\n");
		printf("\t%d\t%d\t%d\n", rgid, egid, sgid);
	}


	return 0;
}


关于进程的实际用户ID和有效用户ID的文章链接:

http://www.cnblogs.com/kunhu/p/3699883.html

linux:SUID、SGID详解:

http://www.cnblogs.com/fhefh/archive/2011/09/20/2182155.html

 

 

原文链接:http://blog.csdn.net/geng823/article/details/40624497

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值