Sysfsの理解とlibudevの浅い分析(四)--第二層の精髄

5749 ワード

まだ見ていないで、私が望んでいる実現の精髄だと思って、理解してどのように獲得するかを知っています.
 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がマウスなのかキーボードなのか、タッチスクリーンなのかを判断する方法です.