Add a simple /bin/df which gathers its info from /proc/df.

This commit is contained in:
Andreas Kling 2019-02-21 14:48:00 +01:00
parent 7d288aafb2
commit 43075e5878
Notes: sideshowbarker 2024-07-19 15:39:11 +09:00
8 changed files with 119 additions and 0 deletions

View file

@ -1359,3 +1359,27 @@ bool Ext2FSInode::chmod(mode_t mode, int& error)
set_metadata_dirty(true);
return true;
}
unsigned Ext2FS::total_block_count() const
{
LOCKER(m_lock);
return super_block().s_blocks_count;
}
unsigned Ext2FS::free_block_count() const
{
LOCKER(m_lock);
return super_block().s_free_blocks_count;
}
unsigned Ext2FS::total_inode_count() const
{
LOCKER(m_lock);
return super_block().s_inodes_count;
}
unsigned Ext2FS::free_inode_count() const
{
LOCKER(m_lock);
return super_block().s_free_inodes_count;
}

View file

@ -62,6 +62,11 @@ public:
virtual ~Ext2FS() override;
virtual bool initialize() override;
virtual unsigned total_block_count() const override;
virtual unsigned free_block_count() const override;
virtual unsigned total_inode_count() const override;
virtual unsigned free_inode_count() const override;
private:
typedef unsigned BlockIndex;
typedef unsigned GroupIndex;

View file

@ -37,6 +37,11 @@ public:
bool is_readonly() const { return m_readonly; }
virtual unsigned total_block_count() const { return 0; }
virtual unsigned free_block_count() const { return 0; }
virtual unsigned total_inode_count() const { return 0; }
virtual unsigned free_inode_count() const { return 0; }
struct DirectoryEntry {
DirectoryEntry(const char* name, InodeIdentifier, byte file_type);
DirectoryEntry(const char* name, size_t name_length, InodeIdentifier, byte file_type);

View file

@ -28,6 +28,7 @@ enum ProcFileType {
__FI_Root_Start,
FI_Root_mm,
FI_Root_mounts,
FI_Root_df,
FI_Root_kmalloc,
FI_Root_all,
FI_Root_summary,
@ -399,6 +400,27 @@ ByteBuffer procfs$mounts(InodeIdentifier)
return builder.to_byte_buffer();
}
ByteBuffer procfs$df(InodeIdentifier)
{
// FIXME: This is obviously racy against the VFS mounts changing.
StringBuilder builder;
VFS::the().for_each_mount([&builder] (auto& mount) {
auto& fs = mount.guest_fs();
builder.appendf("%s,", fs.class_name());
builder.appendf("%u,", fs.total_block_count());
builder.appendf("%u,", fs.free_block_count());
builder.appendf("%u,", fs.total_inode_count());
builder.appendf("%u,", fs.free_inode_count());
if (!mount.host().is_valid())
builder.append("/");
else {
builder.append(VFS::the().absolute_path(mount.host()));
}
builder.append('\n');
});
return builder.to_byte_buffer();
}
ByteBuffer procfs$cpuinfo(InodeIdentifier)
{
StringBuilder builder;
@ -1076,6 +1098,7 @@ ProcFS::ProcFS()
m_entries.resize(FI_MaxStaticFileIndex);
m_entries[FI_Root_mm] = { "mm", FI_Root_mm, procfs$mm };
m_entries[FI_Root_mounts] = { "mounts", FI_Root_mounts, procfs$mounts };
m_entries[FI_Root_df] = { "df", FI_Root_df, procfs$df };
m_entries[FI_Root_kmalloc] = { "kmalloc", FI_Root_kmalloc, procfs$kmalloc };
m_entries[FI_Root_all] = { "all", FI_Root_all, procfs$all };
m_entries[FI_Root_summary] = { "summary", FI_Root_summary, procfs$summary };

View file

@ -64,6 +64,7 @@ cp -v ../Userland/dmesg mnt/bin/dmesg
cp -v ../Userland/chmod mnt/bin/chmod
cp -v ../Userland/top mnt/bin/top
cp -v ../Userland/ln mnt/bin/ln
cp -v ../Userland/df mnt/bin/df
cp -v ../Applications/Terminal/Terminal mnt/bin/Terminal
cp -v ../Applications/FontEditor/FontEditor mnt/bin/FontEditor
cp -v ../Applications/Launcher/Launcher mnt/bin/Launcher

1
Userland/.gitignore vendored
View file

@ -32,3 +32,4 @@ top
chmod
pape
ln
df

View file

@ -27,6 +27,7 @@ OBJS = \
dmesg.o \
chmod.o \
top.o \
df.o \
ln.o \
rm.o
@ -61,6 +62,7 @@ APPS = \
chmod \
top \
ln \
df \
rm
ARCH_FLAGS =
@ -174,6 +176,9 @@ top: top.o
ln: ln.o
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
df: df.o
$(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a
.cpp.o:
@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<

55
Userland/df.cpp Normal file
View file

@ -0,0 +1,55 @@
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <AK/AKString.h>
#include <AK/Vector.h>
struct FileSystem {
String fs;
size_t total_block_count { 0 };
size_t free_block_count { 0 };
size_t total_inode_count { 0 };
size_t free_inode_count { 0 };
String mount_point;
};
int main(int, char**)
{
FILE* fp = fopen("/proc/df", "r");
if (!fp) {
perror("failed to open /proc/df");
return 1;
}
printf("Filesystem Blocks Used Available Mount point\n");
for (;;) {
char buf[4096];
char* ptr = fgets(buf, sizeof(buf), fp);
if (!ptr)
break;
auto parts = String(buf, Chomp).split(',');
if (parts.size() < 6)
break;
bool ok;
String fs = parts[0];
unsigned total_block_count = parts[1].to_uint(ok);
ASSERT(ok);
unsigned free_block_count = parts[2].to_uint(ok);
ASSERT(ok);
unsigned total_inode_count = parts[3].to_uint(ok);
ASSERT(ok);
unsigned free_inode_count = parts[4].to_uint(ok);
ASSERT(ok);
String mount_point = parts[5];
printf("% 10s", fs.characters());
printf("%10u ", total_block_count);
printf("%10u ", total_block_count - free_block_count);
printf("%10u ", free_block_count);
printf("%s", mount_point.characters());
printf("\n");
}
int rc = fclose(fp);
ASSERT(rc == 0);
return 0;
}