APUE习题8.7

系统 1598 0

APUE习题8.7解答

APUE的8.7习题是关于exec的一个问题,书中描述了一句“POSIX.1明确要求再执行exec时关闭打开的目录流”。我们需要自己来验证下这个性质是否在自己的系统上有效,题目给我们提供了思路。

简单的分析下,我们首先需要打开一个目录,这个很简单,使用 opendir() 函数,我们现在获得是 DIR* 的变量,而我们要的是文件描述符fd,所以我们接着调用一个 dirfd() ,将获得目录的文件描述符。有了这些准备工作,我们就可以使用 fcntl()  获得执行时关闭状态(close-on-exec).

接着我们简单的判断一下此时这个状态是否打开的。这一步有利于我们接下来的判断。接着我们将这个fd写入到一个数组里面。用处在下面调用execl时最为参数使用。

我们创建一个进程,在子进程中我们调用execl函数,执行另一个程序,这个程序是利用刚才的描述符,尝试去在调用exec时候打开一个目录,看是否能打开。这就是这个程序的关键。

接着我们来尝试着code。
exercise8-7.c

      
         1
      
       #include<dirent> 
      
        /*
      
      
        opendir()
      
      
        */
      
      
         2
      
       #include<unistd.h> 
      
        /*
      
      
        execl(),fcntl()
      
      
        */
      
      
         3
      
       ...  
      
        /*
      
      
        一些必要的头文件
      
      
        */
      
      
         4
      
      
         5
      
      
        int
      
       main(
      
        void
      
      
        )


      
      
         6
      
      
        {


      
      
         7
      
           DIR *
      
        dir;


      
      
         8
      
      
        int
      
      
         val, fd;


      
      
         9
      
      
        char
      
       buf[
      
        10
      
      ]; 
      
        /*
      
      
        for save fd
      
      
        */
      
      
        10
      
      
        11
      
           dir = opendir(
      
        "
      
      
        /
      
      
        "
      
      
        );


      
      
        12
      
           fd =
      
         dirfd(dir);


      
      
        13
      
      
        14
      
      
        if
      
      ((val = fcntl(fd,F_GETFD,
      
        0
      
      )) < 
      
        0
      
      
        )


      
      
        15
      
               perror(
      
        "
      
      
        fcntl
      
      
        "
      
      
        );


      
      
        16
      
      
        if
      
      (val &
      
         FD_CLOEXEC)


      
      
        17
      
               printf(
      
        "
      
      
        close-on-exec is on\n
      
      
        "
      
      
        );


      
      
        18
      
      
        else
      
      
        19
      
               printf(
      
        "
      
      
        clsose-on-exec is off\n
      
      
        "
      
      
        );


      
      
        20
      
      
        21
      
           sprintf(buf,
      
        "
      
      
        %d\0
      
      
        "
      
      
        ,fd);


      
      
        22
      
      
        23
      
      
        if
      
      ((pid = fork()) < 
      
        0
      
      
        )


      
      
        24
      
               perror(
      
        "
      
      
        fork
      
      
        "
      
      
        );


      
      
        25
      
      
        else
      
      
        if
      
      (pid == 
      
        0
      
      
        )


      
      
        26
      
      
            {


      
      
        27
      
               execl(
      
        "
      
      
        /home/jesse/test/exercise8.7_child
      
      
        "
      
      ,
      
        "
      
      
        exercise8.7_child
      
      
        "
      
      
        ,buf,NULL);


      
      
        28
      
               exit(
      
        0
      
      
        );


      
      
        29
      
      
            }


      
      
        30
      
      
        31
      
      
        return
      
      
        0
      
      
        ;


      
      
        32
      
       }
    

 

    
      
         
      
    
  

上面就是我们的一个基本的框架,接着就是再exercise8.7_child.c中实现一个调用,这个就是很简单了。
exercise8.7_child.c

      
         1
      
       #include<fcntl.h>  
      
        /*
      
      
        fcntl()
      
      
        */
      
      
         2
      
       ...     
      
        /*
      
      
        一些必要的头文件
      
      
        */
      
      
         3
      
      
         4
      
      
        int
      
       main(
      
        int
      
       argc ,
      
        char
      
       *
      
        argv[])


      
      
         5
      
      
        {


      
      
         6
      
      
        int
      
      
         fd,val;


      
      
         7
      
      
         8
      
           sscanf(argv[
      
        1
      
      ], 
      
        "
      
      
        %d
      
      
        "
      
      , &
      
        fd);


      
      
         9
      
      
        if
      
      ((val = fcntl(fd,F_GETFD,
      
        0
      
      )) < 
      
        0
      
      
        )


      
      
        10
      
               perror(
      
        "
      
      
        fcntl
      
      
        "
      
      
        );


      
      
        11
      
      
        if
      
      (val &
      
         FD_CLOEXEC)


      
      
        12
      
               printf(
      
        "
      
      
        close-on-exec is on\n
      
      
        "
      
      
        );


      
      
        13
      
      
        else
      
      
        14
      
               printf(
      
        "
      
      
        clsose-on-exec is off\n
      
      
        "
      
      
        );


      
      
        15
      
      
        return
      
      
        0
      
      
        ;


      
      
        16
      
       }
    
    
      
         
      
    
  

我们执行一下

      
        1
      
       jesse@jesse:~/APUE/process$ ./a.
      
        out
      
      
        2
      
       close-on-exec 
      
        is
      
      
         on


      
      
        3
      
       jesse@jesse:~/APUE/process$ fcntl: Bad file descriptor
    
    
       
    
  

我们会发现,fcntl报错了。说明这个fd不存在,也就是验证了这个确实是在执行exec的时候,将文件描述符关闭了。

我们可以再延伸一些,我们试着将这个标志位关闭,看看结果如何,我们猜想应该是会显示“close-on-exec is off"

我们使用diff,看看哪儿需要更改

      jesse@jesse:~/APUE/process$ diff -u exercise8.
      
        7
      
      
        .c exercise8.7_child.c 


      
      --- exercise8.
      
        7
      
      .c    
      
        2014
      
      -
      
        04
      
      -
      
        25
      
      
        10
      
      :
      
        57
      
      :
      
        23.004544016
      
       +
      
        0800
      
      

+++ exercise8.7_child.c    
      
        2014
      
      -
      
        04
      
      -
      
        25
      
      
        11
      
      :
      
        11
      
      :
      
        14.064562979
      
       +
      
        0800
      
      
        

@@ 
      
      -
      
        19
      
      ,
      
        8
      
       +
      
        19
      
      ,
      
        6
      
      
         @@

         printf(
      
      
        "
      
      
        close-on-exec is on\n
      
      
        "
      
      
        );

     
      
      
        else
      
      
        

         printf(
      
      
        "
      
      
        close-on-exec is off\n
      
      
        "
      
      
        );


      
      -    val &= ~
      
        FD_CLOEXEC;


      
      -
      
            fcntl(fd,F_SETFD,val);

     sprintf(strfd,
      
      
        "
      
      
        %d\0
      
      
        "
      
      
        ,fd);



     
      
      
        if
      
      ((pid = fork()) < 
      
        0
      
      )
    
    
       
    
  

更改的就两行,利用F_SETFD,来实现的。

执行的结果

      
        1
      
       jesse@jesse:~/APUE/process$ ./a.
      
        out
      
      
        2
      
       close-on-exec 
      
        is
      
      
         on


      
      
        3
      
       jesse@jesse:~/APUE/process$ close-on-exec 
      
        is
      
       off
    

 

结果符合猜想。

系统默认的是保持FD_CLOEXEC这个标志打开的,也就是说执行exec的时候是会关闭打开的目录的。

APUE习题8.7


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论