Commit 7f26a51c authored by Nils Maier's avatar Nils Maier
Browse files

Bug 389087 - nsILocalFileUnix affected by 32bit stat/statvfs/truncate,...

Bug 389087 - nsILocalFileUnix affected by 32bit stat/statvfs/truncate, therefore does not work with large files; r+sr=benjamin
parent f3636c5d
Loading
Loading
Loading
Loading
+34 −53
Original line number Diff line number Diff line
@@ -275,21 +275,12 @@ nsLocalFile::nsLocalFileConstructor(nsISupports *outer,

PRBool 
nsLocalFile::FillStatCache() {
#ifdef HAVE_STAT64
    if (stat64(mPath.get(), &mCachedStat) == -1) {
    if (STAT(mPath.get(), &mCachedStat) == -1) {
        // try lstat it may be a symlink
        if (lstat64(mPath.get(), &mCachedStat) == -1) {
        if (LSTAT(mPath.get(), &mCachedStat) == -1) {
            return PR_FALSE;
        }
    }
#else
    if (stat(mPath.get(), &mCachedStat) == -1) {
        // try lstat it may be a symlink
        if (lstat(mPath.get(), &mCachedStat) == -1) {
            return PR_FALSE;
        }
    }
#endif
    return PR_TRUE;
}

@@ -1019,8 +1010,8 @@ nsLocalFile::GetLastModifiedTimeOfLink(PRInt64 *aLastModTimeOfLink)
    CHECK_mPath();
    NS_ENSURE_ARG(aLastModTimeOfLink);

    struct stat sbuf;
    if (lstat(mPath.get(), &sbuf) == -1)
    struct STAT sbuf;
    if (LSTAT(mPath.get(), &sbuf) == -1)
        return NSRESULT_FOR_ERRNO();
    LL_I2L(*aLastModTimeOfLink, (PRInt32)sbuf.st_mtime);

@@ -1063,8 +1054,8 @@ nsLocalFile::GetPermissionsOfLink(PRUint32 *aPermissionsOfLink)
    CHECK_mPath();
    NS_ENSURE_ARG(aPermissionsOfLink);

    struct stat sbuf;
    if (lstat(mPath.get(), &sbuf) == -1)
    struct STAT sbuf;
    if (LSTAT(mPath.get(), &sbuf) == -1)
        return NSRESULT_FOR_ERRNO();
    *aPermissionsOfLink = NORMALIZE_PERMS(sbuf.st_mode);
    return NS_OK;
@@ -1108,11 +1099,7 @@ nsLocalFile::GetFileSize(PRInt64 *aFileSize)
#endif

    if (!S_ISDIR(mCachedStat.st_mode)) {
#ifdef HAVE_STAT64
        *aFileSize = mCachedStat.st_size;
#else
        LL_UI2L(*aFileSize, (PRUint32)mCachedStat.st_size);
#endif
        *aFileSize = (PRInt64)mCachedStat.st_size;
    }
    return NS_OK;
}
@@ -1122,11 +1109,14 @@ nsLocalFile::SetFileSize(PRInt64 aFileSize)
{
    CHECK_mPath();

    PRInt32 size;
    LL_L2I(size, aFileSize);
    /* XXX truncate64? */
    if (truncate(mPath.get(), (off_t)size) == -1)
#ifdef HAVE_TRUNCATE64
    if (truncate64(mPath.get(), (off64_t)aFileSize) == -1)
        return NSRESULT_FOR_ERRNO();
#else
    off_t size = (off_t)aFileSize;
    if (truncate(mPath.get(), size) == -1)
        return NSRESULT_FOR_ERRNO();
#endif
    return NS_OK;
}

@@ -1136,17 +1126,11 @@ nsLocalFile::GetFileSizeOfLink(PRInt64 *aFileSize)
    CHECK_mPath();
    NS_ENSURE_ARG(aFileSize);

#ifdef HAVE_LSTAT64
    struct stat64 sbuf;
    if (lstat64(mPath.get(), &sbuf) == -1)
    struct STAT sbuf;
    if (LSTAT(mPath.get(), &sbuf) == -1)
        return NSRESULT_FOR_ERRNO();
    *aFileSize = sbuf.st_size;
#else
    struct stat sbuf;
    if (lstat(mPath.get(), &sbuf) == -1)
        return NSRESULT_FOR_ERRNO();
    LL_UI2L(*aFileSize, (PRUint32)sbuf.st_size);
#endif

    *aFileSize = (PRInt64)sbuf.st_size;
    return NS_OK;
}

@@ -1157,7 +1141,7 @@ nsLocalFile::GetDiskSpaceAvailable(PRInt64 *aDiskSpaceAvailable)

    // These systems have the operations necessary to check disk space.

#if defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_STATVFS_H)
#ifdef STATFS

    // check to make sure that mPath is properly initialized
    CHECK_mPath();
@@ -1188,11 +1172,8 @@ nsLocalFile::GetDiskSpaceAvailable(PRInt64 *aDiskSpaceAvailable)
     * a non-superuser, minus one as a fudge factor, multiplied by the size
     * of the aforementioned blocks.
     */
    PRInt64 bsize, bavail;
    *aDiskSpaceAvailable = (PRInt64)fs_buf.f_bsize * (fs_buf.f_bavail - 1);

    LL_I2L(bsize, fs_buf.f_bsize);
    LL_I2L(bavail, fs_buf.f_bavail - 1);
    LL_MUL(*aDiskSpaceAvailable, bsize, bavail);
    return NS_OK;

#else
@@ -1209,7 +1190,7 @@ nsLocalFile::GetDiskSpaceAvailable(PRInt64 *aDiskSpaceAvailable)
#endif
    return NS_ERROR_NOT_IMPLEMENTED;

#endif /* HAVE_SYS_STATFS_H or HAVE_SYS_STATVFS_H */
#endif /* STATFS */

}

@@ -1269,9 +1250,9 @@ nsLocalFile::Exists(PRBool *_retval)
{
    CHECK_mPath();
    NS_ENSURE_ARG_POINTER(_retval);
    struct stat buf;
    struct STAT buf;

    *_retval = (stat(mPath.get(), &buf) == 0);
    *_retval = (STAT(mPath.get(), &buf) == 0);
    return NS_OK;
}

@@ -1280,9 +1261,9 @@ nsLocalFile::IsWritable(PRBool *_retval)
{
    CHECK_mPath();
    NS_ENSURE_ARG_POINTER(_retval);
    struct stat buf;
    struct STAT buf;

    *_retval = (stat(mPath.get(), &buf) == 0);
    *_retval = (STAT(mPath.get(), &buf) == 0);
    if (*_retval || errno == EACCES) {
        *_retval = *_retval && (buf.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH ));
        return NS_OK;
@@ -1295,9 +1276,9 @@ nsLocalFile::IsReadable(PRBool *_retval)
{
    CHECK_mPath();
    NS_ENSURE_ARG_POINTER(_retval);
    struct stat buf;
    struct STAT buf;

    *_retval = (stat(mPath.get(), &buf) == 0);
    *_retval = (STAT(mPath.get(), &buf) == 0);
    if (*_retval || errno == EACCES) {
        *_retval = *_retval && (buf.st_mode & (S_IRUSR | S_IRGRP | S_IROTH ));
        return NS_OK;
@@ -1310,9 +1291,9 @@ nsLocalFile::IsExecutable(PRBool *_retval)
{
    CHECK_mPath();
    NS_ENSURE_ARG_POINTER(_retval);
    struct stat buf;
    struct STAT buf;

    *_retval = (stat(mPath.get(), &buf) == 0);
    *_retval = (STAT(mPath.get(), &buf) == 0);
    if (*_retval || errno == EACCES) {
        *_retval = *_retval && (buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH ));
        return NS_OK;
@@ -1404,8 +1385,8 @@ nsLocalFile::IsSymlink(PRBool *_retval)
    NS_ENSURE_ARG_POINTER(_retval);
    CHECK_mPath();

    struct stat symStat;
    if (lstat(mPath.get(), &symStat) == -1)
    struct STAT symStat;
    if (LSTAT(mPath.get(), &symStat) == -1)
        return NSRESULT_FOR_ERRNO();
    *_retval=S_ISLNK(symStat.st_mode);
    return NS_OK;
@@ -1475,8 +1456,8 @@ nsLocalFile::GetNativeTarget(nsACString &_retval)
    CHECK_mPath();
    _retval.Truncate();

    struct stat symStat;
    if (lstat(mPath.get(), &symStat) == -1)
    struct STAT symStat;
    if (LSTAT(mPath.get(), &symStat) == -1)
        return NSRESULT_FOR_ERRNO();

    if (!S_ISLNK(symStat.st_mode))
@@ -1522,7 +1503,7 @@ nsLocalFile::GetNativeTarget(nsACString &_retval)

        // Any failure in testing the current target we'll just interpret
        // as having reached our destiny.
        if (lstat(flatRetval.get(), &symStat) == -1)
        if (LSTAT(flatRetval.get(), &symStat) == -1)
            break;

        // And of course we're done if it isn't a symlink.
+18 −8
Original line number Diff line number Diff line
@@ -68,11 +68,15 @@
    #include <sys/statfs.h>
#endif

#ifdef HAVE_STATVFS64
    #define STATFS statvfs64
#else
    #ifdef HAVE_STATVFS
        #define STATFS statvfs
    #else
        #define STATFS statfs
    #endif
#endif

// so we can statfs on freebsd
#if defined(__FreeBSD__)
@@ -82,6 +86,16 @@
    #include <sys/mount.h>
#endif

#if defined(HAVE_STAT64) && defined(HAVE_LSTAT64)
    #define STAT stat64
    #define LSTAT lstat64
    #define HAVE_STATS64 1
#else
    #define STAT stat
    #define LSTAT lstat
#endif


class NS_COM nsLocalFile : public nsILocalFile,
                           public nsIHashable
{
@@ -115,11 +129,7 @@ private:
protected:
// This stat cache holds the *last stat* - it does not invalidate.
// Call "FillStatCache" whenever you want to stat our file.
#ifdef HAVE_STAT64
    struct stat64 mCachedStat;
#else
    struct stat  mCachedStat;
#endif
    struct STAT  mCachedStat;
    nsCString    mPath;

    void LocateNativeLeafName(nsACString::const_iterator &,