2016-06-17 2 views
1

Я проверяю флаги, отправленные на открытый вызов (2) против разрешений, которые я установил в некоторых метафайлах. Переменные здесь связаны с восьмеричными значениями, обычно отправляемыми на вызовы типа chmod. Я хочу, чтобы блок if был введен, когда perms не соответствует соответствующему флагу.Проверка только флага O_RDONLY для открытия (2)

if((perms == 4 && !(flags & O_RDONLY)) || 
    (perms == 2 && !(flags & O_WRONLY)) || 
    (perms == 6 && !(flags & O_RDWR))) 

Я ожидал, что это работает, и это делает очень хорошо в в O_WRONLY и O_RDWR. Однако фактическое значение O_RDONLY равно 0, поэтому оператор & вернет false для каждого значения. К сожалению, удаление отрицания приведет к нежелательному поведению каждого значения perms 4, пропускающего блок if. Как я могу достичь своей цели здесь?

+3

Используйте '((флаги и O_ACCMODE) == O_RDONLY)' и т.д. –

+0

Хотя 'flags' аргумент может содержать флаги, открытые режимы сами являются * не * флаги. –

+0

Флаги @JoachimPileborg здесь равны открытому системному аргументу 'int flags'. – FutureShocked

ответ

2

Первоначально, второй аргумент open был назван режимоми был зарегистрирован как 0, 1 или 2. Later on, аргумент был переименован в oflag, и теперь он может содержать флаги в дополнение к режиму доступа. Возможные значения для режима сохранялись одинаковыми, хотя для них были даны символические имена с осторожностью, что в отличие от флагов может использоваться только один из O_RDONLY, O_WRONLY и O_RDWR. POSIX standard включает в себя следующее определение:

Маска для использования с режимами доступа к файлу выглядит следующим образом:
O_ACCMODE Маска для режимов доступа к файлам.

Таким образом, вы можете использовать код, такой как ((flags&O_ACCMODE) == O_RDONLY) и т.д.

+0

Так что если '((flags & O_ACCMODE) == O_RDONLY' оценивается как true,' ((flags & O_ACCMODE) == O_RDWR' не может оценить true, правильно? Я запускаю экземпляры режима, оценивающего до 644, где текущий пользователь владелец, но strace показывает, что файлы открываются с помощью O_RDONLY. Я думал, что просто добавлю дополнительную логику, чтобы при обнаружении значения 6 для perms он также проверял RDONLY и WRONLY, но это кажется не только ленив, но вроде бы это может быть неприятно – FutureShocked

+1

Да, if (flags & O_ACCMODE) == O_RDONLY, тогда (flags & O_ACCMODE) не будет == O_RDWR. Если вам нужно сравнивать их более одного раза, может быть целесообразно преобразовать режим доступа в значение где вы можете протестировать отдельные биты, обозначающие доступ для чтения или записи. Ядро UNIX делает это - давным-давно, он должен принять аргумент mode (предположительно 0, 1 или 2) и просто добавить 1 к нему, а затем посмотреть на низкий уровень 2 бит результата. –

1

Использование

int open_mode = (flags & O_ACCMODE); 

Затем вы можете использовать чеки, как:

(open_mode == O_RDONLY) 
Смежные вопросы