手里有个树莓派3B想来还是做局域网的共享服务 以及远程下载机靠谱.由于机械盘不稳定,经常会出现掉盘, 重复挂载问题.
刚好会一点Qt,写个挂载程序,加个开机启动就完事了.
代码主要用到内核的通信机制 netLink用于检测U盘挂载 卸载事件.
Qt则没有使用界面 直接后台运行即可,当然加个sh的守护进程也必不可少.
U盘检测代码:
checkudisk.h //用于检测U盘等设备 用于挂载卸载
#ifndef CHECKUDISK_H
#define CHECKUDISK_H
#include
#include
#include
#include
#include
#include
#include "usbcheck.h"
#include "runCmd.h"
class usbCheck;
class runCmd;
class checkUdisk : public QObject
{
Q_OBJECT
public:
explicit checkUdisk(QObject *parent = 0);
bool checking();
void started();
~checkUdisk();
public slots:
void getName(QStringList,int statue);
private:
QThread *thread;
usbCheck *check;
QStringList usbPathList;
};
#endif // CHECKUDISK_H
checkudisk.cpp
#include "checkudisk.h"
checkUdisk::checkUdisk(QObject *parent): QObject(parent)
{
check = new usbCheck();
thread = new QThread();
connect(thread, SIGNAL(started()),check,SLOT(checking()));
connect(thread, SIGNAL(finished()),check, SLOT(deleteLater()));
connect(check,SIGNAL(usbName(QStringList,int)),this,SLOT(getName(QStringList,int)));
check->moveToThread(thread);
}
void checkUdisk::started()
{
int pos=0;
bool fdiskU,dfU;
QString cmd,path;
QDir dir;
QString checkResult;
/* fdisk -l 检查/dev下是否识别U盘/sd[a-z][0-9]{1,2} */
runCmd checkU;
QString fidsk = "fdisk";
QStringList fdisk_list;
fdisk_list<<"-l";
checkU.setCmd(fidsk,fdisk_list);
checkResult = checkU.getString();
fdisk_list.clear();
QRegExp rx("sd[a-z][0-9]{1,2}");
while( (pos = rx.indexIn(checkResult,pos)) != -1 )
{
fdisk_list<start();
}
checkUdisk::~checkUdisk()
{
disconnect(thread, SIGNAL(started()),check,SLOT(checking()));
disconnect(thread, SIGNAL(finished()),check, SLOT(deleteLater()));
if(thread)
{
if(thread->isRunning())
{
thread->quit();
thread->wait();
}
delete thread;
thread = NULL;
}
if(check)
{
delete check;
check = NULL;
}
}
void checkUdisk::getName(QStringList strList,int statue)
{
QString cmd,path;
QDir dir;
if(strList.length() == 0)
return;
if(statue == 0)
{
for(int i=0; i
usbcheck.h // 通过netlink检测硬件设备的挂载 移除
#ifndef USBCHECK_H
#define USBCHECK_H
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include "head.h"
#define UEVENT_BUFFER_SIZE 4096
class usbCheck : public QObject
{
Q_OBJECT
public:
explicit usbCheck(QObject *parent = 0);
signals:
void usbName(QStringList ,int statue);
public slots:
void checking();
private:
void getName(QString);
private:
int sockfd;
struct sockaddr_nl client;
struct timeval tv;
struct msghdr msg;
struct iovec iov;
fd_set fds;
int receiveLenth,i,result;
int buffersize;
};
#endif // USBCHECK_H
usbcheck.cpp
#include "usbcheck.h"
usbCheck::usbCheck(QObject *parent) : QObject(parent)
{
/* socket通信 使用 netLink方式获取内核消息 */
sockfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
memset(&client,0,sizeof(client));
client.nl_family = AF_NETLINK;
client.nl_pid = getpid();
client.nl_groups = 1;
buffersize = 1024;
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,&buffersize, sizeof(buffersize));
bind(sockfd, (struct sockaddr *)&client,sizeof(client));
}
void usbCheck::checking()
{
for(;;)
{
char buf[UEVENT_BUFFER_SIZE] = {0};
FD_ZERO(&fds);
FD_SET(sockfd,&fds);
tv.tv_sec = 0;
tv.tv_usec = 100*1000;
result = select(sockfd+1,&fds, NULL,NULL, &tv);
if(result <0)
continue;
if(!(result>0 && FD_ISSET(sockfd,&fds)))
continue;
receiveLenth = recv(sockfd,&buf,sizeof(buf),0);
if(receiveLenth >0)
{
getName(buf);
}
}
}
void usbCheck::getName(QString buf)
{
QString statue = buf.split("@").at(0);
QStringList resultList;
QRegExp rx("sd[a-z]{1}[0-9]{1,2}");
int pos = 0;
while( (pos = rx.indexIn(QString(buf),pos)) != -1)
{
resultList<
runCmd.h //为了执行命令 写了proc去执行命令
#ifndef RUNCMD_H
#define RUNCMD_H
#include
#include
#include
class runCmd : public QObject
{
Q_OBJECT
public:
explicit runCmd(QObject *parent = 0);
~runCmd();
void setCmd(QString,QStringList);
QString getString();
signals:
public slots:
void readyRead();
private:
QProcess *process;
QString putout;
};
#endif // RUNCMD_H
runCmd.cpp
#include "runCmd.h"
runCmd::runCmd(QObject *parent) : QObject(parent)
{
process = new QProcess(this);
connect(process, SIGNAL(readyRead()),this,SLOT(readyRead()));
}
runCmd::~runCmd()
{
delete process;
}
QString runCmd::getString()
{
while(false == process->waitForFinished());
return putout;
}
void runCmd::setCmd(QString str,QStringList strList)
{
if(strList.length()==0)
{
process->start(str);
}
else
{
process->start(str,strList);
}
}
void runCmd::readyRead()
{
putout = process->readAll();
}
head.h
#ifndef HEAD_H
#define HEAD_H
#include
#include
#include
#include "usbcheck.h"
#include "checkudisk.h"
#include "runCmd.h"
#endif // HEAD_H
main.cpp // 这个只有调用
#include
#include "head.h"
#include "checkudisk.h"
class checkUdisk;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
checkUdisk check;
check.started();
return a.exec();
}
主要功能就是 通过 netlink检测 U盘,内存卡 等移动设备挂载 移除,然后通过正则筛选 ,再次通过 umount mount进行操作.