2013-08-19 2 views
11

Я пытаюсь установить флаг O_CLOEXEC, используя open(), и не имеет никакого успеха.open() не установлен флаг O_CLOEXEC

Рассмотрим следующий Микротест:

#include <stdio.h> 
#include <fcntl.h> 

int main() { 
    int fd = open("test.c", O_RDONLY | O_CLOEXEC); 
    int ret = fcntl(fd, F_GETFL); 
    if(ret & O_CLOEXEC) { 
    printf("OK!\n"); 
    } else { 
    printf("FAIL!\n"); 
    } 
    printf("fd = %d\n", fd); 
    printf("ret = %x, O_CLOEXEC = %x\n", ret, O_CLOEXEC); 
    return 0; 
} 

При работе в Linux с ядром версии 2.6 тест преуспевает и печатает, но терпит неудачу с 3.8 или 3.9 ядрами «OK!».

Что случилось? Спасибо!

+0

ядра 3.8.0-22-на –

+0

уведомление о том, что флаг может быть правдой еще до поддержки O_CLOEXEC в 2.6.38 –

ответ

12

Было решено, что разоблачение O_CLOEXEC флага fcntl(fd, F_GETFL) герметично безопасность. Изменение было сделано this commit в ядре 3.6-RC7:

commit c6f3d81115989e274c42a852222b80d2e14ced6f 
Author: Al Viro <[email protected]> 
Date: Sun Aug 26 11:01:04 2012 -0400 

don't leak O_CLOEXEC into ->f_flags 

Signed-off-by: Al Viro <[email protected]> 

Другими словами, вы не должны полагаться на O_CLOEXEC быть видны в первую очередь.

2

Параметр вызова fcntl F_GETFD, флаг FD_CLOEXEC и поддержка O_CLOEXEC появилась в 2.6. 23. Прочитайте руководство:

File descriptor flags 
    The following commands manipulate the flags associated with a file descriptor. 
    Currently, only one such flag is defined: FD_CLOEXEC, the close-on-exec flag. 
    If the FD_CLOEXEC bit is 0, the file descriptor will remain open across an 
    execve(2), otherwise it will be closed. 

    F_GETFD (void) 
      Read the file descriptor flags; arg is ignored. 

    F_SETFD (int) 
      Set the file descriptor flags to the value specified by arg. 
+0

OP сказал он преуспевает в ядре 2.6, но не на 3,8/3.9 –

+1

Тест не работает при работе на ядре 3.8, который явно поддерживает O_CLOEXEC. Пожалуйста, прочитайте вопрос. –

+1

Этот ответ верен, поскольку метод * right * для получения статуса CLOEXEC заключается в использовании 'F_GETFD' и теста для' FD_CLOEXEC', поскольку 'CLOEXEC' является флагом, который применяется к каждому файловому дескриптору, а не к базовому открыть файл. Это не объясняет, почему ABI для 'F_GETFL', очевидно, изменилось. – caf

0

Вы делаете это неправильно. Вы должны делать по этому пути:

int ret = fcntl(fd, F_GETFD); 
if (ret & FD_CLOEXEC) { 
... 
}