Sysfsの理解とlibudevの浅い分析(四)--第二層の精髄
5749 ワード
まだ見ていないで、私が望んでいる実現の精髄だと思って、理解してどのように獲得するかを知っています.
dev = udev_device_new_from_syspath( ,/sys/class/input/event0)
strrchr()関数は、指定した文字列の最後に表示される文字の位置を検索します.
ここで疑いますが、伝わってきたのは/sys/class/input/event 0/かもしれません.
判断条件により、転送されたのは/sys/class/input/event 0で、'/'を受けません.
util_resolve_sys_link(udev, path, sizeof(path));リンクシンボルファイルを解決し、実際のパスファイルを得る
event0 -> ../../devices/LNXSYSTM:00/LNXPWRBN:00/input/input0/event0
すなわち/sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input 0/event 0が得られ、udevまたはその例を見て印刷されたのが/devices/LNXSYSTM:00/LNXPWRBN:00/input/input 0/event 0のような形式である.
「/devices/」が含まれている場合は、続行し、
/sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input 0/event 0/uevent、各デバイスにueventがあるので、存在するか否かを判断します.
存在、OK、udevを作成デバイス、pathを追加
udev_device_set_syspath(udev_device, /sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input0/event0);
注意して、ここはset_ですsyspath.
これで終わりですが、まだ/devの下に関連するものはありません.难しくて私が漏らしたのですか???
では、次に/devの下のnodeをどのように手に入れたかを見てみましょう.
node = udev_device_get_devnode(device);
/** * udev_device_get_devnode: * @udev_device: udev device * * Retrieve the device node file name belonging to the udev device. * The path is an absolute path, and starts with the device directory. * * Returns: the device node file name of the udev device, or #NULL if no device node exists **/UDEV_EXPORT const char *udev_device_get_devnode(struct udev_device *udev_device) { if (udev_device == NULL) return NULL; if (!udev_device->info_loaded) { udev_device_read_uevent_file(udev_device); udev_device_read_db(udev_device, NULL); }/* we might get called before we handled an event and have a db, use the kernel-provided name */if (udev_device->devnode == NULL && udev_device_get_knodename(udev_device) != NULL) { char filename[UTIL_NAME_SIZE]; util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", udev_device_get_knodename(udev_device), NULL); udev_device_set_devnode(udev_device, filename); return udev_device->devnode; } return udev_device->devnode; }
ここではueventファイル、dbファイルを読み込みます.これは何ですか
devnodeはdevpath+'/'+knodenameであることがわかります.
devpathおよびknodename
int udev_device_read_uevent_file(struct udev_device *udev_device) { char filename[UTIL_PATH_SIZE]; FILE *f; char line[UTIL_LINE_SIZE]; int maj = 0; int min = 0; if (udev_device->uevent_loaded) return 0; util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL); f = fopen(filename, "re"); if (f == NULL) return -1; udev_device->uevent_loaded = true; while (fgets(line, sizeof(line), f)) { char *pos; pos = strchr(line, ''); if (pos == NULL) continue; pos[0] = '\0'; if (strncmp(line, "DEVTYPE=", 8) == 0) udev_device_set_devtype(udev_device, &line[8]); else if (strncmp(line, "MAJOR=", 6) == 0) maj = strtoull(&line[6], NULL, 10); else if (strncmp(line, "MINOR=", 6) == 0) min = strtoull(&line[6], NULL, 10); else if (strncmp(line, "IFINDEX=", 8) == 0) udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10)); else if (strncmp(line, "DEVNAME=", 8) == 0) udev_device_set_knodename(udev_device, &line[8]); else if (strncmp(line, "DEVMODE=", 8) == 0) udev_device->devnode_mode = strtoul(&line[8], NULL, 8); udev_device_add_property_from_string(udev_device, line); } udev_device->devnum = makedev(maj, min); fclose(f); return 0; }
先に得られた経路付きueventから読み出されていることがわかります
[root@localhostevent 0]#cat uevent MAJOR=13 MINOR=64 DEVNAME=input/event 0 DEVNAMEをknodenameに設定します.
devpathの場合、初期化時のデフォルトは/devです.
/* set defaults */if (udev->dev_path == NULL) if (set_value(&udev->dev_path, "/dev") == NULL) goto err;
したがってdevnode,/dev/input/event 0が得られた.MAJORとMINORは何(キーボード、マウス、タッチデバイス)かを判断するのに使えますか?
次の質問は、/dev/input/event 0がマウスなのかキーボードなのか、タッチスクリーンなのかを判断する方法です.
dev = udev_device_new_from_syspath( ,/sys/class/input/event0)
<span style="font-size:14px;">UDEV_EXPORT struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath)
{
size_t len;
const char *subdir;
char path[UTIL_PATH_SIZE];
char *pos;
struct stat statbuf;
struct udev_device *udev_device;
if (udev == NULL)
return NULL;
if (syspath == NULL)
return NULL;
/* path starts in sys */
len = strlen(udev_get_sys_path(udev));
if (strncmp(syspath, udev_get_sys_path(udev), len) != 0) {
info(udev, "not in sys :%s
", syspath);
return NULL;
}
/* path is not a root directory */
subdir = &syspath[len+1];
pos = strrchr(subdir, '/');
if (pos == NULL || pos[1] == '\0' || pos < &subdir[2]) {
dbg(udev, "not a subdir :%s
", syspath);
return NULL;
}
/* resolve possible symlink to real path */
util_strscpy(path, sizeof(path), syspath);
util_resolve_sys_link(udev, path, sizeof(path));
if (strncmp(&path[len], "/devices/", 9) == 0) {
char file[UTIL_PATH_SIZE];
/* all "devices" require a "uevent" file */
util_strscpyl(file, sizeof(file), path, "/uevent", NULL);
if (stat(file, &statbuf) != 0) {
dbg(udev, "not a device: %s
", syspath);
return NULL;
}
} else {
/* everything else just needs to be a directory */
if (stat(path, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) {
dbg(udev, "directory not found: %s
", syspath);
return NULL;
}
}
udev_device = udev_device_new(udev);
if (udev_device == NULL)
return NULL;
udev_device_set_syspath(udev_device, path);
info(udev, "device %p has devpath '%s'
", udev_device, udev_device_get_devpath(udev_device));
return udev_device;
}</span>
strrchr()関数は、指定した文字列の最後に表示される文字の位置を検索します.
ここで疑いますが、伝わってきたのは/sys/class/input/event 0/かもしれません.
判断条件により、転送されたのは/sys/class/input/event 0で、'/'を受けません.
util_resolve_sys_link(udev, path, sizeof(path));リンクシンボルファイルを解決し、実際のパスファイルを得る
event0 -> ../../devices/LNXSYSTM:00/LNXPWRBN:00/input/input0/event0
すなわち/sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input 0/event 0が得られ、udevまたはその例を見て印刷されたのが/devices/LNXSYSTM:00/LNXPWRBN:00/input/input 0/event 0のような形式である.
「/devices/」が含まれている場合は、続行し、
/sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input 0/event 0/uevent、各デバイスにueventがあるので、存在するか否かを判断します.
存在、OK、udevを作成デバイス、pathを追加
udev_device_set_syspath(udev_device, /sys/devices/LNXSYSTM:00/LNXPWRBN:00/input/input0/event0);
注意して、ここはset_ですsyspath.
これで終わりですが、まだ/devの下に関連するものはありません.难しくて私が漏らしたのですか???
では、次に/devの下のnodeをどのように手に入れたかを見てみましょう.
node = udev_device_get_devnode(device);
/** * udev_device_get_devnode: * @udev_device: udev device * * Retrieve the device node file name belonging to the udev device. * The path is an absolute path, and starts with the device directory. * * Returns: the device node file name of the udev device, or #NULL if no device node exists **/UDEV_EXPORT const char *udev_device_get_devnode(struct udev_device *udev_device) { if (udev_device == NULL) return NULL; if (!udev_device->info_loaded) { udev_device_read_uevent_file(udev_device); udev_device_read_db(udev_device, NULL); }/* we might get called before we handled an event and have a db, use the kernel-provided name */if (udev_device->devnode == NULL && udev_device_get_knodename(udev_device) != NULL) { char filename[UTIL_NAME_SIZE]; util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/", udev_device_get_knodename(udev_device), NULL); udev_device_set_devnode(udev_device, filename); return udev_device->devnode; } return udev_device->devnode; }
ここではueventファイル、dbファイルを読み込みます.これは何ですか
devnodeはdevpath+'/'+knodenameであることがわかります.
devpathおよびknodename
int udev_device_read_uevent_file(struct udev_device *udev_device) { char filename[UTIL_PATH_SIZE]; FILE *f; char line[UTIL_LINE_SIZE]; int maj = 0; int min = 0; if (udev_device->uevent_loaded) return 0; util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL); f = fopen(filename, "re"); if (f == NULL) return -1; udev_device->uevent_loaded = true; while (fgets(line, sizeof(line), f)) { char *pos; pos = strchr(line, ''); if (pos == NULL) continue; pos[0] = '\0'; if (strncmp(line, "DEVTYPE=", 8) == 0) udev_device_set_devtype(udev_device, &line[8]); else if (strncmp(line, "MAJOR=", 6) == 0) maj = strtoull(&line[6], NULL, 10); else if (strncmp(line, "MINOR=", 6) == 0) min = strtoull(&line[6], NULL, 10); else if (strncmp(line, "IFINDEX=", 8) == 0) udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10)); else if (strncmp(line, "DEVNAME=", 8) == 0) udev_device_set_knodename(udev_device, &line[8]); else if (strncmp(line, "DEVMODE=", 8) == 0) udev_device->devnode_mode = strtoul(&line[8], NULL, 8); udev_device_add_property_from_string(udev_device, line); } udev_device->devnum = makedev(maj, min); fclose(f); return 0; }
先に得られた経路付きueventから読み出されていることがわかります
[root@localhostevent 0]#cat uevent MAJOR=13 MINOR=64 DEVNAME=input/event 0 DEVNAMEをknodenameに設定します.
devpathの場合、初期化時のデフォルトは/devです.
/* set defaults */if (udev->dev_path == NULL) if (set_value(&udev->dev_path, "/dev") == NULL) goto err;
したがってdevnode,/dev/input/event 0が得られた.MAJORとMINORは何(キーボード、マウス、タッチデバイス)かを判断するのに使えますか?
次の質問は、/dev/input/event 0がマウスなのかキーボードなのか、タッチスクリーンなのかを判断する方法です.