Если вы перечислите все свойства window.navigator
, используя
console.log(navigator);
, вы увидите что-то вроде этого
# platform = Win32
# appCodeName = Mozilla
# appName = Netscape
# appVersion = 5.0 (Windows; en-US)
# language = en-US
# mimeTypes = [object MimeTypeArray]
# oscpu = Windows NT 5.1
# vendor = Firefox
# vendorSub = 1.0.7
# product = Gecko
# productSub = 20050915
# plugins = [object PluginArray]
# securityPolicy =
# userAgent = Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7
# cookieEnabled = true
# javaEnabled = function javaEnabled() { [native code] }
# taintEnabled = function taintEnabled() { [native code] }
# preference = function preference() { [native code] }
. Обратите внимание, что атрибут oscpu
дает вам версии Windows. Кроме того, вы должны знать, что:
'Windows 3.11' => 'Win16',
'Windows 95' => '(Windows 95)|(Win95)|(Windows_95)',
'Windows 98' => '(Windows 98)|(Win98)',
'Windows 2000' => '(Windows NT 5.0)|(Windows 2000)',
'Windows XP' => '(Windows NT 5.1)|(Windows XP)',
'Windows Server 2003' => '(Windows NT 5.2)',
'Windows Vista' => '(Windows NT 6.0)',
'Windows 7' => '(Windows NT 6.1)',
'Windows 8' => '(Windows NT 6.2)|(WOW64)',
'Windows 10' => '(Windows 10.0)|(Windows NT 10.0)',
'Windows NT 4.0' => '(Windows NT 4.0)|(WinNT4.0)|(WinNT)|(Windows NT)',
'Windows ME' => 'Windows ME',
'Open BSD' => 'OpenBSD',
'Sun OS' => 'SunOS',
'Linux' => '(Linux)|(X11)',
'Mac OS' => '(Mac_PowerPC)|(Macintosh)',
'QNX' => 'QNX',
'BeOS' => 'BeOS',
'OS/2' => 'OS/2',
'Search Bot'=>'(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves/Teoma)|(ia_archiver)'
echo "Hi All" | tr "[:upper:]" "[:lower:]"
-121--1757343- Отсутствует указатель функции .open
в структуре file _ operations
для указания функции, вызываемой при попытке процесса открыть файл устройства. Необходимо также указать указатель функции .ioctl
для функции ioctl.
Попробуйте прочитать Руководство по программированию модуля ядра Linux , в частности главы 4 (Символьные файлы устройств) и 7 (Разговор с файлами устройств).
Глава 4 описывает структуру file _ operations
, которая содержит указатели на определенные модулем/драйвером функции, выполняющие различные операции, такие как open
или ioctl
.
Глава 7 содержит информацию о взаимодействии с модулем/диском через ioctls.
Драйверы устройств Linux, третье издание - еще один хороший ресурс.
-121--2664688- Необходимый Вам пример кода можно найти в drivers/watchdog/softdog.c
(из Linux 2,6,33 на момент написания), который иллюстрирует правильные операции с файлами, а также как разрешить пользователю заполнять структуру ioctl ().
На самом деле это отличный рабочий учебник для всех, кому нужно писать тривиальные драйверы устройств.
При ответе на мой собственный вопрос , который может быть вам полезен, я проанализировал ioctl-интерфейс софтдога.
Вот суть этого (хотя и далеко не исчерпывающая)...
В softdog _ ioctl ()
вы видите простую инициализацию watchdog_info структуры, которая рекламирует функциональность, версию и информацию об устройстве:
static const struct watchdog_info ident = {
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
.firmware_version = 0,
.identity = "Software Watchdog",
};
Мы рассмотрим простой случай, когда пользователь просто хочет получить эти возможности:
switch (cmd) {
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
... который, конечно, заполнит соответствующий watchdog_info пользовательского пространства инициализированными значениями выше. Если ошибка copy_to_user (), возвращается -EFAULT, что приводит к тому, что соответствующий вызов userspace ioctl () возвращает -1 со значимым устанавливать errno.
Обратите внимание, что магические запросы фактически определены в linux/watchdog.h, так что ядро и пользовательское пространство разделяют их:
#define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
#define WDIOC_GETSTATUS _IOR(WATCHDOG_IOCTL_BASE, 1, int)
#define WDIOC_GETBOOTSTATUS _IOR(WATCHDOG_IOCTL_BASE, 2, int)
#define WDIOC_GETTEMP _IOR(WATCHDOG_IOCTL_BASE, 3, int)
#define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int)
#define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int)
#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int)
#define WDIOC_SETPRETIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 8, int)
#define WDIOC_GETPRETIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 9, int)
#define WDIOC_GETTIMELEFT _IOR(WATCHDOG_IOCTL_BASE, 10, int)
WDIOC, очевидно, означает «Watchdog ioctl»
Вы можете легко сделать это шаг дальше, имея ваш драйвер сделать что-то и поместить результат этого в структуру и скопировать его в пользовательское пространство. Например, если структура watchdog_info также имела члена __ u32 result_code
. Обратите внимание, что __ u32
является только версией ядра uint32 _ t
.
С помощью ioctl () пользователь передает адрес объекта, будь то структура, целое число, в ядро, ожидающее, что ядро запишет свой ответ в идентичный объект и скопирует результаты на предоставленный адрес.
Второе, что вам нужно сделать, это убедиться, что ваше устройство знает, что делать, когда кто-то открывает, читает с него, пишет на него или использует крючок, как ioctl (), который вы можете легко увидеть, изучая программное обеспечение.
Интерес представляют:
static const struct file_operations softdog_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = softdog_write,
.unlocked_ioctl = softdog_ioctl,
.open = softdog_open,
.release = softdog_release,
};
Где вы видите обработчик unlocked_ioctl... вы догадались, softdog_ioctl ().
Я думаю, что вы можете сопоставить уровень сложности, который действительно не существует при работе с ioctl (), это действительно так просто. По этой же причине большинство разработчиков ядра хмурятся над новыми интерфейсами ioctl, добавляемыми, если они не являются абсолютно необходимыми. Его слишком легко потерять трек типа, который ioctl () собирается заполнить против магии вы используете, чтобы сделать это, что является основной причиной, что copy_to_user () терпит неудачу, часто приводя к гниение ядра с полчищами процессов userspace застряли в дисковый сон.
Для таймера, я согласен, ioctl () является кратчайшим путем к здравомыслию.
В структуре file_operations
отсутствует указатель на функцию .open
для указания функции, которая будет вызываться при процесс пытается открыть файл устройства. Вам также нужно будет указать указатель на функцию .ioctl
для вашей функции ioctl.
Попробуйте прочитать Руководство по программированию модуля ядра Linux , особенно главы 4 (Файлы символьных устройств) и 7 (Обращение к файлам устройств).
Глава 4 представляет структуру file_operations
, которая содержит указатели на функции, определенные модулем / драйвером, которые выполняют различные операции, такие как open
или ioctl
].
Глава 7 предоставляет информацию о связи с модулем / приводом через ioctls.
Драйверы устройств Linux, третье издание - еще один хороший ресурс.