| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/select.h>
- #include <errno.h>
- #define DEVICE_PATH "/dev/power"
- #define BUFFER_SIZE 256
- int main() {
- int fd;
- fd_set read_fds;
- struct timeval timeout;
- char buffer[BUFFER_SIZE];
- int ret;
- // 1. 以非阻塞方式打开设备节点(也可以阻塞,但select会管理)
- fd = open(DEVICE_PATH, O_RDONLY | O_NONBLOCK);
- if (fd < 0) {
- perror("open device failed");
- return EXIT_FAILURE;
- }
- printf("Waiting for data from %s (select mode)...\n", DEVICE_PATH);
- while (1) {
- // 2. 清空文件描述符集,并加入我们的fd
- FD_ZERO(&read_fds);
- FD_SET(fd, &read_fds);
- // 3. 设置超时时间(例如5秒)
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- // 4. 等待fd可读
- ret = select(fd + 1, &read_fds, NULL, NULL, &timeout);
- if (ret < 0) {
- perror("select error");
- close(fd);
- return EXIT_FAILURE;
- } else if (ret == 0) {
- printf("select timeout after 5 seconds, continue waiting...\n");
- continue;
- }
- // 5. 检查是否是我们的fd可读
- if (FD_ISSET(fd, &read_fds)) {
- memset(buffer, 0, BUFFER_SIZE);
- ret = read(fd, buffer, BUFFER_SIZE - 1);
- if (ret < 0) {
- if (errno != EAGAIN) {
- perror("read error");
- }
- continue;
- } else if (ret == 0) {
- printf("device closed? ret=0\n");
- break;
- } else {
- printf("Received %d bytes: %s\n", ret, buffer);
- // 根据实际数据格式处理
- // 例如解析电池电量等信息
- if (strstr(buffer, "battery") != NULL) {
- printf(" -> Battery related data\n");
- }
- }
- }
- }
- close(fd);
- return EXIT_SUCCESS;
- }
|