Главная страница


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)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Re: MySQL-4.0.17 building warnings: ...   Valentin Nechayev   30 Jan 2004 12:00:42 
Архивное /ru.unix.bsd/736813d4d7c8.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional