linux下检测U盘插入并读取文件

获得U盘的插入或者拔取得信息的传统方法是在内核级运行hotplug程序,相关参数通过环境变量传递过来,再由hotplug通知其他关注hotplug的应用程序。这样的做法效率有些低,现在通过一种特殊类型的socket netlink实现获取U盘拔插的信息。netlink专门用于内核空间和用户空间的异步通信。

由于NETLINK是Linux内置功能,所以使用起来很简单:创建一个AF_NETLINK协议族下NETLINK_KOBJECT_UEVENT类型的特殊文件描述符(套结字)CppLive,然后利用setsocketopt允许该文件描述符(套结字)复用其他端口,再利用band函数将自身进程绑定到特殊文件描述符(套结字)CppLive,最后利用select在while循环内监听CppLive是否可读,如果可读则调用recv接收Linux系统内核传递过来的数据并打印出来,这些输出便是USB热插拔信息。当然你也可以个性化地处理来自内核的热插拔信息,让程序变得更加智能以及人性化。


建立NET_LINK套接字,与内核通信实时检测U状态(与基本的套接字编程基本一致) 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define UEVENT_BUFFER_SIZE 2048

static int init_hotplug_sock(void);

int main(int argc, char* argv[])
{
int hotplug_sock = init_hotplug_sock();
while(1){
char buf[UEVENT_BUFFER_SIZE*2] = {0};
recv(hotplug_sock, &buf, sizeof(buf), 0); 
printf("%s\n", buf);

}
return 0;
}

static int init_hotplug_sock(void)
{
struct sockaddr_nl snl;
const int buffersize = 16 * 1024 * 1024;
int retval;

memset(&snl, 0x00, sizeof(struct sockaddr_nl));
snl.nl_family = AF_NETLINK;
snl.nl_pid = getpid();
snl.nl_groups = 1;
int hotplug_sock = 
socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);

if (hotplug_sock == -1) {
printf("error getting socket: %s", strerror(errno));
return -1;
}

/* set receive buffersize */
setsockopt(hotplug_sock, 
SOL_SOCKET, SO_RCVBUFFORCE, 
&buffersize, sizeof(buffersize));
retval = bind(hotplug_sock,
 (struct sockaddr *) &snl, 
sizeof(struct sockaddr_nl));

if (retval < 0) {
printf("bind failed: %s", strerror(errno));
close(hotplug_sock);
hotplug_sock = -1;
return -1;
}

return hotplug_sock;
}

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值