QT全自动检测,挂载U盘

  手里有个树莓派3B想来还是做局域网的共享服务 以及远程下载机靠谱.由于机械盘不稳定,经常会出现掉盘, 重复挂载问题.

刚好会一点Qt,写个挂载程序,加个开机启动就完事了.

 代码主要用到内核的通信机制 netLink用于检测U盘挂载 卸载事件.

Qt则没有使用界面 直接后台运行即可,当然加个sh的守护进程也必不可少.

U盘检测代码:

checkudisk.h //用于检测U盘等设备 用于挂载卸载
#ifndef CHECKUDISK_H
#define CHECKUDISK_H

#include <QThread>
#include <QStringList>
#include <QString>
#include <QFile>
#include <QFileInfo>
#include <QDir>
#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<<rx.cap(0);
        pos += rx.matchedLength();
    }

    /* 检测到的 sd* 存于fdisk_list列表 */
    if(fdisk_list.length() == 0)
        fdiskU = false;
    else
        fdiskU = true;

    /* df -h 检查对应的U盘是否挂载; */
    checkResult.clear();
    runCmd chechDf;
    QString df = "df";
    QStringList df_list;
    df_list<<"-h";
    chechDf.setCmd(df,df_list);
    checkResult = chechDf.getString();


    df_list.clear();
    QRegExp rz("/dev/sd[a-z][0-9]{1,2}");
    pos = 0;
    while( (pos = rz.indexIn(checkResult,pos)) != -1 )
    {
        df_list<<rz.cap(0);
        pos += rz.matchedLength();
    }

    if(df_list.length() == 0)
        dfU = false;
    else
        dfU = true;

    if(fdiskU == true)
    {
        if(dfU == false)
        {
            for(int i=0; i<fdisk_list.length();i++)
            {
                path = QString("/mnt/%1").arg(fdisk_list.at(i));
                dir.mkdir(path);
                cmd = QString("mount /dev/%1 /mnt/%1").arg(fdisk_list.at(i));
                system(cmd.toStdString().c_str());
            }
        }
    }


    thread->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<strList.length();i++)
        {
            path = QString("/mnt/%1").arg(strList.at(i));
            cmd = QString("umount /mnt/%1").arg(strList.at(i));
            system(cmd.toStdString().c_str());
            dir.rmdir(path);
        }
    }
    else if(statue == 1)
    {
        for(int i=0; i<strList.length();i++)
        {
            path = QString("/mnt/%1").arg(strList.at(i));
            dir.mkdir(path);
            usbPathList<<path;
            cmd = QString("mount /dev/%1 /mnt/%1").arg(strList.at(i));
            system(cmd.toStdString().c_str());
        }
    }
    else
    {
        for(int i=0; i<usbPathList.length();i++)
        {
            dir.rmdir(usbPathList.at(i));
        }
    }
}
usbcheck.h // 通过netlink检测硬件设备的挂载 移除
#ifndef USBCHECK_H
#define USBCHECK_H

#include <QObject>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>

//#include <QDebug>
#include <QString>
#include <QStringList>
#include <asm/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>

#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<<rx.cap(0);
        pos += rx.matchedLength();
    }

    if(statue == "remove")
    {
        /* 检测到usb移除 */
        emit usbName(resultList,0);
    }
    else if(statue == "add")
    {
        /* 检测到usb挂载 */
        emit usbName(resultList,1);
    }
}

runCmd.h //为了执行命令 写了proc去执行命令
#ifndef RUNCMD_H
#define RUNCMD_H

#include <QProcess>
#include <QDebug>

#include <QObject>

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 <QObject>
#include <QString>
#include <QThread>
#include "usbcheck.h"
#include "checkudisk.h"
#include "runCmd.h"

#endif // HEAD_H

main.cpp  // 这个只有调用

 

#include <QCoreApplication>
#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进行操作.

 

  • 5
    点赞
  • 19
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

smaller_maple

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值