admin管理员组文章数量:1654698
手里有个树莓派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进行操作.
版权声明:本文标题:QT全自动检测,挂载U盘 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1729681787a1209892.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论