zoukankan      html  css  js  c++  java
  • APUE习题8.7

    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
    ");
    18     else
    19         printf("clsose-on-exec is off
    ");
    20 
    21     sprintf(buf,"%d",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
    ");
    13     else
    14         printf("clsose-on-exec is off
    ");
    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
    ");
         else
             printf("close-on-exec is off
    ");
    -    val &= ~FD_CLOEXEC;
    -    fcntl(fd,F_SETFD,val);
         sprintf(strfd,"%d",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的时候是会关闭打开的目录的。

  • 相关阅读:
    LeetCode 1245. Tree Diameter
    LeetCode 1152. Analyze User Website Visit Pattern
    LeetCode 1223. Dice Roll Simulation
    LeetCode 912. Sort an Array
    LeetCode 993. Cousins in Binary Tree
    LeetCode 1047. Remove All Adjacent Duplicates In String
    LeetCode 390. Elimination Game
    LeetCode 1209. Remove All Adjacent Duplicates in String II
    LeetCode 797. All Paths From Source to Target
    LeetCode 1029. Two City Scheduling
  • 原文地址:https://www.cnblogs.com/JesseEisen/p/3688513.html
Copyright © 2011-2022 走看看