红联Linux门户
Linux帮助

Linux下侦测USB Disk插拔

发布时间:2014-11-26 09:43:59来源:linux网站作者:linux人

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/netlink.h>

// netlink.h 中定义
//struct sockaddr_nl
//{
// sa_family_t nl_family;   // AF_NETLINK
// unsigned short nl_pad;  // zero
// __u32   nl_pid;   // 进程ID
//__u32   nl_groups; // 多播组掩码
//};
//

static int
monitoring_usb_device( void )
{
// 本函数返回值
int iResult = 0;
// 接收内核发来的消息字符串
char caKernelMsgBuff[1024];
// 接收内核发来的消息缓冲区大小
const unsigned int uiRecvBuffSize = sizeof( caKernelMsgBuff );
// 套接字地址
struct sockaddr_nl snl;
// 套接字文件描述符
int sfd = -1;

do // 非循环,只是为了减少分支嵌套
{


// 1.添写套接字地址
snl.nl_family = AF_NETLINK;
snl.nl_pad = 0;
// 如果希望内核处理消息或多播消息,就把该字段设置为 0,
// 否则设置为处理消息的进程ID。
snl.nl_pid = getpid();
snl.nl_groups = 1;


// 2.创建套接字
// NETLINK_KOBJECT_UEVENT - 内核消息到用户空间,出现在 Linux 2.6.10
sfd = socket( PF_NETLINK, // 使用 netlink
SOCK_DGRAM, // 使用不连续不可信赖的数据包连接
NETLINK_KOBJECT_UEVENT );
// 如果 创建套接字失败 的话,则
if ( -1 == sfd )
{
iResult = -1;
break;
}


// 3.设置套接字接收缓冲区大小
setsockopt( sfd,
SOL_SOCKET, // 存取 socket 层
SO_RCVBUF,  // 设置接收缓冲区大小
&uiRecvBuffSize,
sizeof( uiRecvBuffSize ) );


// 4.将套接字加入指定的多播组
iResult = bind( sfd,
(struct sockaddr*)&snl,
sizeof( snl ) );
// 如果 将套接字加入指定的多播组失败 的话,则
if ( -1 == iResult )
{
return -2;
break;
}

while( 1 )
{
// 接收内核消息
recv( sfd,
&caKernelMsgBuff,
sizeof( caKernelMsgBuff ),
0 );

printf( "Kernel Message:\n%s\n", caKernelMsgBuff );

// USB 设备的插入时,会出现以 add@/devices/ 开头,含 usb 的字符串
if( 0 == memcmp( caKernelMsgBuff,
"add@",
4 )
&&
NULL != strstr( caKernelMsgBuff,
"usb" ) )
{
printf( "Add USB Device\n" );
break;
}

// USB 设备的拔除时,会出现以 remove@/devices/ 开头,含 usb 的字符串
if( 0 == memcmp( caKernelMsgBuff,
"remove@",
7 )
&&
NULL != strstr( caKernelMsgBuff,
"usb" ) )
{
printf( "Remove USB Device\n" );
break;
}
}

// 等一秒钟,让设备加载完毕
sleep(1);

}while( 0 );

// 如果 创建套接字成功 的话,则
if ( -1 != sfd )
{
// 关闭套接字
close( sfd );
sfd = -1;
}

return iResult;
}

int main(int argc, char* argv[])
{
printf( "monitoring_usb_device return %d\n",
monitoring_usb_device() );

return 0;
 
}