Изучив ответы и комментарии, здесь и в Как разобраться в O_RDONLY = 0?, я собрал код ниже. Оттуда я получил следующую информацию о статусе дескриптора файла «слова» (я не хотел бы использовать термин «флаги», см. Примечание ниже, взятое из этот комментарий) и режим открытия файла < / em> s.
*** Flag O_RDONLY = 0 = 0 = x0000
*** Flag O_WRONLY = 1 = 1 = x0001
*** Flag O_RDWR = 2 = 10 = x0002
*** Flag O_CREAT = 64 = 1000000 = x0040
*** Flag O_TRUNC = 512 = 1000000000 = x0200
*** Flag O_APPEND = 1024 = 10000000000 = x0400
*** Flag O_WRONLY | O_CREAT | O_TRUNC = 577 = 1001000001 = x0241
*** Flag O_WRONLY | O_CREAT | O_APPEND = 1089 = 10001000001 = x0441
*** Flag O_RDWR | O_CREAT | O_TRUNC = 578 = 1001000010 = x0242
*** Flag O_RDWR | O_CREAT | O_APPEND = 1090 = 10001000010 = x0442
*** Mode r F_GETFL -> 32768 = 1000000000000000 = x8000
*** Mode w F_GETFL -> 32769 = 1000000000000001 = x8001
*** Mode a F_GETFL -> 33793 = 1000010000000001 = x8401
*** Mode r+ F_GETFL -> 32770 = 1000000000000010 = x8002
*** Mode w+ F_GETFL -> 32770 = 1000000000000010 = x8002
*** Mode a+ F_GETFL -> 33794 = 1000010000000010 = x8402
Числа в трех столбцах представлены в десятичном, двоичном и шестнадцатеричном формате. Искал "странный" x8000
, нашел в fcntl-linux.h
# ifdef __USE_GNU
...
# define AT_RECURSIVE 0x8000 /* Apply to the entire subtree. */
...
# endif
Таким образом, за исключением этого флага, присутствующего во всех режимах, ассоциация будет
r <-> O_RDONLY
w <-> O_WRONLY
a <-> O_WRONLY | O_APPEND
r+ <-> O_RDWR
w+ <-> O_RDWR
a+ <-> O_RDWR | O_APPEND
Это дает мне пару интригующих открытий:
Список не совпадает с таблицей, приведенной Тони Таннусом.
Слово для r+
такое же, как для w+
. Это ставит перед кодировщиком задачу относительно того, какой режим использовать с fdopen
, когда слово равно O_RDWR
(и r+
, и w+
подойдут). Согласно this, я ожидал, что w+
будет также O_CREAT
(как в таблице упомянутый выше). Я тоже ожидал, что w
получит это.
Чтобы написать полностью переносимый код, кажется, что всякий раз, когда используется fdopen
, нужно писать код, как я писал, чтобы автоматически находить mode ‹-> word соединения. (на самом деле, часть работы, которую я проделал, заключалась в ручной идентификации, и нужен дополнительный код).
РЕДАКТИРОВАТЬ. Пункты 1 и 2 в комментариях объясняются тем, что в таблице показано соответствие между режимами fopen
и флагами open
, то есть во время создания. Но то, что я получил с fcntl
, - это постоянные флаги после создания, а не те, которые использовались во время создания. Как также объяснялось здесь, O_CREAT
и O_TRUNC
относятся к категории флагов создания файлов < / em> и поэтому не являются постоянными. С другой стороны, O_APPEND
относится к категории флаги состояния файла и является постоянным. «Различие между этими двумя группами флагов состоит в том, что флаги создания файла влияют на семантику самой операции открытия, в то время как флаги состояния файла влияют на семантику последующих операций ввода / вывода. O операции ". [ref]
Примечание. справочная страница по открытому (2 ) сначала описывает режимы доступа к файлам, а затем добавляет: «Кроме того, ноль или более флагов создания файлов и флагов состояния файлов могут быть побитовыми или помещены в флаги ....» Но это (правильно) не упомяните, что режим доступа к файлам может быть побитовым. Для меня слово «флаг» является абсолютно неправильным и вводящим в заблуждение.
Код (можно использовать любую функцию
to_binary
для получения двоичной формы):
int main() {
const char fname[100] = "test.txt";
const char modes[][4] = { "r", "w", "a", "r+", "w+", "a+" };
const size_t nmodes = sizeof(modes) / sizeof(modes[0]);
const int flags[] = { O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_APPEND,
O_WRONLY | O_CREAT | O_TRUNC,
O_WRONLY | O_CREAT | O_APPEND,
O_RDWR | O_CREAT | O_TRUNC,
O_RDWR | O_CREAT | O_APPEND
};
const char flags_str[][100] = { "O_RDONLY", "O_WRONLY", "O_RDWR", "O_CREAT", "O_TRUNC", "O_APPEND",
"O_WRONLY | O_CREAT | O_TRUNC",
"O_WRONLY | O_CREAT | O_APPEND",
"O_RDWR | O_CREAT | O_TRUNC",
"O_RDWR | O_CREAT | O_APPEND"
};
const size_t nflags = sizeof(flags) / sizeof(flags[0]);
for (size_t iflag = 0 ; iflag < nflags ; iflag++) {
const int flag = flags[iflag];
const char * flag_str = flags_str[iflag];
char nbin[33];
to_binary(flag, nbin);
printf( "*** Flag %30s = %5d = %12s = x%04x\n", flag_str, flag, nbin, flag);
}
for (size_t imode = 0 ; imode < nmodes ; imode++) {
const char * mode = modes[imode];
FILE * fp1 = fopen(fname, mode);
int fd1 = fileno(fp1);
int retval = fcntl(fd1, F_GETFL);
char nbin[33];
to_binary(retval, nbin);
printf( "*** Mode %2s F_GETFL -> %5d = %12s = x%04x", mode, retval, nbin, retval);
fclose(fp1);
}
return 0;
}
person
sancho.s ReinstateMonicaCellio
schedule
21.05.2020
O_RDONLY
,O_WRONLY
иO_RDWR
. Если вы вернетесь к связанной ссылке, вы сможете понять, как это получить. А с помощью хорошейfopen
ссылки это не должно быть слишком сложно чтобы сопоставить их со строкой режимаfopen
(и действительноfdopen
). - person Some programmer dude   schedule 20.05.2020F_GETFL
, чтобы получить флаги, которые должны включать открытый режим (для выхода из которого может потребоваться побитовое маскирование). - person Some programmer dude   schedule 20.05.2020F_GETFL
и зная, что он включает открытый режим. Но я все еще не мог составить простые описательные списки, которые являются целью вопроса, и связи между ними. - person sancho.s ReinstateMonicaCellio   schedule 20.05.2020O_READ
- это"r"
.O_WRITE
равно"w"
или"a"
(в зависимости от того, где вы хотите записать в файл).O_RDWR
может быть любой другой строкой для чтения и записи, в зависимости от ваших потребностей. - person Some programmer dude   schedule 20.05.2020O_READ
, даже если я использую gcc и этот gnu.org/software/libc/manual/html_node/Access-Modes.html. И у меня естьO_ACCMODE
, вfcntl-linux.h
. - person sancho.s ReinstateMonicaCellio   schedule 20.05.2020O_RDONLY
иO_WRONLY
. - person Some programmer dude   schedule 20.05.2020