chdir改变当前目录以及理解守护进程为何fork()两次?
/* 父进程退出 */
if (fork() != 0)
{
exit(1);
}
if (setsid() < 0)
{
exit(1);
}
if (fork() != 0)
{
exit(1);
}
sprintf(app_dir_path, "%s/%s", WORK_DIR_PATH, APP_DIR_PATH);
if (chdir(app_dir_path) == -1)
{
printf("chdir %s failed,taskd exit!\n",app_dir_path);
exit(1);
}
为什么fork两次?
1进程组首进程不能调用setsid,会得到EPERM错误,这就是第一个fork的原因,执行第一个fork并让父进程退出,子进程继续,这时候由于子进程会继承其父进程的进程组GID并有自己的进程PID,而这个PID和GID肯定是不一样的。所子进程绝不可能成为进程组首进程,满足了调用setsid的条件。2调用setsid后所有到之前控制终端的连接都会断开。
最后,再执行一次fork,让子进程退出,孙进程继续。这样让孙进程pid不等于它所在的会话sid,这样它就不会自己变成会话首进程,也就使它不能打开控制终端。这样守护进程就得到了一个干净的环境,它不会被终端产生的信号干扰。
经过前面2个步骤,基本想要做的都做了。第2次fork不是必须的。也看到很多开源服务没有fork第二次。fork第二次主要目的是。防止进程再次打开一个控制终端。因为打开一个控制终端的前台条件是该进程必须是会话组长。再fork一次,子进程ID != sid(sid是进程父进程的sid)。所以也无法打开新的控制终端。
理解:此程序是守护进程的部分代码,
1、在实际应用中,代码需要从当前目录进到其它目录,完成操作,然后再回到当前目录。这个时候需要getcwd获取当前目录路径,保存起来,在使用chdir跳转到其它目录,然后再使用chdir和保存的路径回到最初的目录。
2、man chdir
3、int chdir(const char *path);
-参数*path;文件路径
-返回值;成功返回0,错误返回-1.
4、例:
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- //chdir和fchdir函数头文件
- #include <unistd.h>
- #define LENTH 255
- int main(int argc,char *argv[])
- {
- int ret;
- char pwd[LENTH];
- //检测参数
- if(argc <3){
- printf("\nPlease input file path\n");
- return 1;
- }
- //getcwd函数获取当前目录
- if(!getcwd(pwd,LENTH)){
- perror("getcwd");
- return 1;
- }
- printf("\ngetcwd pwd is %s\n",pwd);
- //使用chdir函数转入其他目录
- ret = chdir(argv[1]);
- if(ret){
- printf("Please make sure file path\n");
- return 1;
- }
- printf("chdir %s is success!\n",argv[1]);
- //转入其他目录,完成操作
- //使用rmdir函数删除目录
- ret = rmdir(argv[2]);
- if(ret<0){
- printf("rmdir %s failed!\n",argv[2]);
- return 1;
- }
- printf("rmdir %s is success!\n",argv[2]);
- //再次使用chdir回到pwd保存的目录
- ret = chdir(pwd);
- if(ret){
- printf("Please make sure file path\n");
- return 1;
- }
- printf("chdir %s is success!\n",pwd);
- return 0;
- }