본문 바로가기

Programming/Linux_Platform

close_on_exec

static __inline__ int  adb_socketpair( int  sv[2] )

{

    int  rc;


    rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );

    if (rc < 0)

        return -1;


    close_on_exec( sv[0] );

    close_on_exec( sv[1] );

    return 0;

}


static __inline__ void  close_on_exec(int  fd)

{

    fcntl( fd, F_SETFD, FD_CLOEXEC );

}


#include <unistd.h>int

        execve(const char *filename, char *const argv[],
                  char *const envp[]);

함수를 호출하면 기본적으로는 file descriptor 가 open 된 상태로 있지만,

FD 에 FD_CLOEXEC 를 set 하면, close 된다고 한다.

정리하자면 exec 를 호출하면 프로세스가 전환되는데 이때 exec 를 호출한 프로세스쪽에서의 file descriptor 를 자동으로 close 하게 해주는 것이다.


이글을 포스팅 한지 오랜시간이 지나, 그디어 그 이유를 알게 되었다.

-> 

open 된 socket 역시 file descriptor 의 일종이다. process 가 fork 될때 부모 process 의 open 된 fd 를 상속받는다. 하지만 어떤 fd 들을 fork 된 자식 process 가 그대로 open 된 fd 를 상속하지 않기를 원할 수 있다.

그때 사용하는 것이 바로 FD_CLOEXEC 옵션이다.

특히, android sepolicy 권한의 경우 각 process 마다 access 권한을 가지게 되는데, 자식 process 라고해서 부모 process 의 권한을 다 가지지 않는다. 따라서, 부모에게 접근이 혀용된 file 의 fd 를 그대로 상속했다가는, 접근위반으로 kill 될 수 있다.







참조 : http://man7.org/linux/man-pages/man2/execve.2.html


아래 댓글에 따르면, child process 들 에서 exec* 계열 함수를 성공하면 자동으로 file descriptor 를 close 해 주기 때문에 자원의 낭비를 줄일 수 있고, 해당 file descriptor 가 valid 한 것을 check 해서, 현재 상태를 알 수 있다고 한다.


It marks the file descriptor so that it will be close()d automatically when the process or any children it fork()s calls one of the exec*() family of functions. This is useful to keep from leaking your file descriptors to random programs run by e.g. system()


-------


It will allow the OS to automatically close the file descriptor if any other process to execute the file you open(the file your fd is referring to). This is more useful when you writing any scripts and in multi-threaded programming environments.

http://stackoverflow.com/questions/6125068/what-does-the-fd-cloexec-fcntl-flag-do



아래 설명이 근본적인 이유인것 같은데..

http://man7.org/linux/man-pages/man2/open.2.html

 

O_CLOEXEC (since Linux 2.6.23)
              Enable the close-on-exec flag for the new file descriptor.
              Specifying this flag permits a program to avoid additional
              fcntl(2) F_SETFD operations to set the FD_CLOEXEC flag.

              Note that the use of this flag is essential in some
              multithreaded programs, because using a separate fcntl(2)
              F_SETFD operation to set the FD_CLOEXEC flag does not suffice
              to avoid race conditions where one thread opens a file
              descriptor and attempts to set its close-on-exec flag using
              fcntl(2) at the same time as another thread does a fork(2)
              plus execve(2).  Depending on the order of execution, the race
              may lead to the file descriptor returned by open() being
              unintentionally leaked to the program executed by the child
              process created by fork(2).  (This kind of race is in
              principle possible for any system call that creates a file
              descriptor whose close-on-exec flag should be set, and various
              other Linux system calls provide an equivalent of the
              O_CLOEXEC flag to deal with this problem.)






'Programming > Linux_Platform' 카테고리의 다른 글

헷갈리는 c string 함수들  (0) 2015.10.19
epoll 에 대한 한국어 설명  (0) 2015.10.19
socketpair()  (0) 2015.10.19
linux signals  (0) 2015.10.19
linux stand out 을 file 에 logging 하기  (0) 2015.10.19