00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "qplatformdefs.h"
00039 #include "qdir.h"
00040
00041 #ifndef QT_NO_DIR
00042
00043 #include "qdir_p.h"
00044 #include "qfileinfo.h"
00045 #include "qregexp.h"
00046 #include "qstringlist.h"
00047
00048 #ifdef QT_THREAD_SUPPORT
00049 # include <private/qmutexpool_p.h>
00050 #endif // QT_THREAD_SUPPORT
00051
00052 #include <stdlib.h>
00053 #include <limits.h>
00054 #include <errno.h>
00055
00056
00057 void QDir::slashify( QString& )
00058 {
00059 }
00060
00061 QString QDir::homeDirPath()
00062 {
00063 QString d;
00064 d = QFile::decodeName(getenv("HOME"));
00065 slashify( d );
00066 if ( d.isNull() )
00067 d = rootDirPath();
00068 return d;
00069 }
00070
00071 QString QDir::canonicalPath() const
00072 {
00073 QString r;
00074 char cur[PATH_MAX+1];
00075 if ( ::getcwd( cur, PATH_MAX ) ) {
00076 char tmp[PATH_MAX+1];
00077 if( ::realpath( QFile::encodeName( dPath ), tmp ) )
00078 r = QFile::decodeName( tmp );
00079 slashify( r );
00080
00081
00082 ::chdir( cur );
00083 }
00084 return r;
00085 }
00086
00087 bool QDir::mkdir( const QString &dirName, bool acceptAbsPath ) const
00088 {
00089 #if defined(Q_OS_MACX) // Mac X doesn't support trailing /'s
00090 QString name = dirName;
00091 if (dirName[dirName.length() - 1] == "/")
00092 name = dirName.left( dirName.length() - 1 );
00093 int status =
00094 ::mkdir( QFile::encodeName(filePath(name,acceptAbsPath)), 0777 );
00095 #else
00096 int status =
00097 ::mkdir( QFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 );
00098 #endif
00099 return status == 0;
00100 }
00101
00102 bool QDir::rmdir( const QString &dirName, bool acceptAbsPath ) const
00103 {
00104 return ::rmdir( QFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
00105 }
00106
00107 bool QDir::isReadable() const
00108 {
00109 return ::access( QFile::encodeName(dPath), R_OK | X_OK ) == 0;
00110 }
00111
00112 bool QDir::isRoot() const
00113 {
00114 return dPath == QString::fromLatin1("/");
00115 }
00116
00117 bool QDir::rename( const QString &name, const QString &newName,
00118 bool acceptAbsPaths )
00119 {
00120 if ( name.isEmpty() || newName.isEmpty() ) {
00121 #if defined(QT_CHECK_NULL)
00122 qWarning( "QDir::rename: Empty or null file name(s)" );
00123 #endif
00124 return FALSE;
00125 }
00126 QString fn1 = filePath( name, acceptAbsPaths );
00127 QString fn2 = filePath( newName, acceptAbsPaths );
00128 return ::rename( QFile::encodeName(fn1),
00129 QFile::encodeName(fn2) ) == 0;
00130 }
00131
00132 bool QDir::setCurrent( const QString &path )
00133 {
00134 int r;
00135 r = ::chdir( QFile::encodeName(path) );
00136 return r >= 0;
00137 }
00138
00139 QString QDir::currentDirPath()
00140 {
00141 QString result;
00142
00143 struct stat st;
00144 if ( ::stat( ".", &st ) == 0 ) {
00145 char currentName[PATH_MAX+1];
00146 if ( ::getcwd( currentName, PATH_MAX ) )
00147 result = QFile::decodeName(currentName);
00148 #if defined(QT_DEBUG)
00149 if ( result.isNull() )
00150 qWarning( "QDir::currentDirPath: getcwd() failed" );
00151 #endif
00152 } else {
00153 #if defined(QT_DEBUG)
00154 qWarning( "QDir::currentDirPath: stat(\".\") failed" );
00155 #endif
00156 }
00157 slashify( result );
00158 return result;
00159 }
00160
00161 QString QDir::rootDirPath()
00162 {
00163 QString d = QString::fromLatin1( "/" );
00164 return d;
00165 }
00166
00167 bool QDir::isRelativePath( const QString &path )
00168 {
00169 int len = path.length();
00170 if ( len == 0 )
00171 return TRUE;
00172 return path[0] != '/';
00173 }
00174
00175 bool QDir::readDirEntries( const QString &nameFilter,
00176 int filterSpec, int sortSpec )
00177 {
00178 int i;
00179 if ( !fList ) {
00180 fList = new QStringList;
00181 Q_CHECK_PTR( fList );
00182 fiList = new QFileInfoList;
00183 Q_CHECK_PTR( fiList );
00184 fiList->setAutoDelete( TRUE );
00185 } else {
00186 fList->clear();
00187 fiList->clear();
00188 }
00189
00190 QValueList<QRegExp> filters = qt_makeFilterList( nameFilter );
00191
00192 bool doDirs = (filterSpec & Dirs) != 0;
00193 bool doFiles = (filterSpec & Files) != 0;
00194 bool noSymLinks = (filterSpec & NoSymLinks) != 0;
00195 bool doReadable = (filterSpec & Readable) != 0;
00196 bool doWritable = (filterSpec & Writable) != 0;
00197 bool doExecable = (filterSpec & Executable) != 0;
00198 bool doHidden = (filterSpec & Hidden) != 0;
00199 bool doSystem = (filterSpec & System) != 0;
00200
00201 QFileInfo fi;
00202 DIR *dir;
00203 dirent *file;
00204
00205 dir = opendir( QFile::encodeName(dPath) );
00206 if ( !dir )
00207 return FALSE;
00208
00209 #if defined(QT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
00210 union {
00211 struct dirent mt_file;
00212 char b[sizeof(struct dirent) + MAXNAMLEN + 1];
00213 } u;
00214 while ( readdir_r(dir, &u.mt_file, &file ) == 0 && file )
00215 #else
00216 while ( (file = readdir(dir)) )
00217 #endif // QT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
00218 {
00219 QString fn = QFile::decodeName(file->d_name);
00220 fi.setFile( *this, fn );
00221 if ( !qt_matchFilterList(filters, fn) && !(allDirs && fi.isDir()) )
00222 continue;
00223 if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) ||
00224 (doSystem && (!fi.isFile() && !fi.isDir())) ) {
00225 if ( noSymLinks && fi.isSymLink() )
00226 continue;
00227 if ( (filterSpec & RWEMask) != 0 )
00228 if ( (doReadable && !fi.isReadable()) ||
00229 (doWritable && !fi.isWritable()) ||
00230 (doExecable && !fi.isExecutable()) )
00231 continue;
00232 if ( !doHidden && fn[0] == '.' &&
00233 fn != QString::fromLatin1(".")
00234 && fn != QString::fromLatin1("..") )
00235 continue;
00236 fiList->append( new QFileInfo( fi ) );
00237 }
00238 }
00239 if ( closedir(dir) != 0 ) {
00240 #if defined(QT_CHECK_NULL)
00241 qWarning( "QDir::readDirEntries: Cannot close the directory: %s",
00242 dPath.local8Bit().data() );
00243 #endif
00244 }
00245
00246
00247 if(fiList->count()) {
00248 QDirSortItem* si= new QDirSortItem[fiList->count()];
00249 QFileInfo* itm;
00250 i=0;
00251 for (itm = fiList->first(); itm; itm = fiList->next())
00252 si[i++].item = itm;
00253 qt_cmp_si_sortSpec = sortSpec;
00254 qsort( si, i, sizeof(si[0]), qt_cmp_si );
00255
00256 fiList->setAutoDelete( FALSE );
00257 fiList->clear();
00258 int j;
00259 for ( j=0; j<i; j++ ) {
00260 fiList->append( si[j].item );
00261 fList->append( si[j].item->fileName() );
00262 }
00263 delete [] si;
00264 fiList->setAutoDelete( TRUE );
00265 }
00266
00267 if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
00268 nameFilter == nameFilt )
00269 dirty = FALSE;
00270 else
00271 dirty = TRUE;
00272 return TRUE;
00273 }
00274
00275 const QFileInfoList * QDir::drives()
00276 {
00277
00278
00279 static QFileInfoList * knownMemoryLeak = 0;
00280
00281 if ( !knownMemoryLeak ) {
00282
00283 #ifdef QT_THREAD_SUPPORT
00284 QMutexLocker locker( qt_global_mutexpool ?
00285 qt_global_mutexpool->get( &knownMemoryLeak ) : 0 );
00286 #endif // QT_THREAD_SUPPORT
00287
00288 if ( !knownMemoryLeak ) {
00289 knownMemoryLeak = new QFileInfoList;
00290
00291 knownMemoryLeak->append( new QFileInfo( rootDirPath() ) );
00292 }
00293 }
00294
00295 return knownMemoryLeak;
00296 }
00297 #endif //QT_NO_DIR