|
|
ru.unix.bsd- RU.UNIX.BSD ------------------------------------------------------------------ From : Valentin Nechayev 2:5020/400 30 Jan 2004 12:00:42 To : Artem_'Zazoobr'_Ignatiev Subject : Re: MySQL-4.0.17 building warnings: ... -------------------------------------------------------------------------------- >>> Artem 'Zazoobr' Ignatiev wrote: >> Это признак открытого файлового объекта в памяти, а не дескриптора. >> Установка/снятие O_NONBLOCK через любой дескриптор воздействует на операции >> через любой из дескрипторов. Если ты подумал про то, что я говорю про объект >> в постоянной FS, то это не так. >> Признаки отдельных дескрипторов управляются через fcntl(,F_SETFD), >> сейчас такой признак только один - FD_CLOEXEC AZI> А? Чего? А тогда поясни, пожалуйста, вот это: AZI> The fcntl() system call provides for control over descriptors. *The AZI> argument fd is a descriptor to be operated on by cmd* as described AZI> below. Depending on the value of cmd, fcntl() can take an additional AZI> third argument int arg. AZI> ... AZI> F_SETFL Set descriptor status flags to arg. AZI> Что-то я тут не вижу фразы, по смыслу совпадающей с отквоченным. Вижу как AZI> раз наоборот. Или всё врут календари? Эти календари, похоже, врут. Или выражаются не теми словами, какими надо. SUS говорит "file status flags", а не "descriptor status flags". А истину даст RTFS, результаты которого идентичны по всем доступным системам и которую в стандартах надо долго и нудно выискивать по тонкостям формулировок. Далее - по FreeBSD 4.9: 1. В описании процесса (struct proc) - поле p_fd. Указывает на struct filedesc. Для каждого процесса она обычно своя, кроме rfork'нутых с явным указанием разделения структур. Для контроля при rfork'нутых - есть счётчик использований, при его обнулении структура удаляется и всё открытое в ней закрывается. 2. В struct filedesc такие поля: struct file **fd_ofiles; /* file structures for open files */ char *fd_ofileflags; /* per-process open file flags */ fcntl() с F_GETFD и F_SETFD управляет элементами массива fd_ofileflags и дальше не идёт: case F_GETFD: p->p_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0; return (0); case F_SETFD: *pop = (*pop &~ UF_EXCLOSE) | (uap->arg & FD_CLOEXEC ? UF_EXCLOSE : 0); return (0); (pop - был присвоен как pop = &fdp->fd_ofileflags[uap->fd]) 3. Из fd_ofiles идут ссылки на структуры типа struct file. F_GETFL, F_SETFL управляют полями в них. case F_GETFL: p->p_retval[0] = OFLAGS(fp->f_flag); return (0); Для F_SETFL там ещё добавлен переходник на установку async режимов, поэтому там код немного сложнее, но основной кусок тот же по сути: case F_SETFL: fp->f_flag &= ~FCNTLFLAGS; fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS; Эта struct file соответствует понятию "открытый файловый объект", полученный по open(), socket(), pipe() и так далее. Hа неё должна быть как минимум одна ссылка из открытых дескрипторов (то есть fd_ofiles в процессах). По fork(), по dup(), dup2(), fcntl(,F_DUPFD) дескрипторы размножаются, при этом в struct file счётчик использований (f_count) увеличивается; по закрытию дескриптора - уменьшается; по переходу в 0 - struct file закрывается и удаляется. Через struct file хранятся режимы доступа, текущая позиция и так далее, поэтому они общее на одно открытие файла; если надо держать две позиции одновременно, надо сделать два разных open(). Hаконец, внутри struct file просто ссылка на другой объект, уже конкретного типа (vnode, сокет и так далее), через которую делаются реальные действия над самим файлом: #define DTYPE_VNODE 1 /* file */ #define DTYPE_SOCKET 2 /* communications endpoint */ #define DTYPE_PIPE 3 /* pipe */ #define DTYPE_FIFO 4 /* fifo (named pipe) */ #define DTYPE_KQUEUE 5 /* event queue */ #define DTYPE_CRYPTO 6 /* crypto */ short f_type; /* descriptor type */ struct fileops *f_ops; caddr_t f_data; /* vnode or socket */ Тут f_data - указатель на объект реализации, ну и чтобы далеко не тянуться вынесены указатели на функции операций и - для удобства - тип открытого объекта. Все действия типа read, write, recv, send, fseek и так далее - уходят на выполнение в объект указанный в f_data через указание его в функции из f_ops. Hапример, read(): static __inline int fo_read(fp, uio, cred, flags, p) [...] error = (*fp->f_ops->fo_read)(fp, uio, cred, flags, p); [...] Открыть один сокет или безымянный пайп несколько раз нельзя; именованный пайп или файл - можно, поэтому у них в соответствующих структурах свои счётчики ссылок (из struct file и других мест использования). Отака х#$ня, малята ([Дiд Панас]) -netch- --- ifmail v.2.15dev5.2 * Origin: Dark side of coredump (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.unix.bsd/736813d4d7c8.html, оценка из 5, голосов 10
|