- 论坛徽章:
- 0
|
本人比较笨,研究了几天,了解了一点。内核通过netlink把内核消息发送出去,udevd专门建一个连接监听然后接收消息。- # event to be catched by udevmonitor
- RUN+="socket:/org/kernel/udev/monitor"
复制代码 是udevd的一条规则,意思是把udevd收到的消息发送到一个socket,这个socket绑定在/org/kernel/udev/monitor上,我们可以写个程序去接收这消息如下:
我在/etc/udevd/rules.d/下添加一条规则- RUN+="socket:@/org/kernels/udev/udevd
复制代码 然后编译运行下面的代码,就可以接收到消息了。- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <stddef.h>
- #include <string.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <signal.h>
- #include <getopt.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <sys/un.h>
- #include <sys/select.h>
- #include <linux/types.h>
- #include <linux/netlink.h>
- static int udev_sock = -1;
- static int
- init_socket (void)
- {
- struct sockaddr_un saddr;
- socklen_t addrlen;
- int retval;
- memset (&saddr, 0x00, sizeof (saddr));
- saddr.sun_family = AF_LOCAL;
- strcpy (&saddr.sun_path[1], "/org/kernels/udev/udevd");
- addrlen =
- offsetof (struct sockaddr_un, sun_path) + strlen (saddr.sun_path + 1) + 1;
- udev_sock = socket (AF_LOCAL, SOCK_DGRAM, 0);
- if (udev_sock == -1)
- {
- printf ("create socket err\n");
- return -1;
- }
- retval = bind (udev_sock, (struct sockaddr *) &saddr, addrlen);
- if (retval < 0)
- {
- printf("bind error\n");
- close (udev_sock);
- udev_sock = -1;
- return -1;
- }
- return 0;
- }
- int
- main ()
- {
- fd_set readfds;
- char buf[1024];
- int retval = 0;
- int fdcount;
- int buflen = 0;
- init_socket();
- while (1)
- {
- FD_ZERO (&readfds);
- if (udev_sock >= 0)
- FD_SET (udev_sock, &readfds);
- fdcount = select (udev_sock + 1, &readfds, NULL, NULL, NULL);
- if (fdcount < 0)
- {
- continue;
- }
- if (udev_sock >= 0 && FD_ISSET (udev_sock, &readfds))
- {
- buflen = recv (udev_sock, &buf, sizeof (buf), 0);
- printf ("%s\n", buf);
- }
- }
- }
复制代码 不过这些还是不能解决我的问题,我需要电源键被按下的时候也能收到一条消息,但没有收到,不知道是不是只有插拔事件才会产生事件。还是的确有办法只是我没有找到,我现在能想到的是我们的电源键有一个设备文件,可以从中读取状态,也就是说它是有驱动的,是不是可以改驱动产生一个事件,然后我再去读电源键设备的文件状态。这样就不用一直查询了。 |
|