4
4
#include < ctime>
5
5
#include < iomanip>
6
6
#include < sstream>
7
- #include < sys/types.h>
8
- #include < pwd.h>
9
- #include < grp.h>
10
7
#include < cstdlib>
11
8
#include < QTreeWidgetItem>
12
9
#include < QListWidgetItem>
13
- #include < utility>
14
-
10
+ #include < QFileInfo>
11
+ #include < QDateTime>
12
+ #include < QTextStream>
13
+ #include < QDir>
14
+ #include < QProcess>
15
15
#include < cxxabi.h>
16
16
17
17
#define MAXBUFFER 512
18
18
19
- using namespace std ;
20
-
21
- QLdd::QLdd (QString fileName, QString lddDirPath) : _fileName(std::move(fileName)), _link(false ), _lddDirPath(std::move(lddDirPath)) {
22
- memset (&_fstat, 0 , sizeof (_fstat));
23
- int rez = stat64 (_fileName.toLocal8Bit ().data (), &_fstat);
24
- if (rez) {
25
- throw std::runtime_error (" Error stat file" );
26
- }
27
- _link = S_ISLNK (_fstat.st_mode );
28
19
#ifdef __APPLE__
29
- _tmStatus = std::ctime (( const time_t *)&_fstat. st_ctimespec . tv_sec );
30
- _tmAccess = std::ctime (( const time_t *)&_fstat. st_atimespec . tv_sec );
31
- _tmModify = std::ctime (( const time_t *)&_fstat. st_mtimespec . tv_sec );
20
+ # define CMD_LDD " otool -L "
21
+ # define NM " nm -g "
22
+ # define DEPEND_SPLITTER " : "
32
23
#else
33
- _tmStatus = std::ctime (&_fstat. st_ctim . tv_sec );
34
- _tmAccess = std::ctime (&_fstat. st_atim . tv_sec );
35
- _tmModify = std::ctime (&_fstat. st_mtim . tv_sec );
24
+ # define CMD_LDD " ldd "
25
+ # define NM " nm -D "
26
+ # define DEPEND_SPLITTER " => "
36
27
#endif
37
28
38
- _ownerMod.read = S_IRUSR & _fstat.st_mode ;
39
- _ownerMod.write = S_IWUSR & _fstat.st_mode ;
40
- _ownerMod.execute = S_IXUSR & _fstat.st_mode ;
29
+ template <typename Action>
30
+ void execAndDoOnEveryLine (const std::string &execString, const Action &action) {
31
+ std::unique_ptr<FILE, std::function<int (FILE *)>> stream (popen (execString.c_str (), " r" ), pclose);
32
+
33
+ QTextStream nmOutStream (stream.get ());
34
+ QString line;
35
+ int status = 0 ;
36
+ do {
37
+ line = nmOutStream.readLine ().trimmed ();
38
+ if (line.isNull ()) {
39
+ break ;
40
+ }
41
+ action (line);
42
+ } while (!line.isNull ());
43
+ }
44
+
45
+ QLdd::QLdd (QString fileName, QString lddDirPath)
46
+ : _fileName(std::move(fileName)), _fileInfo(_fileName), _link(false ), _lddDirPath(std::move(lddDirPath)) {
47
+ _ownerMod.read = _fileInfo.permission (QFile::ReadOwner);
48
+ _ownerMod.write = _fileInfo.permission (QFile::WriteOwner);
49
+ _ownerMod.execute = _fileInfo.permission (QFile::ExeOwner);
41
50
42
- _groupMod.read = S_IRGRP & _fstat. st_mode ;
43
- _groupMod.write = S_IWGRP & _fstat. st_mode ;
44
- _groupMod.execute = S_IXGRP & _fstat. st_mode ;
51
+ _groupMod.read = _fileInfo. permission (QFile::ReadGroup) ;
52
+ _groupMod.write = _fileInfo. permission (QFile::WriteGroup) ;
53
+ _groupMod.execute = _fileInfo. permission (QFile::ExeGroup) ;
45
54
46
- _otherMod.read = S_IROTH & _fstat. st_mode ;
47
- _otherMod.write = S_IWOTH & _fstat. st_mode ;
48
- _otherMod.execute = S_IXOTH & _fstat. st_mode ;
55
+ _otherMod.read = _fileInfo. permission (QFile::ReadOther) ;
56
+ _otherMod.write = _fileInfo. permission (QFile::WriteOther) ;
57
+ _otherMod.execute = _fileInfo. permission (QFile::ExeOther) ;
49
58
50
- struct passwd *pw = getpwuid (_fstat.st_uid );
51
- _ownerName.append (pw->pw_name );
52
- struct group *gr = getgrgid (_fstat.st_gid );
53
- _groupName.append (gr->gr_name );
54
- }
59
+ _tmStatus = _fileInfo.created ().toString ();
60
+ _tmAccess = _fileInfo.lastRead ().toString ();
61
+ _tmModify = _fileInfo.lastModified ().toString ();
55
62
56
- QLdd::~QLdd () {}
63
+ _link = _fileInfo. isSymLink ();
57
64
58
- size_t QLdd::getFileSize () { return _fstat.st_size ; }
65
+ _ownerName.append (_fileInfo.owner ());
66
+ _groupName.append (_fileInfo.group ());
59
67
60
- const QString &QLdd::getStringFileSize () {
61
- auto size = static_cast <double >(_fstat.st_size );
68
+ auto size = static_cast <double >(_fileInfo.size ());
62
69
int i = 0 ;
63
70
const char *units[] = {" B" , " kB" , " MB" , " GB" , " TB" , " PB" , " EB" , " ZB" , " YB" };
64
71
while (size > 1024 ) {
@@ -69,41 +76,32 @@ const QString &QLdd::getStringFileSize() {
69
76
sprintf (buf, " %.*f %s" , i, size, units[i]);
70
77
_fileSize.clear ();
71
78
_fileSize.append (buf);
72
- return _fileSize;
73
79
}
74
80
81
+ QLdd::~QLdd () {}
82
+
83
+ uint64_t QLdd::getFileSize () const { return _fileInfo.size (); }
84
+
85
+ const QString &QLdd::getStringFileSize () const { return _fileSize; }
86
+
75
87
void QLdd::fillDependency (QTreeWidget &treeWidget) {
76
88
treeWidget.clear ();
77
- QTreeWidgetItem *item = nullptr ;
78
89
79
- char buffer[MAXBUFFER] = {0 };
80
- stringstream ss;
81
- QString path = getPathOfBinary ();
90
+ std::stringstream ss;
91
+
92
+ QDir::setCurrent (getPathOfBinary ());
93
+ ss << CMD_LDD << " " << _fileName.toStdString ();
82
94
83
- chdir (path.toStdString ().c_str ());
84
- #ifdef __APPLE__
85
- ss << " otool -L " << _fileName.toStdString ();
86
- #else
87
- ss << " ldd " << _fileName.toStdString ();
88
- #endif
89
- FILE *stream = popen (ss.str ().c_str (), " r" );
90
- QString buf;
91
- QStringList sl;
92
- #ifdef __APPLE__
93
95
bool flag = false ;
94
- # endif
95
- while ( fgets (buffer, MAXBUFFER, stream) != nullptr ) {
96
- buf. clear () ;
97
- buf = QString::fromLocal8Bit (buffer). trimmed () ;
98
- if (!buf .contains (" =>" ) && buf .contains (" (0x" )) {
99
- sl = buf .split (" (" );
96
+
97
+ execAndDoOnEveryLine (ss. str (), [&flag, &treeWidget]( const QString &line ) {
98
+ QTreeWidgetItem *item = nullptr ;
99
+ QStringList sl ;
100
+ if (!line .contains (" =>" ) && line .contains (" (0x" )) {
101
+ sl = line .split (" (" );
100
102
sl.removeLast ();
101
103
} else {
102
- #ifdef __APPLE__
103
- sl = buf.split (" :" );
104
- #else
105
- sl = buf.split (" =>" );
106
- #endif
104
+ sl = line.split (DEPEND_SPLITTER);
107
105
}
108
106
int i = 0 ;
109
107
for (const QString &v : sl) {
@@ -141,48 +139,34 @@ void QLdd::fillDependency(QTreeWidget &treeWidget) {
141
139
sl.removeFirst ();
142
140
QTreeWidgetItem *tmp = item;
143
141
QColor redC (" red" );
144
- for (const QString &v: sl) {
142
+ for (const QString &v : sl) {
145
143
if (!v.trimmed ().isEmpty ()) {
146
144
if (v.contains (" not found" )) {
147
145
tmp->setTextColor (0 , redC);
148
146
tmp->setText (0 , tmp->text (0 ) + " " + v);
149
147
tmp->setToolTip (0 , tmp->text (0 ));
150
148
} else {
151
- QTreeWidgetItem *nitm = new QTreeWidgetItem (tmp);
149
+ auto *nitm = new QTreeWidgetItem (tmp);
152
150
nitm->setText (0 , v);
153
151
nitm->setToolTip (0 , v);
154
152
tmp = nitm;
155
153
}
156
154
}
157
155
}
156
+ });
158
157
159
- memset (&buffer, 0 , sizeof (buffer));
160
- }
161
- pclose (stream);
162
- chdir (_lddDirPath.toStdString ().c_str ());
158
+ QDir::setCurrent (_lddDirPath);
163
159
}
164
160
165
161
void QLdd::fillExportTable (QListWidget &listWidget) {
166
162
listWidget.clear ();
163
+ int status = 0 ;
164
+ std::stringstream ss;
165
+ ss << NM << " " << _fileName.toStdString () << " | grep \\ T\\ " ;
167
166
168
- char buffer[MAXBUFFER] = {0 };
169
- stringstream ss;
170
- #ifdef __APPLE__
171
- ss << " nm -g "
172
- #else
173
- ss << " nm -D "
174
- #endif
175
- << _fileName.toStdString () << " | grep \\ T\\ " ;
176
- FILE *stream = popen (ss.str ().c_str (), " r" );
177
- QString buf;
178
- QStringList sl;
179
-
180
- while (fgets (buffer, MAXBUFFER, stream) != nullptr ) {
181
- buf.clear ();
182
- buf = QString::fromLocal8Bit (buffer).trimmed ();
183
- QStringList info = buf.split (" " );
167
+ execAndDoOnEveryLine (ss.str (), [&status, &listWidget](const QString &line) {
168
+ QStringList info = line.split (" " );
184
169
QString demangled (info.at (2 ));
185
- int status = 0 ;
186
170
char *realname = abi::__cxa_demangle (info.at (2 ).toStdString ().c_str (), nullptr , nullptr , &status);
187
171
if (realname) {
188
172
demangled = QString::fromLocal8Bit (realname);
@@ -192,56 +176,28 @@ void QLdd::fillExportTable(QListWidget &listWidget) {
192
176
demangled.replace (" std::basic_string<char, std::char_traits<char>, std::allocator<char> >" , " std::string" );
193
177
}
194
178
listWidget.addItem (new QListWidgetItem (info.at (0 ) + " " + demangled));
195
-
196
- memset (&buffer, 0 , sizeof (buffer));
197
- }
198
- pclose (stream);
179
+ });
199
180
}
200
181
201
- QString QLdd::getPathOfBinary () {
202
- string fullPath = _fileName.toStdString ();
203
- size_t cwdLen = 0 ;
204
- for (size_t i = fullPath.size (); i > 0 ; i--) {
205
- if ((fullPath.c_str ()[i] == ' /' ) || (fullPath.c_str ()[i] == ' \\ ' )) {
206
- cwdLen = i;
207
- fullPath = fullPath.substr (0 , cwdLen);
208
- break ;
209
- }
210
- }
211
- return QString::fromStdString (fullPath);
212
- }
182
+ QString QLdd::getPathOfBinary () { return _fileInfo.absolutePath (); }
213
183
214
- QString QLdd::getBinaryName () {
215
- string fullPath = _fileName.toStdString ();
216
- size_t cwdLen = 0 ;
217
- for (size_t i = fullPath.size (); i > 0 ; i--) {
218
- if ((fullPath.c_str ()[i] == ' /' ) || (fullPath.c_str ()[i] == ' \\ ' )) {
219
- cwdLen = i;
220
- fullPath = fullPath.substr (cwdLen + 1 , fullPath.size ());
221
- break ;
222
- }
223
- }
224
- return QString::fromStdString (fullPath);
225
- }
184
+ QString QLdd::getBinaryName () { return _fileInfo.fileName (); }
226
185
227
186
const QString &QLdd::getStatusTime () { return _tmStatus; }
228
187
229
188
const QString &QLdd::getModifyTime () { return _tmModify; }
230
189
231
190
QString QLdd::getInfo () {
232
191
char buffer[MAXBUFFER] = {0 };
233
- stringstream ss;
192
+ std:: stringstream ss;
234
193
ss << " file " << _fileName.toStdString ();
235
- FILE *stream = popen (ss.str ().c_str (), " r" );
236
194
QString buf;
237
- while (fgets (buffer, MAXBUFFER, stream) != nullptr ) {
238
- buf.append (QString::fromLocal8Bit (buffer));
239
- memset (&buffer, 0 , sizeof (buffer));
240
- }
241
- pclose (stream);
195
+ execAndDoOnEveryLine (ss.str (), [&buf](const QString &line) { buf.append (line); });
242
196
QStringList slTmp = buf.split (" ," );
243
197
buf.clear ();
244
- for (const QString &v: slTmp) { buf.append (v.trimmed ()).append (" \n " ); }
198
+ for (const QString &v : slTmp) {
199
+ buf.append (v.trimmed ()).append (" \n " );
200
+ }
245
201
return buf;
246
202
}
247
203
const QMOD &QLdd::getOwnerMod () const { return _ownerMod; }
0 commit comments