From: Gerd von Egidy Date: Wed, 16 Dec 2015 13:37:17 +0000 (+0100) Subject: add get_free_diskspace() X-Git-Tag: v2.8~16 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=34ed5e5ed99d5c4eae773806d775e25d6a7791f1;p=libi2ncommon add get_free_diskspace() --- 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()