linux下 USB动态监测 hotplug事件监测
From: http://blog.csdn.net/qwyang/article/details/6425555
總體規劃:
使用netlink接口向內核注冊hotplug事件通知,獲取事件通知后進行相關動作如(Action==add)掛載或(action==remove)卸載,使用Socket IPC機制向需要響應USB熱拔插事件的應用程序報告。
功能包括:
1、獲取usb卷標
2、掛載、卸載usb
3、動態監測usb熱拔插事件
4、使用socket向應用程序報告熱拔插事件
函數接口說明:
int reportToIplayer(USBEvent event,const char *servername);
向應用程序IPlayer報告熱拔插事件
void check();
程序啟動開始先檢查當前u盤狀態(空或者已存在)
int getDevPath(const char *buf,char *path,int size);
從熱拔插事件的Diagram消息即buf中獲得usb的設備路徑存放到path,size為path緩沖大小
int rm_dir(const char *path);
刪除掛載時建立的空目錄
int make_dir(const char *devPath,const char *dstPath);
掛載錢建立一個空目錄dstPath,dstPath為掛載目錄
int get_label(const char *dev,char *buf,int size);
獲取u盤卷標
int recordDstPath(int no,const char *dstPath);
記錄下掛載路徑,便于rm_dir查詢
int init_hotplug_sock(void);
向內核注冊hotplug事件
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/un.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <linux/netlink.h> #include <errno.h> #include <sys/stat.h> #include <sys/types.h> #include <dirent.h> #include <stddef.h>typedef struct USBEvent {int event;char path[30]; }USBEvent;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 get 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(0>retval){printf("bind failed:%s",strerror(errno));close(hotplug_sock);hotplug_sock = -1;return -1;}return hotplug_sock; }char dstPathTable[8][30];int recordDstPath(int no,const char *dstPath) {if(strlen(dstPath) >= 30 || no>8){printf("pathname = %s,no = %d",dstPath,no);return -1;}strcpy(dstPathTable[no-1],dstPath);printf("%s has been recorded",dstPathTable[no-1]);return 0; }const char *LABEL = "label_tmp";void trim(char *buf) {int i = strlen(buf)-1;while(i == '\n' || i == ' '){--i;printf("true/n");}buf[i+1] = 0; }int get_label(const char *dev,char *buf,int size) {static int noLabel = 0;int ret,fd;char comm[200] = {0};sprintf(comm,"vol_id -l %s | sed -n '$p' > %s",dev,LABEL);system(comm);printf("get_label\n");fd = open(LABEL,O_RDONLY);if(fd == -1){perror("open in get_label");goto error;}ret = read(fd,buf,size-1);if(-1 == ret){perror("read in get_label");goto error;}close(fd);buf[ret-1] = 0;printf("get_label:%s,%d",buf,strlen(buf));if(strlen(buf) <= 1){++noLabel;sprintf(buf,"usb%d",noLabel);}return 0; error:++noLabel;sprintf(buf,"use%d",noLabel);return -1; }int make_dir(const char *devPath,const char *dstPath) {mode_t dMode = S_IRWXU|S_IRWXG|S_IRWXO;int ret;int no = devPath[strlen(devPath)-1]-'0';ret = mkdir(dstPath,dMode);if(ret == -1){perror("make_dir");return ret;}return recordDstPath(no,dstPath); }int rm_dir(const char *path) {int no = path[strlen(path)-1]-'0';printf("rmdir:%s\n",dstPathTable[no-1]);int ret = rmdir(dstPathTable[no-1]);if(ret == -1)perror("rm_dir");dstPathTable[no-1][0] = 0;return 0; }int getDevPath(const char *buf,char *path,int size) {int i;char tmp[20];for(i = 1;i <= 8;++i){sprintf(tmp,"/sdb%d",i);if(strstr(buf,tmp)){strcpy(path,"/dev");strcat(path,tmp);printf("getDevPath:%s\n",path);return 0;}}printf("getDevPath:null\n");path[0] = 0;return -1; }const int ADD_EVENT = 0; const int REMOVE_EVENT = 1;void check() {char devPath[20];char label[21];char dstPath[30];char comm[100];char tmp[30];int i,ret;struct stat sb;struct dirent *file;USBEvent event;memset(&event,0,sizeof(event));for(i = 1;i<9;++i){sprintf(devPath,"/dev/sdb%d",i);sprintf(comm,"umount %s",devPath); // umount /dev/sdb1-8system(comm);}DIR *dir = opendir("/media/usb");while((file = readdir(dir)) != NULL){sprintf(tmp,"/media/usb/%s",file->d_name);ret = rmdir(tmp);if(0 == ret)printf("%s has been deleted!",tmp);}closedir(dir);for(i = 0;i<9;++i){sprintf(devPath,O_RDONLY); // what?????if(-1 != ret){close(ret);printf("%s found\n",devPath);get_label(devPath,label,21);printf(dstPath,"/media/usb/%s",label);make_dir(devPath,dstPath);sprintf(comm,"mount -t auto -o utf8,rw %s %s",devPath,dstPath);ret = system(comm);event.event = ADD_EVENT;strcpy(event.path,dstPath);reportTolplayer(event,"server.socket");printf("ret:%s\n",ret);}}printf("check exit\n"); }int reportTolplayer(USBEvent event,const char *servername) {const char *CLIENT_PATH = "/tmp/cli";struct sockaddr_un un;int ret,fd,size,i;unlink(CLIENT_PATH);memset(&un,0,sizeof(un));un.sun_family = AF_UNIX;sprintf(un.sun_path,"%s%5d",CLIENT_PATH,getpid());size = offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);fd = socket(AF_UNIX,SOCK_STREAM,0);if(-1 == fd){perror("socket error");return -1;}unlink(un.sun_path);ret = bind(fd,(struct sockaddr *)&un,size);if(-1 == ret){perror("bind error");return -1;}memset(&un,0,sizeof(un));un.sun_family = AF_UNIX;strcpy(un.sun_path,servername);ret = connect(fd,(struct sockaddr *)&un,size);if(-1 == ret){perror("connect error");return -1;}ret = write(fd,&event,sizeof(event));if(-1 == ret){perror("write error");return -1;}ret = close(fd);if(-1 == ret){perror("close error");return -1;} }void splitString(char *buf, char *seps) {if(buf && seps){char *p = buf;p = strtok(buf, seps);while(p){printf("p=[%s]\n", p);p = strtok(NULL, seps);}printf("\n");} }int getConsoleOutput(char *command, char *mode, char *out, int maxLen) {FILE *p = popen(command, mode);if(p == NULL){perror("popen");return 0;}fread(out, 1, maxLen, p);return ferror(p) == 0; }int main(int argc,char **argv) {char buf[1024] = {0};char comm[200] = {0};char dstPath[30] = {0};char devPath[30] = {0};char vol[21] = {0};int hotplug_sock;int sum,size;char *str;USBEvent event;memset(&event,0,sizeof(event));check();hotplug_sock = init_hotplug_sock();while(1){sum = 0;size = recv(hotplug_sock,buf,sizeof(buf),0);printf("size=%d, buf=[%s], strlen(buf)=%d\n", size, buf, strlen(buf));while(sum < size){str = buf + sum;sum += strlen(str);buf[sum] = '\n';}buf[sum] = 0;//printf("buf=[%s]\n\n", buf);splitString(buf, "\n");if(strstr(buf,"ACTION=add")){printf("ACTION=add\n");if(getDevPath(buf,devPath,30) == 0){get_label(devPath,vol,21);sprintf(dstPath,"/media/usb/%s",vol);make_dir(devPath,dstPath);sprintf(comm,"mount -t auto -o utf8,rw %s %s",devPath,dstPath);system(comm);event.event = ADD_EVENT;strcpy(event.path,dstPath);reportTolplayer(event,"server.socket");}}if(strstr(buf,"ACTION=remove")){printf("ACTION = remove\n");if(getDevPath(buf,devPath,30) == 0){sprintf(comm,"umount %s",devPath);system(comm);rm_dir(devPath);event.event = REMOVE_EVENT;reportTolplayer(event,"server.socket");}}}return 0; }總結
以上是生活随笔為你收集整理的linux下 USB动态监测 hotplug事件监测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: svn 的使用(二)
- 下一篇: linux下mariadb大小写敏感