For the Open function O_cloexec mode, the FCNTL function fd_cloexec option is summarized as follows:
Calling the Open function O_cloexec mode opens a file descriptor that is closed in a new program that executes the exec call, and is an atomic operation.
Calling the Open function does not use the O_cloexec mode to open the file descriptor, and then calls the FCNTL function to set the FD_CLOEXEC option, the effect is the same as using the O_CLOEXEC option of the Open function, but calls the open, fcnt two L functions respectively, not atomic operations, There are race conditions in multi-threaded environment, so the Open function o_cloexec option is used instead.
Call the Open function o_cloexec the file descriptor opened by the mode, or use Fcntl to set the Fd_cloexec option, both of which are not closed in the child process resulting from the fork call.
The new file descriptor that is obtained by invoking the DUP race function clears the o_cloexec mode.
The test procedure is as follows:
#include <unistd.h>#include <sys/types.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#define ERR_SYS (FMT, arg ...) \ Do{printf (FMT, # #arg); printf"\nerrno:%d%s\n", errno, Strerror (errno)); Exit (exit_failure);} while(0)intMain () {intFD, Fd2, Val; pid_t pid;#ifdef _o_cloexecif (FD = open ("My.txt",O_rdwr|o_creat| O_cloexec,0600)) <0)#elseif (FD = open ("My.txt",O_rdwr| O_creat,0600)) <0)#endifErr_sys ("Open Error");#ifdef _dupif ((fd2 = DUP (FD)) <0) Err_sys ("DUP error"); if (Write (FD2,"123",3) <0) Err_sys ("Write error");#endif#ifdef _fcntl_cloexecif (val = fcntl (fd, F_GETFD)) <0) Err_sys ("Fcntl (F_GETFD) Error"); Val |= fd_cloexec; if (Fcntl (FD, F_SETFD, Val) <0) Err_sys ("Fcntl (F_SETFD) Error");#endif#ifndef _forkif (Execl ("/bin/sleep","Sleep","10000", (void*)0) <0) Err_sys ("Execl Error");#else Switch(PID = fork ())) { Case-1: Err_sys ("Fork Error"); Case 0: Sleep (10000); Break;default: Sleep (10000); Break; }#endif return 0;}
Compile into o_cloexec options with macro _o_cloexec
#gcc-D_O_CLOEXEC-o cloexec cloexec.c
Execute the program
#./cloexec
View process and process resources, note that the process name changes to sleep after executing execl
#ps Aux|grep SleepRoot7900 0.0 0.0 4200 280pts/0S+ One: $ 0:xx Sleep 10000Root7915 0.0 0.1 4384 836pts/1S+ One: the 0:xxgrep--color=autoSleep#lsof-P 7900COMMAND PID USER FD TYPE DEVICE size/off NODE NAMESleep 7900Root CWD DIR8,1 4096 163741/home/zozy/aupSleep 7900Root RTD DIR8,1 4096 2/Sleep 7900Root txt REG8,1 26156 131621/bin/SleepSleep 7900Root Mem REG8,1 2919792 A/usr/lib/locale/locale-archiveSleep 7900Root Mem REG8,1 1730024 15701/lib/i386-linux-gnu/libc-2.15. soSleep 7900Root Mem REG8,1 134344 15713/lib/i386-linux-gnu/LD-2.15. soSleep 7900Root0U CHR136,0 0T03/dev/pts/0Sleep 7900Root1U CHR136,0 0T03/dev/pts/0Sleep 7900Root2U CHR136,0 0T03/dev/pts/0
You can see that there are no files in the process resource My.txt
Compile with no macro _o_cloexec
#gcc -o nocloexec cloexec.c
Execute the program
#./nocloexec
View process and Process resources
#ps Aux|grep SleepRoot7925 0.0 0.0 4200 280pts/0S+ One:Wuyi 0:xx Sleep 10000Root7928 0.0 0.1 4384 836pts/1S+ One: the 0:xxgrep--color=autoSleep#lsof-P 7925COMMAND PID USER FD TYPE DEVICE size/off NODE NAMESleep 7925Root CWD DIR8,1 4096 163741/home/zozy/aupSleep 7925Root RTD DIR8,1 4096 2/Sleep 7925Root txt REG8,1 26156 131621/bin/SleepSleep 7925Root Mem REG8,1 2919792 A/usr/lib/locale/locale-archiveSleep 7925Root Mem REG8,1 1730024 15701/lib/i386-linux-gnu/libc-2.15. soSleep 7925Root Mem REG8,1 134344 15713/lib/i386-linux-gnu/LD-2.15. soSleep 7925Root0U CHR136,0 0T03/dev/pts/0Sleep 7925Root1U CHR136,0 0T03/dev/pts/0Sleep 7925Root2U CHR136,0 0T03/dev/pts/0Sleep 7925Root3U REG8,1 0 163759/home/zozy/aup/my. txt
You can see that there are files in the process resources my.txt
The test fcntl function can be set to compile the macro-d_fcntl_cloexec test, compile the test process as above, similarly, by turning on the-d_o_cloexec-d_fork compilation option to test the status of the descriptor in the child process using the O_cloexec mode, through the macro-d_ The DUP compilation option tests the effect of the DUP function on o_cloexec and compiles the test process slightly.
Analysis of open function o_cloexec mode and fcntl function fd_cloexec option