摘自:https://www.cnblogs.com/jlmgary/p/6742630.html
之前学习了下Udev,就随便做了个测试小程序.....设计什么的也没考虑,就实现了一个基本功能,插入U盘,识别,循环检测到有特定文件后,就然后往U盘里面写数据,插拔多次,都能正常工作。
里面的warning和不规范的写法请自己修改。
1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <stddef.h> 5 #include <string.h> 6 #include <errno.h> 7 #include <getopt.h> 8 #include <fcntl.h> 9 #include <errno.h> 10 #include <signal.h> 11 #include <getopt.h> 12 #include <sys/time.h> 13 #include <sys/socket.h> 14 #include <sys/un.h> 15 #include <sys/select.h> 16 #include <linux/types.h> 17 #include <linux/netlink.h> 18 #include <sys/types.h> 19 #include <libudev.h> 20 #include <iostream> 21 #include <pthread.h> 22 #include <sys/mount.h> 23 #include <sys/stat.h> 24 #include <dirent.h> 25 #include <time.h> 26 using namespace std; 27 static std::string record_path=""; 28 29 static bool FindRecord=false; 30 void File_Opreation(); 31 void GetUsbFolderLocation(char *basePath); 32 void MountTheSystem(char *basePath); 33 static bool NeedToCheck=false; 34 int ListDevice() 35 { 36 udev *udev; 37 struct udev_enumerate *enumerate; 38 struct udev_list_entry *devices, *dev_list_entry; 39 struct udev_device *dev; 40 41 /* Create the udev object */ 42 udev = udev_new(); 43 if (!udev) 44 { 45 printf("Can't create udev "); 46 exit(1); 47 } 48 49 /* Create a list of the devices in the 'hidraw' subsystem. */ 50 enumerate = udev_enumerate_new(udev); 51 udev_enumerate_add_match_subsystem(enumerate, "block"); 52 udev_enumerate_scan_devices(enumerate); 53 devices = udev_enumerate_get_list_entry(enumerate); 54 /* For each item enumerated, print out its information. 55 udev_list_entry_foreach is a macro which expands to 56 a loop. The loop will be executed for each member in 57 devices, setting dev_list_entry to a list entry 58 which contains the device's path in /sys. */ 59 udev_list_entry_foreach(dev_list_entry, devices) 60 { 61 const char *path; 62 63 /* Get the filename of the /sys entry for the device 64 and create a udev_device object (dev) representing it */ 65 path = udev_list_entry_get_name(dev_list_entry); 66 dev = udev_device_new_from_syspath(udev, path); 67 68 /* usb_device_get_devnode() returns the path to the device node 69 itself in /dev. */ 70 printf("Device Node Path: %s ", udev_device_get_devnode(dev)); 71 72 /* The device pointed to by dev contains information about 73 the hidraw device. In order to get information about the 74 USB device, get the parent device with the 75 subsystem/devtype pair of "usb"/"usb_device". This will 76 be several levels up the tree, but the function will find 77 it.*/ 78 dev = udev_device_get_parent_with_subsystem_devtype( 79 dev, 80 "usb", 81 "usb_device"); 82 if (!dev) 83 { 84 cout<<"Unable to find parent usb device"<<endl; 85 exit(1); 86 } 87 88 /* From here, we can call get_sysattr_value() for each file 89 in the device's /sys entry. The strings passed into these 90 functions (idProduct, idVendor, serial, etc.) correspond 91 directly to the files in the directory which represents 92 the USB device. Note that USB strings are Unicode, UCS2 93 encoded, but the strings returned from 94 udev_device_get_sysattr_value() are UTF-8 encoded. */ 95 printf(" VID/PID: %s %s ", 96 udev_device_get_sysattr_value(dev,"idVendor"), 97 udev_device_get_sysattr_value(dev, "idProduct")); 98 printf(" %s %s ", 99 udev_device_get_sysattr_value(dev,"manufacturer"), 100 udev_device_get_sysattr_value(dev,"product")); 101 printf(" serial: %s ", 102 udev_device_get_sysattr_value(dev, "serial")); 103 udev_device_unref(dev); 104 } 105 /* Free the enumerator object */ 106 udev_enumerate_unref(enumerate); 107 108 udev_unref(udev); 109 110 return 0; 111 } 112 113 void Udev_Enumrate() 114 { 115 struct udev* udev_ancestor=NULL; 116 struct udev_enumerate* udev_enum=NULL; 117 struct udev_list_entry* device_fistentry=NULL; 118 struct udev_list_entry *dev_list_entry=NULL; //entry to store the current position 119 struct udev_device *dev=NULL; 120 udev_ancestor=udev_new(); 121 udev_enum=udev_enumerate_new(udev_ancestor); 122 if(udev_enumerate_add_match_subsystem (udev_enum, "block")==0) 123 { 124 cout<<"add block device to match subsystem successful"<<endl; 125 } 126 127 if(udev_enumerate_add_match_subsystem (udev_enum, "usb")==0) 128 { 129 cout<<"add usb device to match subsystem successful"<<endl; 130 } 131 132 if(udev_enumerate_add_match_subsystem (udev_enum, "scsi")==0) 133 { 134 cout<<"add scsi device to match subsystem successful"<<endl; 135 } 136 137 //Scan the system under /sys/ 138 udev_enumerate_scan_devices(udev_enum); 139 140 //get the first entry of the device list 141 device_fistentry=udev_enumerate_get_list_entry(udev_enum); 142 143 /* For each item enumerated, print out its information. 144 udev_list_entry_foreach is a macro which expands to 145 a loop. The loop will be executed for each member in 146 devices, setting dev_list_entry to a list entry 147 which contains the device's path in /sys. */ 148 udev_list_entry_foreach(dev_list_entry, device_fistentry) 149 { 150 const char *path; 151 152 /* Get the filename of the /sys entry for the device 153 and create a udev_device object (dev) representing it */ 154 path = udev_list_entry_get_name(dev_list_entry); 155 dev = udev_device_new_from_syspath(udev_ancestor, path); 156 157 /* usb_device_get_devnode() returns the path to the device node 158 itself in /dev. */ 159 printf("Test Device Node Path: %s ", udev_device_get_devnode(dev)); 160 161 162 /* The device pointed to by dev contains information about 163 the hidraw device. In order to get information about the 164 USB device, get the parent device with the 165 subsystem/devtype pair of "usb"/"usb_device". This will 166 be several levels up the tree, but the function will find 167 it.*/ 168 dev = udev_device_get_parent_with_subsystem_devtype( 169 dev, 170 "usb", 171 "usb_device"); 172 if (!dev) 173 { 174 cout<<"Test Unable to find parent usb device"<<endl; 175 //exit(1); 176 } 177 else 178 { 179 printf(" VID/PID: %s %s ",udev_device_get_sysattr_value(dev,"idVendor"), udev_device_get_sysattr_value(dev, "idProduct")); 180 printf(" %s %s ",udev_device_get_sysattr_value(dev,"manufacturer"), udev_device_get_sysattr_value(dev,"product")); 181 printf(" serial: %s ",udev_device_get_sysattr_value(dev, "serial")); 182 } 183 184 udev_device_unref(dev); 185 } 186 udev_enumerate_unref(udev_enum); 187 udev_unref(udev_ancestor); 188 189 } 190 191 void* udev_Monitor(void*) 192 { 193 struct udev* udev=NULL; 194 struct udev_monitor * mon=NULL; 195 struct udev_device *dev; 196 int fd; 197 fd_set fds; 198 struct timeval tv; 199 static int flag=0; 200 201 udev=udev_new(); 202 mon=udev_monitor_new_from_netlink(udev,"udev"); 203 204 udev_monitor_filter_add_match_subsystem_devtype(mon, "sound", "usb_device"); 205 udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", "usb_device"); 206 udev_monitor_filter_add_match_subsystem_devtype(mon, "block", "disk"); 207 udev_monitor_filter_add_match_subsystem_devtype(mon, "block", "partition"); 208 udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", "usb_interface"); 209 udev_monitor_enable_receiving(mon); 210 fd = udev_monitor_get_fd(mon); 211 while(1) 212 { 213 214 fd_set fds; 215 struct timeval tv; 216 int ret; 217 218 FD_ZERO(&fds); 219 FD_SET(fd, &fds); 220 tv.tv_sec = 0; 221 tv.tv_usec = 0; 222 223 ret = select(fd+1, &fds, NULL, NULL, &tv); 224 //ret means there's an event fd_isset means fd is readable 225 if(ret>0 & FD_ISSET(fd,&fds)) 226 { 227 //cout<<"There's a change with Num="<<flag<<endl; 228 //flag++; 229 /* Make the call to receive the device. 230 select() ensured that this will not block. */ 231 dev = udev_monitor_receive_device(mon); 232 if (dev) 233 { 234 const char* sysPath = udev_device_get_syspath(dev); 235 const char* action = udev_device_get_action(dev); 236 const char* subsystem = udev_device_get_subsystem(dev); 237 const char* devType = udev_device_get_devtype(dev); 238 if (0 == strncmp(action, "add", strlen("add"))) 239 { 240 241 const char* devClass = udev_device_get_sysattr_value(dev, "bDeviceClass"); 242 const char* devInterfaceClass = udev_device_get_sysattr_value(dev, "bInterfaceClass"); 243 244 cout<<"The devClass: "<<devClass<<endl; 245 cout<<"The devInterfaceClass:"<<devInterfaceClass<<endl; 246 247 NeedToCheck=true; 248 249 } 250 printf("Got Device "); 251 printf(" Node: %s ", udev_device_get_devnode(dev)); 252 printf(" Subsystem: %s ", udev_device_get_subsystem(dev)); 253 printf(" Devtype: %s ", udev_device_get_devtype(dev)); 254 printf(" Action: %s ",udev_device_get_action(dev)); 255 printf(" Path: %s ",udev_device_get_syspath(dev)); 256 257 udev_device_unref(dev); 258 } 259 else 260 { 261 printf("No Device from receive_device(). An error occured. "); 262 } 263 } 264 } 265 } 266 267 268 269 int LoopileList(char *basePath) 270 { 271 DIR *dir; 272 struct dirent *ptr; 273 char base[1000]; 274 275 if ((dir=opendir(basePath)) == NULL) 276 { 277 perror("Open dir error..."); 278 exit(1); 279 } 280 281 while ((ptr=readdir(dir)) != NULL) 282 { 283 if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0) ///current dir OR parrent dir 284 { 285 continue; 286 } 287 else if(ptr->d_type == 8) ///file 288 { 289 printf("d_name:%s/%s ",basePath,ptr->d_name); 290 } 291 else if(ptr->d_type == 10) ///link file 292 { 293 printf("d_name:%s/%s ",basePath,ptr->d_name); 294 } 295 else if(ptr->d_type == 4) ///dir 296 { 297 memset(base,'