process control
1 exec functions
#include <unistd.h>
extern char** environ;
int execl(const char* path, const char* arg, ...);
int execlp(const char* file, const char* arg, ...);
int execle(const char* path, const char* arg, ..., char* const envp[]);
int execv(const char* path, char* const argv[]);
int execvp(const char* file, char* const argv[]);
int execvpe(const char* file, char* const argv[], char* const envp[]);
int fexecve(int fd, char* const argv[], char* const envp[]);
系统调用exec是以新的程序代替原来的程序,替换了原来的代码段,数据段,堆,栈的内容。新程序从main函数开始执行。
没有创建新的进程,所以,替换前后进程ID保持不变。
这是一个函数簇,由以上列出的函数组成。
有的函数末尾是用命令行参数: 末尾可以使用NULL,(char*)0结尾。最好不要用0结尾,万一系统实现把0当成了参数,那么函数执行就失败了。
书上是说如果整型长度和char*长度不同,则会失败。而本机int-4, char*-8,但使用0结尾也可以运行。
有的是使用字符串数组:
程序用例:
// 将被调用的程序,写完后编译成test8.4
// g++ -o test8.4 test8.4.cc
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
extern char** environ;
for(int i = 0; i < argc; ++i)
printf("arg[%d]: %s \n", i, argv[i]);
printf("\nenviron: \n");
for(char** ptr = environ; *ptr != 0; ++ptr)
printf("%s \n", *ptr);
exit(EXIT_SUCCESS);
}
// 手动执行的程序, 使用execl,绝对路径
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
int main(int argc, char** argv)
{
pid_t pid = fork();
if(pid < 0)
{
printf("fork failed \n");
exit(EXIT_FAILURE);
}
if(pid == 0)
{
if(execl("/home/alex_my/Code/Apue/test8.4", "test8.4", "arg1", "arg2", NULL) < 0)
{
printf("child execlp failed, error[%d]: %s\n",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
}
waitpid(pid, NULL, 0);
exit(EXIT_SUCCESS);
}
输出:
arg[0]: test8.4
arg[1]: arg1
arg[2]: arg2
environ:
XDG_VTNR=1
SSH_AGENT_PID=2946
XDG_SESSION_ID=2
... ...
2 changing user IDs and Group IDs
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
上图(取自APUE)标记了在使用exec或者setuid函数时,对各种情况下三个ID的变化。
setuid:
-1: 如果是超级用户,则三个ID都会变成uid
-2: 如果是非超级用户,且该用户的uid与real user ID/saved set-user ID相同,则会把effective user ID设置为uid
exec:
与set-user-ID位是否关闭有关。
3 process time
#include <sys/times.h>
clock_t times(struct tms *buffer);
tms定义:
struct tms
{
clock_t tms_utime; /* user CPU time */
clock_t tms_stime; /* system CPU time */
clock_t tms_cutime; /* user CPU time, terminated children */
clock_t tms_cstime; /* system CPU time, terminated children */
};