#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/statvfs.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
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
mode_t umask(mode_t mask);
+long long get_free_diskspace(const std::string& path);
+
/*
** more specialized tool function(s)
#include <filefunc.hxx>
#include <daemonfunc.hpp>
+#include <pipestream.hxx>
+#include <stringfunc.hxx>
#ifdef NOISEDEBUG
#define DOUT(msg) std::cout << msg << std::endl
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<long long>(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()