g_uevent_device_new 使用
时间: 2024-06-08 10:09:46 浏览: 13
g_uevent_device_new 是一个函数,用于创建一个新的 GUnixDevice 对象,该对象表示一个 Unix 设备。这个函数是 GIO 库的一部分,可以用于在 Linux 系统中创建和管理设备。
函数的声明为:
```C
GUnixDevice *g_uevent_device_new (gchar *sysfs_path,
guint flags,
GError **error);
```
其中,
- sysfs_path:设备的 sysfs 路径。
- flags:设备的标志位,可以是 0 或 G_UNIX_DEVICE_FLAGS_WATCH_MOUNTS 常量。
- error:用于存储错误信息的指针。
函数返回一个 GUnixDevice 对象的指针,如果出错则返回 NULL。
使用这个函数,我们可以创建一个 GUnixDevice 对象,然后调用其它 GIO 函数来操作设备,例如监听设备事件、读取设备属性等。
相关问题
g_uevent_device_new 代码举例
以下是一个简单的 g_uevent_device_new 函数实现的示例代码:
```c
#include <glib.h>
#include <gio/gio.h>
#define UEVENT_BUFFER_SIZE 2048
typedef struct _GUeventDevice GUeventDevice;
struct _GUeventDevice {
GObject parent_instance;
gchar *syspath;
gchar *subsystem;
gchar *devtype;
gchar **filters;
GRegex **regex_filters;
guint n_filters;
GIOChannel *io_channel;
guint io_watch_id;
gchar io_buffer[UEVENT_BUFFER_SIZE];
};
G_DEFINE_TYPE(GUeventDevice, g_uevent_device, G_TYPE_OBJECT);
static gboolean
g_uevent_device_io_watch_callback(GIOChannel *channel, GIOCondition condition,
gpointer user_data)
{
GUeventDevice *self = G_UEVENT_DEVICE(user_data);
if (condition & G_IO_IN) {
gsize bytes_read = 0;
gsize io_buffer_size = sizeof(self->io_buffer) - 1;
if (g_io_channel_read_chars(channel, self->io_buffer, io_buffer_size,
&bytes_read, NULL) != G_IO_ERROR_NONE) {
g_warning("Failed to read from uevent device");
return G_SOURCE_REMOVE;
}
/* Null-terminate the read buffer */
self->io_buffer[bytes_read] = '\0';
/* Process the uevent messages in the buffer */
gchar *line_start = self->io_buffer;
gchar *line_end = NULL;
while ((line_end = strchr(line_start, '\n'))) {
*line_end = '\0';
gchar **kv_pairs = g_strsplit(line_start, "=", -1);
/* Process the key-value pairs in the uevent message */
for (guint i = 0; kv_pairs[i]; i += 2) {
gchar *key = kv_pairs[i];
gchar *value = kv_pairs[i + 1];
/* Filter out the key-value pairs that don't match any of the
regex filters */
gboolean filter_match = FALSE;
for (guint j = 0; j < self->n_filters; j++) {
if (g_regex_match(self->regex_filters[j], key, 0, NULL)) {
filter_match = TRUE;
break;
}
}
if (!filter_match) {
continue;
}
g_message("Received uevent message: %s=%s", key, value);
}
g_strfreev(kv_pairs);
line_start = line_end + 1;
}
}
return G_SOURCE_CONTINUE;
}
static void
g_uevent_device_init(GUeventDevice *self)
{
self->syspath = NULL;
self->subsystem = NULL;
self->devtype = NULL;
self->filters = NULL;
self->regex_filters = NULL;
self->n_filters = 0;
self->io_channel = NULL;
self->io_watch_id = 0;
}
static void
g_uevent_device_class_init(GUeventDeviceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
object_class->finalize = (GObjectFinalizeFunc) g_free;
}
GUeventDevice *
g_uevent_device_new(const gchar *syspath, const gchar *subsystem,
const gchar *devtype, gchar **filters)
{
GUeventDevice *self = g_object_new(G_TYPE_UEVENT_DEVICE, NULL);
self->syspath = g_strdup(syspath);
self->subsystem = g_strdup(subsystem);
self->devtype = g_strdup(devtype);
self->filters = g_strdupv(filters);
/* Compile the regex filters */
for (guint i = 0; self->filters[i]; i++) {
GRegex *regex_filter = g_regex_new(self->filters[i], 0, 0, NULL);
if (!regex_filter) {
g_warning("Failed to compile regex filter: %s", self->filters[i]);
continue;
}
self->regex_filters = g_realloc(self->regex_filters,
(self->n_filters + 1) * sizeof(GRegex *));
self->regex_filters[self->n_filters++] = regex_filter;
}
/* Open the uevent device file */
gchar *uevent_path = g_build_filename(self->syspath, "uevent", NULL);
GError *error = NULL;
self->io_channel = g_io_channel_new_file(uevent_path, "r", &error);
if (!self->io_channel) {
g_warning("Failed to open uevent device: %s", error->message);
g_error_free(error);
g_object_unref(self);
return NULL;
}
/* Add a watch for the IO channel */
self->io_watch_id = g_io_add_watch(self->io_channel, G_IO_IN,
g_uevent_device_io_watch_callback, self);
g_free(uevent_path);
return self;
}
```
这个示例代码演示了如何使用 GLib 和 GIO 库来创建一个 GUeventDevice 对象,该对象可以通过监听 Linux 内核的 uevent 消息来获取设备事件。GUeventDevice 对象可以指定一些过滤器,以只接收特定的 uevent 消息。在对象的销毁期间,将释放所有内存和资源。
kobject_uevent
kobject_uevent 是一个 Linux 内核中的函数,用来生成和发送内核事件通知。它主要被用于通知用户空间关于内核对象状态的改变。该函数的使用方法如下:
1. 首先,在内核中创建一个 kobject 对象,kobject 是内核对象的基本结构,用来表示一个具体的内核实体。
2. 在用户空间,可以通过监听 uevent 文件来接收内核事件通知。这个文件位于 /sys 目录下的子目录中,目录以 kobject 的名称命名。通过监听 uevent 文件,用户空间可以实时接收内核对象状态的改变。
3. 当需要发送内核事件通知时,内核通过调用 kobject_uevent 函数生成包含事件信息的 uevent 消息。可以在函数调用时传递不同的参数,比如事件类型、事件名称和事件的详细信息等。
4. 一旦 uevent 消息生成完成,内核会将其写入到 kobject 对应的 uevent 文件中。
5. 用户空间可以通过读取 uevent 文件获取事件通知。通常,用户空间会使用类似于轮询的方式去读取 uevent 文件,以获取所有与内核对象相关的事件。
总结一下,kobject_uevent 是一个函数,用于在 Linux 内核中生成和发送内核事件通知。用户空间可以通过监听 uevent 文件来接收这些通知。这个机制在内核对象状态发生改变时,可以提供实时的通知和交互能力,方便用户空间与内核之间进行通信。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)