zoukankan      html  css  js  c++  java
  • linux下u盘检測程序

           获得U盘的插入或者拔取得信息的传统方法是在内核级执行hotplug程序。相关參数通过环境变量传递过来,再由hotplug通知其它关注hotplug的应用程序,可是效率比較低.

         网上查找知道:

       用户空间的程序与设备通信的方法,主要有下面几种方式。
      1. 通过ioperm获取操作IOport的权限,然后用inb/inw/ inl/ outb/outw/outl等函数,避开设备驱动程序,直接去操作IOport。(没实用过)
      2. 用ioctl函数去操作/dev文件夹下相应的设备,这是设备驱动程序提供的接口。像键盘、鼠标和触摸屏等输入设备一般都是这样做的。
      3. 用write/read/mmap去操作/dev文件夹下相应的设备。这也是设备驱动程序提供的接口。像framebuffer等都是这样做的。

           上面的方法在大多数情况下,都能够正常工作,可是对于热插拨(hotplug)的设备。比方像U盘,就有点困难了,由于不知道:什么时候设备插上了,什么时候设备拔掉了。

    这就是所谓的hotplug问题了。

       新的方法是採用NETLINK实现的,这是一种特殊类型的socket。专门用于内核空间与用户空间的异步通信。



       先说明几个总要的结构体:

      sockaddr_nl结构:
          struct sockaddr_nl {
                           sa_family_t nl_family;    //AF_NETLINK
                           unsigned short nl_pad;    // 0
                           pid_t nl_pid;         // 进程pid
                            u_32 nl_groups;      // 多播组掩码
                       }nl;

      int setsockopt(
                          SOCKET s,
                          int level,
                          int optname,
                          const char* optval,
                          int optlen
                    );

    s(套接字): 指向一个打开的套接口描写叙述字
              level:(级别): 指定选项代码的类型。
              SOL_SOCKET: 基本套接口
              IPPROTO_IP: IPv4套接口
              IPPROTO_IPV6: IPv6套接口
              IPPROTO_TCP: TCP套接口
              optname(选项名): 选项名称
              optval(选项值): 是一个指向变量的指针 类型:整形,套接口结构, 其它结构类型:linger{}, timeval{ }
              optlen(选项长度) :optval 的
    大小

    贴出代码:

    #include <stdio.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <linux/netlink.h>
    #include <dirent.h>
    #include <sys/statfs.h>
    
    int init_socket()
    {
    	struct sockaddr_nl snl;
    	const int BufferSize= 1024;
    	int retval;
    	
    	memset(&snl,0,sizeof(struct sockaddr_nl));
    	snl.nl_family = AF_NETLINK;
    	snl.nl_pid = getpid();
    	snl.nl_groups = 1;
    	
    	int Sock_id = socket(PF_NETLINK,SOCK_DGRAM,NETLINK_KOBJECT_UEVENT);
    	
    	if(Sock_id == -1)
    	printf("sock err:%m
    "),exit(-1);
    	
    	// set reveive buffer
    	setsockopt(Sock_id,SOL_SOCKET,SO_RCVBUFFORCE,&BufferSize,sizeof(BufferSize));
    	retval = bind(Sock_id,(struct sockaddr*)&snl,sizeof(struct sockaddr_nl));
    	if(retval==-1)
    	printf("bind err:%m
    "),close(Sock_id),exit(-1);
    	return Sock_id;
    }
    
    // 该函数主要作用时检測u盘的 总空间,剩余空间,剩余空间百分比
    double GetDiskFreeSpacePercent(const char *pDisk,double* freespace,double*  totalspace)
    {
    	struct statfs disk_statfs;
    	double freeSpacePercent =0;
    	if(statfs(pDisk,&disk_statfs) == 0)
    	{
    		
    		*freespace = (disk_statfs.f_bsize * disk_statfs.f_bfree) / (1024*1024*1024.0);
    		*totalspace = (disk_statfs.f_bsize * disk_statfs.f_blocks) / (1024*1024*1024.0);
    	}
    	return freeSpacePercent = (*freespace)/(*totalspace)*100;
    
    }
    
    #define BUFFER_SIZE 2048
    
    int main()
    {
    	DIR *dp;
    	double f=0;
    	double t=0;
    	double percent=0;
    	const char* path="/media/cjl/disk";
    	int sd= init_socket();
    	while(1)
    	{
    		char buf[BUFFER_SIZE] = {0};
    		recv(sd,&buf,sizeof(buf),0);
    		//printf("%s
    ",buf);
    			if(!memcmp(buf,"add@",4) /*&& !memcmp(&buf[strlen(buf) - 4],"/sdb",4)*/)
    		{
    			printf("Found U Disk
    ");
    			break;
    		}
    	}
    	printf("是否打开u盘Y/N
    ");
    	char c;
    	scanf("%c",&c);
    	if(c=='Y' || c=='y')
    	{
    		if((dp = opendir(path)) ==NULL)
    		{
    			printf("打开失败!
    ");
    		}
    		else
    		{
    			system("ls -l /media/cjl/disk");
    		}
    	}
    	else if(c=='N' || c=='n')
    	
    	percent = GetDiskFreeSpacePercent(path,&f,&t);
    	
    	printf("u盘剩余空间: %.2f
    ",f);
    	printf("u盘总空间:   %.2f
    ",t);
    	printf("u盘剩余空间百分比: %0.2f%%
    ",percent);
    	return 0;
    }


                     









  • 相关阅读:
    Spring之调度器(Scheduler)
    Spring之拦截器(Interceptor)
    ThreadLocal相关
    hibernate操作数据库
    文件操作的工具类
    日期操作工具类
    有关mysql的utf8和utf8mb4,以及Illegal mix of collations for operation 'like'
    [原]nginx 一下快一下慢的问题
    再谈微信公众号网页授权的40163错误
    用DBCC CHECK修复SQL2000的数据库一致性问题
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7120855.html
Copyright © 2011-2022 走看看