Orb/Doxygen/qtools/qfileinfo_unix.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /****************************************************************************
       
     2 ** 
       
     3 **
       
     4 ** Implementation of QFileInfo class
       
     5 **
       
     6 ** Created : 950628
       
     7 **
       
     8 ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
       
     9 **
       
    10 ** This file is part of the tools module of the Qt GUI Toolkit.
       
    11 **
       
    12 ** This file may be distributed under the terms of the Q Public License
       
    13 ** as defined by Trolltech AS of Norway and appearing in the file
       
    14 ** LICENSE.QPL included in the packaging of this file.
       
    15 **
       
    16 ** This file may be distributed and/or modified under the terms of the
       
    17 ** GNU General Public License version 2 as published by the Free Software
       
    18 ** Foundation and appearing in the file LICENSE.GPL included in the
       
    19 ** packaging of this file.
       
    20 **
       
    21 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
       
    22 ** licenses for Unix/X11 or for Qt/Embedded may use this file in accordance
       
    23 ** with the Qt Commercial License Agreement provided with the Software.
       
    24 **
       
    25 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
       
    26 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
       
    27 **
       
    28 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
       
    29 **   information about Qt Commercial License Agreements.
       
    30 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
       
    31 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
       
    32 **
       
    33 ** Contact info@trolltech.com if any conditions of this licensing are
       
    34 ** not clear to you.
       
    35 **
       
    36 **********************************************************************/
       
    37 
       
    38 #include "qglobal.h"
       
    39 
       
    40 #if defined(_OS_SUN_)
       
    41 #define readlink _qt_hide_readlink
       
    42 #endif
       
    43 
       
    44 #include <pwd.h>
       
    45 #include <grp.h>
       
    46 
       
    47 #include "qfileinfo.h"
       
    48 #include "qfiledefs_p.h"
       
    49 #include "qdatetime.h"
       
    50 #include "qdir.h"
       
    51 
       
    52 #if defined(_OS_SUN_)
       
    53 #undef readlink
       
    54 extern "C" int readlink( const char *, void *, uint );
       
    55 #endif
       
    56 
       
    57 
       
    58 void QFileInfo::slashify( QString& )
       
    59 {
       
    60     return;
       
    61 }
       
    62 
       
    63 
       
    64 void QFileInfo::makeAbs( QString & )
       
    65 {
       
    66     return;
       
    67 }
       
    68 
       
    69 extern bool qt_file_access( const QString& fn, int t );
       
    70 
       
    71 /*!
       
    72   Returns TRUE if we are pointing to a real file.
       
    73   \sa isDir(), isSymLink()
       
    74 */
       
    75 bool QFileInfo::isFile() const
       
    76 {
       
    77     if ( !fic || !cache )
       
    78 	doStat();
       
    79     return fic ? (fic->st.st_mode & STAT_MASK) == STAT_REG : FALSE;
       
    80 }
       
    81 
       
    82 /*!
       
    83   Returns TRUE if we are pointing to a directory or a symbolic link to
       
    84   a directory.
       
    85   \sa isFile(), isSymLink()
       
    86 */
       
    87 
       
    88 bool QFileInfo::isDir() const
       
    89 {
       
    90     if ( !fic || !cache )
       
    91 	doStat();
       
    92     return fic ? (fic->st.st_mode & STAT_MASK) == STAT_DIR : FALSE;
       
    93 }
       
    94 
       
    95 /*!
       
    96   Returns TRUE if we are pointing to a symbolic link.
       
    97   \sa isFile(), isDir(), readLink()
       
    98 */
       
    99 
       
   100 bool QFileInfo::isSymLink() const
       
   101 {
       
   102     if ( !fic || !cache )
       
   103 	doStat();
       
   104     return fic ? fic->isSymLink : FALSE;
       
   105 }
       
   106 
       
   107 
       
   108 /*!
       
   109   Returns the name a symlink points to, or a null QString if the
       
   110   object does not refer to a symbolic link.
       
   111 
       
   112   This name may not represent an existing file; it is only a string.
       
   113   QFileInfo::exists() returns TRUE if the symlink points to an
       
   114   existing file.
       
   115 
       
   116   \sa exists(), isSymLink(), isDir(), isFile()
       
   117 */
       
   118 
       
   119 QString QFileInfo::readLink() const
       
   120 {
       
   121     QString r;
       
   122 
       
   123 #if defined(_OS_UNIX_) && !defined(_OS_OS2EMX_)
       
   124     char s[PATH_MAX+1];
       
   125     if ( !isSymLink() )
       
   126 	return QString();
       
   127     int len = readlink( QFile::encodeName(fn).data(), s, PATH_MAX );
       
   128     if ( len >= 0 ) {
       
   129 	s[len] = '\0';
       
   130 	r = QFile::decodeName(s);
       
   131     }
       
   132 #endif
       
   133 
       
   134     return r;
       
   135 }
       
   136 
       
   137 static const uint nobodyID = (uint) -2;
       
   138 
       
   139 /*!
       
   140   Returns the owner of the file.
       
   141 
       
   142   On systems where files do not have owners this function returns 0.
       
   143 
       
   144   Note that this function can be time-consuming under UNIX. (in the order
       
   145   of milliseconds on a 486 DX2/66 running Linux).
       
   146 
       
   147   \sa ownerId(), group(), groupId()
       
   148 */
       
   149 
       
   150 QString QFileInfo::owner() const
       
   151 {
       
   152     passwd *pw = getpwuid( ownerId() );
       
   153     if ( pw )
       
   154 	return QFile::decodeName( pw->pw_name );
       
   155     return QString::null;
       
   156 }
       
   157 
       
   158 /*!
       
   159   Returns the id of the owner of the file.
       
   160 
       
   161   On systems where files do not have owners this function returns ((uint) -2).
       
   162 
       
   163   \sa owner(), group(), groupId()
       
   164 */
       
   165 
       
   166 uint QFileInfo::ownerId() const
       
   167 {
       
   168     if ( !fic || !cache )
       
   169 	doStat();
       
   170     if ( fic )
       
   171 	return fic->st.st_uid;
       
   172     return nobodyID;
       
   173 }
       
   174 
       
   175 /*!
       
   176   Returns the group the file belongs to.
       
   177 
       
   178   On systems where files do not have groups this function always
       
   179   returns 0.
       
   180 
       
   181   Note that this function can be time-consuming under UNIX (in the order of
       
   182   milliseconds on a 486 DX2/66 running Linux).
       
   183 
       
   184   \sa groupId(), owner(), ownerId()
       
   185 */
       
   186 
       
   187 QString QFileInfo::group() const
       
   188 {
       
   189     struct group *gr = getgrgid( groupId() );
       
   190     if ( gr )
       
   191 	return QFile::decodeName( gr->gr_name );
       
   192     return QString::null;
       
   193 }
       
   194 
       
   195 /*!
       
   196   Returns the id of the group the file belongs to.
       
   197 
       
   198   On systems where files do not have groups this function always
       
   199   returns ((uind) -2).
       
   200 
       
   201   \sa group(), owner(), ownerId()
       
   202 */
       
   203 
       
   204 uint QFileInfo::groupId() const
       
   205 {
       
   206     if ( !fic || !cache )
       
   207 	doStat();
       
   208     if ( fic )
       
   209 	return fic->st.st_gid;
       
   210     return nobodyID;
       
   211 }
       
   212 
       
   213 
       
   214 /*!
       
   215   \fn bool QFileInfo::permission( int permissionSpec ) const
       
   216 
       
   217   Tests for file permissions.  The \e permissionSpec argument can be several
       
   218   flags of type PermissionSpec or'ed together to check for permission
       
   219   combinations.
       
   220 
       
   221   On systems where files do not have permissions this function always
       
   222   returns TRUE.
       
   223 
       
   224   Example:
       
   225   \code
       
   226     QFileInfo fi( "/tmp/tonsils" );
       
   227     if ( fi.permission( QFileInfo::WriteUser | QFileInfo::ReadGroup ) )
       
   228 	qWarning( "Tonsils can be changed by me, and the group can read them.");
       
   229     if ( fi.permission( QFileInfo::WriteGroup | QFileInfo::WriteOther ) )
       
   230 	qWarning( "Danger! Tonsils can be changed by the group or others!" );
       
   231   \endcode
       
   232 
       
   233   \sa isReadable(), isWritable(), isExecutable()
       
   234 */
       
   235 
       
   236 bool QFileInfo::permission( int permissionSpec ) const
       
   237 {
       
   238     if ( !fic || !cache )
       
   239 	doStat();
       
   240     if ( fic ) {
       
   241 	uint mask = 0;
       
   242 	if ( permissionSpec & ReadUser)
       
   243 	    mask |= S_IRUSR;
       
   244 	if ( permissionSpec & WriteUser)
       
   245 	    mask |= S_IWUSR;
       
   246 	if ( permissionSpec & ExeUser)
       
   247 	    mask |= S_IXUSR;
       
   248 	if ( permissionSpec & ReadGroup)
       
   249 	    mask |= S_IRGRP;
       
   250 	if ( permissionSpec & WriteGroup)
       
   251 	    mask |= S_IWGRP;
       
   252 	if ( permissionSpec & ExeGroup)
       
   253 	    mask |= S_IXGRP;
       
   254 	if ( permissionSpec & ReadOther)
       
   255 	    mask |= S_IROTH;
       
   256 	if ( permissionSpec & WriteOther)
       
   257 	    mask |= S_IWOTH;
       
   258 	if ( permissionSpec & ExeOther)
       
   259 	    mask |= S_IXOTH;
       
   260 	if ( mask ) {
       
   261 	   return (fic->st.st_mode & mask) == mask;
       
   262 	} else {
       
   263 #if defined(CHECK_NULL)
       
   264 	   qWarning( "QFileInfo::permission: permissionSpec is 0" );
       
   265 #endif
       
   266 	   return TRUE;
       
   267 	}
       
   268     } else {
       
   269 	return FALSE;
       
   270     }
       
   271 }
       
   272 
       
   273 /*!
       
   274   Returns the file size in bytes, or 0 if the file does not exist if the size
       
   275   cannot be fetched.
       
   276 */
       
   277 
       
   278 uint QFileInfo::size() const
       
   279 {
       
   280     if ( !fic || !cache )
       
   281 	doStat();
       
   282     if ( fic )
       
   283 	return (uint)fic->st.st_size;
       
   284     else
       
   285 	return 0;
       
   286 }
       
   287 
       
   288 
       
   289 /*!
       
   290   Returns the date and time when the file was last modified.
       
   291   \sa lastRead()
       
   292 */
       
   293 
       
   294 QDateTime QFileInfo::lastModified() const
       
   295 {
       
   296     QDateTime dt;
       
   297     if ( !fic || !cache )
       
   298 	doStat();
       
   299     if ( fic )
       
   300 	dt.setTime_t( fic->st.st_mtime );
       
   301     return dt;
       
   302 }
       
   303 
       
   304 /*!
       
   305   Returns the date and time when the file was last read (accessed).
       
   306 
       
   307   On systems that do not support last read times, the modification time is
       
   308   returned.
       
   309 
       
   310   \sa lastModified()
       
   311 */
       
   312 
       
   313 QDateTime QFileInfo::lastRead() const
       
   314 {
       
   315     QDateTime dt;
       
   316     if ( !fic || !cache )
       
   317 	doStat();
       
   318     if ( fic )
       
   319 	dt.setTime_t( fic->st.st_atime );
       
   320     return dt;
       
   321 }
       
   322 
       
   323 
       
   324 void QFileInfo::doStat() const
       
   325 {
       
   326     QFileInfo *that = ((QFileInfo*)this);	// mutable function
       
   327     if ( !that->fic )
       
   328 	that->fic = new QFileInfoCache;
       
   329     STATBUF *b = &that->fic->st;
       
   330     that->fic->isSymLink = FALSE;
       
   331 
       
   332 #if defined(_OS_UNIX_) && defined(S_IFLNK)
       
   333     if ( ::lstat(QFile::encodeName(fn),b) == 0 ) {
       
   334 	if ( S_ISLNK( b->st_mode ) )
       
   335 	    that->fic->isSymLink = TRUE;
       
   336 	else
       
   337 	    return;
       
   338     }
       
   339 #endif
       
   340     int r;
       
   341 
       
   342     r = STAT( QFile::encodeName(fn), b );
       
   343 
       
   344     if ( r != 0 ) {
       
   345 	delete that->fic;
       
   346 	that->fic = 0;
       
   347     }
       
   348 }
       
   349 
       
   350 /*!
       
   351   Returns the directory path of the file.
       
   352 
       
   353   If \e absPath is TRUE an absolute path is always returned.
       
   354 
       
   355   \sa dir(), filePath(), fileName(), isRelative()
       
   356 */
       
   357 #ifndef QT_NO_DIR
       
   358 QString QFileInfo::dirPath( bool absPath ) const
       
   359 {
       
   360     QString s;
       
   361     if ( absPath )
       
   362 	s = absFilePath();
       
   363     else
       
   364 	s = fn;
       
   365     int pos = s.findRev( '/' );
       
   366     if ( pos == -1 ) {
       
   367 	return QString::fromLatin1(".");
       
   368     } else {
       
   369 	if ( pos == 0 )
       
   370 	    return QString::fromLatin1( "/" );
       
   371 	return s.left( pos );
       
   372     }
       
   373 }
       
   374 #endif
       
   375 /*!
       
   376   Returns the name of the file, the file path is not included.
       
   377 
       
   378   Example:
       
   379   \code
       
   380      QFileInfo fi( "/tmp/abdomen.lower" );
       
   381      QString name = fi.fileName();		// name = "abdomen.lower"
       
   382   \endcode
       
   383 
       
   384   \sa isRelative(), filePath(), baseName(), extension()
       
   385 */
       
   386 
       
   387 QString QFileInfo::fileName() const
       
   388 {
       
   389     int p = fn.findRev( '/' );
       
   390     if ( p == -1 ) {
       
   391 	return fn;
       
   392     } else {
       
   393 	return fn.mid(p+1);
       
   394     }
       
   395 }
       
   396 
       
   397 /*!
       
   398   Returns the absolute path name.
       
   399 
       
   400   The absolute path name is the file name including the absolute path. If
       
   401   the QFileInfo is absolute (i.e. not relative) this function will return
       
   402   the same string as filePath().
       
   403 
       
   404   Note that this function can be time-consuming under UNIX. (in the order
       
   405   of milliseconds on a 486 DX2/66 running Linux).
       
   406 
       
   407   \sa isRelative(), filePath()
       
   408 */
       
   409 #ifndef QT_NO_DIR
       
   410 QString QFileInfo::absFilePath() const
       
   411 {
       
   412     if ( QDir::isRelativePath(fn) ) {
       
   413 	QString tmp = QDir::currentDirPath();
       
   414 	tmp += '/';
       
   415 	tmp += fn;
       
   416 	makeAbs( tmp );
       
   417 	return QDir::cleanDirPath( tmp );
       
   418     } else {
       
   419 	QString tmp = fn;
       
   420 	makeAbs( tmp );
       
   421 	return QDir::cleanDirPath( tmp );
       
   422     }
       
   423 
       
   424 }
       
   425 #endif