这几天在做Linux的U盘检测,仅限于热插拔。查了很多资料,有用HAL的,UDISK的,还有直接用libusb库的,最后无聊的我选择了用NetLinkSock和udev来接收内核发送过来的信息,从而判断有没有设备接入。
#include <sys/socket.h>
#include <linux/netlink.h>
#include <unistd.h>
#include <sys/poll.h>
int main()
{
const int nBufferSize = 1024;
struct sockaddr_nl snl;
struct pollfd pfd;
bzero(&snl, sizeof(snl));
snl.nl_family = AF_NETLINK; // Or PF_NETLINK, It's all the same under Linux.
snl.nl_pid = getpid(); // Port, Use Pid As Socket Port;
snl.nl_pad = 0; // must be zero
snl.nl_groups = -1;
pfd.events = POLLIN;
pfd.fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
if(pfd.fd < 0)
{
qDebug() << "suc: " << pfd.fd << " socket create failed!";
return;
}
int ret = bind(pfd.fd, (struct sockaddr*)&snl, sizeof (struct sockaddr_nl));
if(ret < 0)
{
qDebug() << "ret: " << ret << " socket bind failed";
return;
}
char buff[1024 * 8] = { 0 };
//recv之前先poll,若只是单独循环recv数据是缺失的。
while(poll(&pfd, 1, -1) != -1)
{
recv(pfd.fd, buff, sizeof(buff), 0);//buff接收到内核发过来的关于设备数据
}
return 0;
}
打印出来大概这样,ACTION=add代表插入,拔出为remove,根据文本内容筛选出自己需要的东西。
如果是U盘提前插入,程序还没运行就没法检测到了,所以仅限于热插拔。
不过现在带UI的Linux系统基本大部分支持自动挂载,如果不想用第三方库或者投入大量精力,可以直接获取挂载目录,然后遍历挂载目录下是否有文件,从而达到检测和读取文件的目的。
若有更好的办法,或者写不到位的地方,欢迎评论指点QAQ