QT全自动检测,挂载U盘

  手里有个树莓派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进行操作.

 

你可能感兴趣的:(Qt学习,linux,netlink,Qt检测U盘,Qt自动挂载U盘)