首页 > 代码库 > 《unix环境高级编程》 读书笔记 (8)

《unix环境高级编程》 读书笔记 (8)

目录: http://blog.csdn.net/alex_my/article/details/39346381

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 */
};








《unix环境高级编程》 读书笔记 (8)