From 34ed5e5ed99d5c4eae773806d775e25d6a7791f1 Mon Sep 17 00:00:00 2001 From: Gerd von Egidy Date: Wed, 16 Dec 2015 14:37:17 +0100 Subject: [PATCH] add get_free_diskspace() --- src/filefunc.cpp | 33 +++++++++++++++++++++++++++++++++ src/filefunc.hxx | 2 ++ test/test_filefunc.cpp | 20 ++++++++++++++++++++ 3 files changed, 55 insertions(+), 0 deletions(-) diff --git a/src/filefunc.cpp b/src/filefunc.cpp index 4316048..5359f46 100644 --- a/src/filefunc.cpp +++ b/src/filefunc.cpp @@ -33,6 +33,7 @@ on this file might be covered by the GNU General Public License. #include #include +#include #include #include #include @@ -951,5 +952,37 @@ bool remove_unlisted_files(const std::string &directory, return all_fine; } +/** + * @brief Get free size in bytes on a given path or filename + * + * @param path Directory or filename to look in + * + * @return Number of bytes available to a regular user, -1 in case of an error + **/ +long long get_free_diskspace(const std::string& path) +{ + struct statvfs sf; + + int ret; + while ( ((ret=statvfs(path.c_str(),&sf)) == -1) && (errno==EINTR) ); + + if (ret==-1) + { + // a real error occured + return -1; + } + + long long free_bytes=0; + + // load block size + free_bytes=sf.f_bsize; + + // multiply by number of free blocks accessible by normal users + // make sure we really multiply long long by long long and don't overflow at 2 GB + free_bytes*=(long long)sf.f_bavail; + + return free_bytes; +} + } // eo namespace I2n diff --git a/src/filefunc.hxx b/src/filefunc.hxx index a2f4bc0..7e71311 100644 --- a/src/filefunc.hxx +++ b/src/filefunc.hxx @@ -190,6 +190,8 @@ bool chdir(const std::string &path, std::string *error=NULL); mode_t umask(mode_t mask); +long long get_free_diskspace(const std::string& path); + /* ** more specialized tool function(s) diff --git a/test/test_filefunc.cpp b/test/test_filefunc.cpp index 88515d1..fd1efb0 100644 --- a/test/test_filefunc.cpp +++ b/test/test_filefunc.cpp @@ -41,6 +41,8 @@ on this file might be covered by the GNU General Public License. #include #include +#include +#include #ifdef NOISEDEBUG #define DOUT(msg) std::cout << msg << std::endl @@ -512,4 +514,22 @@ BOOST_AUTO_TEST_CASE(FileContentDiffersEqualSize) BOOST_CHECK_EQUAL( true, res ); } +BOOST_AUTO_TEST_CASE(FreeDiskSpace1) +{ + inpipestream cmd_df("df -B 1 --output=avail /tmp | tail -n 1"); + string dfstr; + if (cmd_df) + getline(cmd_df, dfstr); + + long long dfout=-1; + string_to(dfstr,dfout); + + BOOST_CHECK_EQUAL( dfout, get_free_diskspace("/tmp") ); +} + +BOOST_AUTO_TEST_CASE(FreeDiskSpace2) +{ + BOOST_CHECK_EQUAL( -1, get_free_diskspace("/this/path/is/really/bogus") ); +} + BOOST_AUTO_TEST_SUITE_END() -- 1.7.1