1. 日志函数 syslog
syslog
2. 用户信息
UID(真实用户ID) 与 EUID(有效用户ID)
- 为什么引入EUID(有效用户id)? 允许不同的用户以UID的权限运行改程序。设置
set-user-id
字段,任何用户启动该程序,其有效用户就是该程序的所有者
demo 切换用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
* 以root身份启动的进程切换为一个普通用户身份运行
*/
static bool switch_to_user( uid_t user_id, gid_t gp_id )
{
// 先确保目标用户不是root
if ( ( user_id == 0 ) && ( gp_id == 0 ) )
{
return false;
}
//确保当前用户是合法用户
gid_t gid = getgid();
uid_t uid = getuid();
if ( ( ( gid != 0 ) || ( uid != 0 ) ) && ( ( gid != gp_id ) || ( uid != user_id ) ) )
{
return false;
}
// 如果不是root 则已经是目标用户
if ( uid != 0 )
{
return true;
}
// 切换到目标用户
if ( ( setgid( gp_id ) < 0 ) || ( setuid( user_id ) < 0 ) )
{
return false;
}
return true;
}
3. 进程间的关系
进程组 Linux 下每个进程都属于一个进程组,因此除了
PID
信息外,还有进程组IDPGID
. 每个进程组都有一个首领进程,其PGID 与 PID 相同。进程组将一直存在,直到其中所有的进程都退出。 一个进程只能设置自己或其子进程的PGID。1 2
int setpgid(pid_t pid, pid_t pgid); // 设置pgid int gettpgid(pid_t pid, pid_t pgid); // 获得pgid
- 会话 脱离父进程。
pid_t setsid(void)
用于创建一个会话,该函数不能由进程组的首领进程调用- 调用的进程会成为会话的首领。
- PGID 就是调用进程的PID
用ps命令查看进程间关系
命令:
ps -o pid,ppid,pgid,sid,comm | less
1 2 3 4
PID PPID PGID SID COMMAND 824 24456 824 24456 ps 825 24456 824 24456 less 24456 24455 24456 24456 bash
4.系统资源限制
p120
1
2
int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);
5. 改变工作目录
1
2
char* getcwd(char *buf,size_t size); // 获取当前目录
chdir() // 改变工作目录
6. 服务器后台化
在代码中让一个进程以守护进程的方式运行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
bool daemonize(){
// 创建子进程 关闭父进程 这样可以使得程序在后台运行
pid_t pid = fork();
if (pid < 0)
return false;
else if (pid > 0)
exit(0);
// 设置文件权限掩码 一般配合create file 使用
umask(0);
// 新建会话 设置本进程为进程组的首领
pid_t sid = setsid();
// 切换工作目录
if ((chdir("/")) < 0){
return false;
}
// 关闭标准输入 标准输出 标准错误输出
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// 将标准输入 输出 error 重定向到 /dev/null 文件
open("/dev/null",O_RDONLY);
open("/dev/null",O_RDWR);
open("/dev/null",O_RDWR);
}