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)。所以也无法打开新的控制终端。


(chdir(app_dir_path)  产生的此子进程或孙进程可能不在/home/app里面工作,需要重新更改工作目录



理解:此程序是守护进程的部分代码,


1、在实际应用中,代码需要从当前目录进到其它目录,完成操作,然后再回到当前目录。这个时候需要getcwd获取当前目录路径,保存起来,在使用chdir跳转到其它目录,然后再使用chdir和保存的路径回到最初的目录。


2、man chdir


3、int  chdir(const char *path);

   -参数*path;文件路径

   -返回值;成功返回0,错误返回-1.


4、例:

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <fcntl.h>  
  5. //chdir和fchdir函数头文件  
  6. #include <unistd.h>  
  7.   
  8. #define LENTH 255  
  9.   
  10. int main(int argc,char *argv[])  
  11. {  
  12.     int ret;  
  13.     char pwd[LENTH];  
  14.   
  15. //检测参数    
  16.     if(argc <3){  
  17.         printf("\nPlease input file path\n");  
  18.         return 1;  
  19.     }  
  20.       
  21. //getcwd函数获取当前目录          
  22.     if(!getcwd(pwd,LENTH)){  
  23.         perror("getcwd");  
  24.         return 1;  
  25.     }  
  26.     printf("\ngetcwd pwd is %s\n",pwd);  
  27.       
  28. //使用chdir函数转入其他目录  
  29.     ret = chdir(argv[1]);  
  30.     if(ret){  
  31.         printf("Please make sure file path\n");  
  32.         return 1;  
  33.     }  
  34.     printf("chdir %s is success!\n",argv[1]);  
  35.       
  36. //转入其他目录,完成操作  
  37. //使用rmdir函数删除目录  
  38.     ret = rmdir(argv[2]);  
  39.     if(ret<0){  
  40.         printf("rmdir %s failed!\n",argv[2]);  
  41.         return 1;  
  42.     }  
  43.     printf("rmdir %s is success!\n",argv[2]);  
  44.       
  45. //再次使用chdir回到pwd保存的目录  
  46.     ret = chdir(pwd);  
  47.     if(ret){  
  48.         printf("Please make sure file path\n");  
  49.         return 1;  
  50.     }  
  51.     printf("chdir %s is success!\n",pwd);  
  52.   
  53.     return 0;  
  54. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值