2014-08-18 7 views
0

Мне нужно определить, изнутри программы на C++, можно ли записывать каталог в файловой системе Linux или нет. Мое первоначальное (наивное) решение состояло в том, чтобы открыть файл и попытаться записать его с помощью ofstream, но потоки не генерируют исключений (если вы не включите их).Определить, является ли каталог доступным для записи

Вот моя попытка №1. Обратите внимание, что /tmp/protectedstorage-test/mnt монтируется как только для чтения перед запуском тестового примера):

class create_test_file_failed {}; 

void create_test_file() { 
    std::ofstream os; 
    os.open("/tmp/protectedstorage-test/mnt/test_file", std::ofstream::out | std::ofstream::trunc); 
    if (os.fail()) 
     throw create_test_file_failed{}; 
    os << MAGIC_NUMBER; 
    os.close(); 
} 

bool not_writable_exception_check(std::exception const& ex) { 
    return true; 
} 

BOOST_FIXTURE_TEST_CASE (uninitialized_mirror_test) { 
    BOOST_CHECK_EXCEPTION(create_test_file, create_test_file_failed, not_writable_exception_check); 
} 

Однако os.fail(), кажется, всегда возвращает ложь. Я также пробовал os.bad() без успеха.

Итак, вот моя вторая попытка:

void create_test_file() { 
    std::ofstream os; 
    os.exceptions(std::ofstream::failbit | std::ofstream::badbit); 
    os.open("/tmp/protectedstorage-test/mnt/test_file", std::ofstream::out | std::ofstream::trunc); 
    os << MAGIC_NUMBER; 
    os.close(); 
} 

bool not_writable_exception_check(std::exception const& ex) { 
    return true; 
} 

BOOST_FIXTURE_TEST_CASE (uninitialized_mirror_test) { 
    BOOST_CHECK_EXCEPTION(create_test_file, std::exception, not_writable_exception_check); 
} 

Это приводит к следующему сообщению, когда я запускаю тест блока:

halfmirror_test.cpp(66): error in "uninitialized_mirror_test": exception std::exception is expected 

Если удалить макрос BOOST_CHECK_EXCEPTION и просто вызовите функцию , Я получил следующее сообщение, подразумевающее, что было сделано исключение из std::exception:

unknown location(0): fatal error in "uninitialized_mirror_test": std::exception: basic_ios::clear 

Поскольку basic_ios::clear является метод, а не тип, похоже, я должен ловить std::exception ...

Что здесь происходит? Почему не работает fail()? Какой тип бросается, поэтому я могу проверить, что его действительно бросают?

Я видел другие ответы, предполагающие, что проверка прав доступа к файлам является наилучшим способом для достижения этой цели, но эти разрешения действительно не говорят вам ничего о файловой системе только для чтения. Файл с возможностью записи разрешен в действительности отсутствует. в этом случае.

+0

Что произойдет, если вы проверяете 'неудачу()' после того, как вы пытались писать, а не только после того, как 'открытой()'? –

+1

Посмотрите пример кода на странице http://pubs.opengroup.org/onlinepubs/009695399/functions/stat.html. –

+0

Я уверен, что если вы монтируете файловую систему только для чтения, все файлы будут доступны только для чтения, независимо от разрешений при нормальной установке файловой системы. – dohashi

ответ

-2

stat - твой друг.

stat, fstat, lstat - get file status 

Если вы используете импульс, рассмотрим boost::filesystem

+0

+1 для boost :: filesystem – AndyG

+0

Я работаю над проверкой 'stat' будет делать то, что я хочу. Я использую 'boost :: filesystem' уже для других вещей. Имеет ли он возможность определить, что файл не может быть записан (хотя он имеет + w на нем)? – Steve

+0

@Steve Я достаточно уверен, что эффективные разрешения - это то, что сообщает stat/boost :: filesystem, а не разрешения файлов, когда диск установлен «нормально». boost :: filesystem имеет функцию «status», которая ведет себя так же, как stat. – dohashi

Смежные вопросы